Jade template inheritance - node.js

Jade template inheritance in Jade is driving me mad...
The problem is that I would like to exclude a large bit of code to external template and then include it. When I do so everything gets f** up :/
Sample code:
!!!5
html(lang="en")
head
title sample title
body
header
div#someDiv
div#someContent
section#main
Let's say I want to exclude everything from top to div#someContent. Then I would have
include inc/header
section#main
This way code indentation goes wrong and everything is messed up :/ Can you point me to the right direction in including templates?
Thanks in advance!

This is not template inheritance, but includes (template inheritance is with block and extends keywords). I did try your code, and what it does with the include is insert "section#main" into "div#someDiv" instead of "div#someContent". Not sure if this should be considered a bug or what (how can the parser know if the added content should be inside the last item in the include file, or at the same level?). It doesn't seem to care about the level of indentation under the "include" statement.
However, if you DO use template inheritance, you can put an empty block at the end of your include:
!!!5
html(lang="en")
head
title sample title
body
header
div#someDiv
div#someContent
block content
Then you can append the block in your actual content file:
include inc/header
block append content
section#main
And this renders OK in the DOM (section#main is inside div#someContent). Depending on the structure of your views, you may be better off with "extends" instead of "include + block append". You can check Jade's GitHub doc for the details.

Related

how to use pug-bootstrap module in nodejs?

I installed the pug-bootstrap module in a nodejs project. I am trying to create a menu from a navbar.
I have done those files:
layout.pug:
include /node_modules/pug-bootstrap/_bootstrap.pug
index.pug:
extends layout
block head
+navbar("menu")
+nav_item("#", undefined, true)
string test
block body
h1= title
p Welcome to #{title}
the _bootstrap.pug contains the bootstrap css file : https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css. But it is not loaded on the webpage.
Someone know why? And how to fix that?
Any help would be appreciate.
When you extend a part of a template with block, you're replacing any code that was already in that block, before. In this case, I assume that the head included a reference to that CSS file, which you're overwriting.
Generally speaking, use append instead of block for the head section (see this page from their docs). That way, previous content of parent templates is not overwritten.
In your usecase, I am doubtful whether you should be placing anything at all in that head block, since it is reserved for meta-tags, not for actual visible content. In other words: You'll need to move the code you have there to the body anyway, since visible document objects belong in the body, not in the head.

FreeMarker layouts to reduce template redundancy?

According to the FreeMarker include statement docs, you can make header- and footer- aware templates like so:
<#include "/header.ftl">
<!-- Content of my this page -->
<#include "/footer.ftl">
But if my web app has hundreds of pages/views, this is a lot of redundant copy pasta. It would be great if there was like a "layout" concept in FreeMarker, where I could say "Hey, here is a layout:"
<#include "/header.ftl">
<#import_FTL_Somehow>
<#include "/footer.ftl">
And then create separate templates for each view/page (index.ftl, contactUs.ftl, etc.) and then tell FreeMarkers which FTL files "use" the layout. That way I wouldn't have to keep specifying header/footer includes in each and every template file.
Does FreeMarker support this kind of concept?
It doesn't, though if you only need a footer or header it can be solved with some TemplateLoader hack (where the TemplateLoader inserts the header and footer snippets, as if was there in the template file). But the usual solution in FreeMarker is calling the layout code explicitly from each templates, but not with two #include-s directly, but like:
<#my.page>
<!-- Content of my this page -->
</#my.page>
where my is an auto-import (see Configuration.addAutoImport).
Update: Another approach is that you have a layout.ftl like:
Heading stuff here...
<#include bodyTemplate>
Footer stuff here...
And then from Java you always call layout.ftl, but also pass in the body template name using the bodyTemplate variable:
dataModel.put("bodyTemplate", "/foo.ftl");
cfg.getTemplate("layout.ftl").process(dataModel, out);

load external html files with handlebars

I would like to create external Handlebars files using the following -
1. header- Contains html codes
2. footer- Contains html codes
3. nav- Contains html codes
4. search - Contains html codes
etc.
Is there a way with handlebars to do this, so that I can include each template if and when needed in a specific page. Not sure how to go about it.
Thanks!
Absolutely! You can use Handlebar partials to do this. Simply register your header, nav, etc files as partials and then you can use this in your main template by doing something like this:
{{> header }}
{{> nav activePage=(activePage) }}
Have you considered using ASP.NET?
If you wanted to add content from other html files, I would highly recommend using
#RenderPage()If you use this, then you could set up a layout such as:
#RenderPage("header.html")
Some random description
#RenderPage("navigationbar.html")
#RenderPage("searchbar.html")
- Insert some content here -
#RenderPage("footer.html")
I'm certain that if you use this kind of layout, you'd get the appearance you would want. Obviously this is just an example, so you'd probably want to add some kind of CSS layout to suit your taste, but this is how I would go about it in ASP.NET.

"Unexpected identifier" when adding extends/block to wintersmith-jade content file

I am making a static website using Wintersmith alongside the wintersmith-stylus and wintersmith-jade plugins.
I want to add a specific CSS file in a help page. The help page is based off the "layout" template. When I try to use a block to insert the stylesheet into the html head, I receive the following error:
Line ##: Unexpected identifier
layout.jade
doctype html
html
head
block head
link(rel="stylesheet" href="/styles/layout.css")
body
...
help.jade
---
template: layout.jade
---
//- Error inducing code
extends ./layout.jade
block head
link(rel="stylesheet" type="text/css" href="../styles/help.css")
//- end of error inducing code
...
Even if I move the extends and block head lines on top of the metadata block containing template: layout.jade, I still receive the same error. Removing extends ./layout.jade results in the error lines position moving from 40 to 5 in my case.
My guess is the error is caused by the wintersmith-jade plugin, but even if that's the case I'm lost for how I would go about fixing it.
Since I wanted to use both Stylus and Jade (with Jade for both content and templates), I ended up moving over to Harp. Harp not only has Stylus and Jade "built-in", but it's also slightly simpler than Wintersmith.
It's quite a workaround, but I'd say it's actually an upgrade at the same time.
I'm not using wintersmith-jade, but it looks like that plugin shouldn't affect the regular templates in /templates (which is what I think you're referring to).
Looking at templates/article.jade, it looks like you should use just extends layout instead of extends ./layout.jade.
The default templates also do not have the metadata block, but maybe that's necessary for the plugin you're using.

How to divide web pages in blocks with sailsjs

I am starting developing with Sailsjs and I would like to know how to divide a webpage into differents blocks.
for example :
in layout.jade i have
doctype html
html(lang="fr")
head
body
div(class='container')
div(class='row')
div(class='col-md-12')
block header
h1 header
div(class='row')
div(class='col-md-8')
block content
div(class='col-md-4')
block right
block footer
then in my controller1/index.jade i have
extends layout
append content
p
some content
So when I type http://myserver.com/controller1/index in the browser, it works.
How to append some code in the block right form the result of another controller ? (I don't want to append some code to the block right directly in the controller1/index.jade file, to make the file as shorter as possible).
So I guess we can call another method of the controller inside the jade file ?
For example i would like to put a code like :
append right
=call('controller2/action1')
at the end of the controller1/index.jade file.
The purpose of my question is to figure out how divide the html parts of a webpage like we can do it with php using include method (for example).
Thank you
Benjamin

Resources