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

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.

Related

Express 4+pug disable layout

I want to ajax for blocks that without layout
Such as
extends layout
block content
p xxxx
I want to get the content in block
if !layout
include layout
The solution
If you don't want the standard pug layout then create a file that doesn't have extends layout in it:
doctype html
html(lang='en-us')
head
title Page Title
body
div Content goes here
You don't need to do anything in your app.js file to make this happen. You've probably figured out that none of the statements in your question work. This is all controlled in the pug template file.

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.

Jade: modify <head> from any place other than the main page

Update:
I also posted this question to the Jade GitHub repository. I'm dropping it here too, for future (circular) reference:
https://github.com/jadejs/jade/issues/1943
Original post:
In a default node + express + jade application, I'm trying to build some common reusable components (menu, footer...) that I can include in some pages. I got stuck while trying to add references to .css or .js files from a block or an included file.
I want to do this because I don't want to include all the styles and scripts if I don't need them.
The folder structure is something like this:
Root
public
javascripts
main.js
menu.js
stylesheets
main.css
menu.css
views
shared
layout.jade
menu.jade
footer.jade
index.jade
The layout.jade file:
doctype html
html
head
title= title
link(rel="stylesheet", href="stylesheets/main.css")
script(src="javascripts/main.js")
body
block content
The index.jade file:
extends shared/layout
block content
h1= title
p Welcome to #{title}
In menu.jade there is some code that needs the menu.css and menu.js files.
Now I need a way to add those files to the <head> of the page only when I use the menu.jade file.
I started using Jade a few hours ago so it's very possible that I missed something in the documentation.
Thank you!
You could do this with jQuery in your menu.js like so:
$("head link[rel='stylesheet']").last().after("<link rel='stylesheet' href='stylesheets/menu.css' type='text/css'>");
I would caution you about this practice however. One alternative would be to have a build step that concatenates all of your CSS files together and serves all of your style in a single css file. LESS and cssmin are good options here, and they have nice modules to automate this for you in grunt or gulp, whichever you're using.
You did mention that you didn't want to include all styles if you don't need them, but I would suggest that having a web browser download many small css files is going to be slower than having it download one big one, especially if you serve those files via a webserver like nginx that employs gzip, or if you serve your static files through a CDN like CloudFront.

sails can't find layout.jade

I am starting to learn Sails (0.9.7, node 0.10.16) and running through the sailscasts episodes. I am also trying to use jade as I do so. Where I am stuck now is that sails is not finding views/layout.jade. I backed out all the jade stuff and redid with ejs and sails is not finding views/layout.ejs.
As a last resort, I cloned activtyoverlord (the sailscasts app) and when I sails lift activityoverlord does not find its views/layout.ejs.
Any suggests as to what I might be doing wrong?
I'm not a jade user, however, I think you need to put extends ../layout at the top of your index.jade file to use layout.jade.
Also, I think both the layout.jade and index.jade have tabs and spaces (I don't think you can use both). I took out the tabs and added spaces in your layout.ejs file.
I created a project from scratch, changed engine to jade in config/views.js but left layout to the default value.
Also, I used these tags in layout.jade:
// SCRIPTS
// SCRIPTS END
and
// STYLES
// STYLE END
Grunt then puts the appropriate paths for javascript and styles in your layout file. I couldn't get index.jade into the layout.jade but I don't know enough about jade to determine what's wrong.
Here's a link to the repo I made: https://github.com/irlnathan/sails-answers-jade

Jade template inheritance

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.

Resources