sunng87 / handlebars-iron

Handlebars middleware for Iron web framework
MIT License
119 stars 20 forks source link

Handlebars and Mount and StaticFile #43

Closed GildedHonour closed 8 years ago

GildedHonour commented 8 years ago

How to use it with Mount, does it support it?

  let mut hbse = HandlebarsEngine::new();
  hbse.add(Box::new(DirectorySource::new("./views/", ".hbs")));
  if let Err(r) = hbse.reload() {
    panic!("{}", r.description());
  }

  let mut router = Router::new();
  router.get("/", index);

  let mut mount = Mount::new();
  mount
    .mount("/", router)
    mount("/css/", Static::new(Path::new("static/css/")));

   println!("Server running at http://localhost:3000/");
   Iron::new(mount).http("localhost:3000").unwrap();

Here how can I add hbse to mount or how to get them work together?

sunng87 commented 8 years ago

There's no different to use it with mount. Handlebars-iron only renders html with a Template is found in Response extension.

You can add hbse as after middleware. Find the example in example directory. Let me know if you getting any issue with it.

GildedHonour commented 8 years ago

I'm aware of AfterMiddleware, but this doesn't compile:

let mut chain = Chain::new(router);
chain.link_after(hbse);

let mut mount = Mount::new();
mount
  .mount("/", router)
  .mount("/css/", Static::new(Path::new("static/css/")));

chain.link_after(mount); --- doesn't compile

println!("Server running at http://localhost:3000/");
Iron::new(chain).http("localhost:3000").unwrap();

And if I'm not using this approach at all and only using Template in the function-handler for the view "index"

//let mut hbse = HandlebarsEngine::new();
//hbse.add(Box::new(DirectorySource::new("./views/", ".hbs")));

then this won't render anything either:

fn index(_: &mut Request) -> IronResult<Response> {

   resp.set_mut(Template::new("views/index.hbs", "".to_string())).set_mut(status::Ok); //empty response
  -- resp.set_mut(Template::new("/views/index.hbs", "".to_string())).set_mut(status::Ok); //empty response
  -- resp.set_mut(Template::new("./views/index.hbs", "".to_string())).set_mut(status::Ok); //empty response
ghotiphud commented 8 years ago

The problem here seems to be the use of router and mount. It should be something like:

let mut mount = Mount::new();
mount
  .mount("/", router)
  .mount("/css/", Static::new(Path::new("static/css/")));

let mut chain = Chain::new(mount);
chain.link_after(hbse);

println!("Server running at http://localhost:3000/");
Iron::new(chain).http("localhost:3000").unwrap();

Notice that hbse is linked after everything else, and that router is used only once.

GildedHonour commented 8 years ago

@ghotiphud thanks, working.

How can I inherit a template from another one? That is, I want to create a base template for the skeletton layout with a header and footer and inherit some pages off it.

sunng87 commented 8 years ago

@GildedHonour you can find example in examples/partail.rs

GildedHonour commented 8 years ago

There's no such a file.

sunng87 commented 8 years ago

Sorry, my bad. It's in the handlebars-rust repo:

https://github.com/sunng87/handlebars-rust/blob/master/examples/partials.rs

ghotiphud commented 8 years ago

I had trouble with that at first. It's not so much inheriting as defining partials then rendering your base template. {{> _base }} renders your base template.

With that one thing in mind it makes a lot more sense of what's happening to me.

GildedHonour commented 8 years ago

In base.hds I have:

//base.hds
<!DOCTYPE html>
<html>
  <head>
 ........
<body>
  {{#block sub_page}}
  {{/block}}
    <script type="text/javacript" src="/static/js/script01.js" />
  {{#block page_scripts}}
  {{/block}}
  </body>
</html>

and in a child one something like:

//index.hds
{{#partial sub_page}}
  {{#each articles}}
    {{article.title}} 
    {{article.body}} 
  {{/each}}
{{/partial}}

And it's not working, it returns 200 and empty 1 B response when I request "index". Whereas without the parent-child templates, only with a single page it's working.

How should I properly combine handlebars-iron and handlebars-rust where a paren-child template is used?

GildedHonour commented 8 years ago

@ghotiphud

then rendering your base template. {{> _base }} renders your base template.

Can you show me an example? In the /examples/ there's no " {{> _base }} " which renders a base template.

sunng87 commented 8 years ago

You need to add {{> base}} at the bottom of index.hbs. Otherwise the engine has no way to find the parent template at all.

ghotiphud commented 8 years ago

{{#block foo}}{{/block}} declares a location for a partial to be inserted {{#partial foo}}{{/partial}} declares the partial that will be rendered there.

In index.hbs, you've only declared the partial, but partials do not render until you give them a place to render. So, in my poorly worded explanation earlier, I was trying to say that rendering the {{> _base}} is the line that kicks off the actual rendering.

TLDR: Add {{> base}} as the last line of index.hbs.

Also, "base" is nothing special, could have named your template "mary_poppins" and put {{> mary_poppins}}

GildedHonour commented 8 years ago

Thanks, that's working. However, this "{{articles.description}}" doesn't render anything in a loop. In the "examples" it's just "{{description}}", however, how does it know whether it referes to a loop variable with the fileld description or just a normal field description?

In other words, can't I use "{{articles.description}}" in a loop {{#each articles}} if I want to? Or how to refer to a loop variable?

UPDATE: it's "this".

ghotiphud commented 8 years ago

http://handlebarsjs.com/ has been very helpful in getting my templates to work... It's mostly consistent, and where it's not, I've just had to tweak a bit.