sails can't find layout.jade - node.js

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

Related

Placing a Pug extends anywhere in a file?

I'm currently following this Jade tutorial https://www.youtube.com/watch?v=l5AXcXAP4r8 (I know Jade is Pug now but I'm watching jade tutorials to get familiar with it since many don't exist for pug) and at 24:25 the instructor places an 'extends filename' in the middle of his index.jade file. This works fine for him but this does not work for me when executing with pug. I get an error in my terminal saying "Declaration of template inheritance ("extends") should be the first thing in the file." Is it not possible in pug to put an extends in the middle of a file and it used to be possible with jade? Is there any way to make it possible? Thank you in advance for your help!
This is not possible with pug. The error message is fairly clear, extendsmust be the first thing in the file, it cannot be placed in the middle. Without any code (or idea of what you're trying to achieve), it is difficult to tell if you could find a workaround for this (using mixins perhaps?).

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.

"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.

grunt to build dynamic jade pages

I want to use grunt to build my node.js project (based on Kraken.js, but I've replaced dust with jade). I've installed grunt-contrib-jade. For jade files that contain no server side state this all works nicely and I get the HTML files output. However, where I have .jade files that contain logic and render server-side state it all goes wrong. For example, if I have h1 #{x.y} in my file the grunt output is cannot read property y of undefined. This makes complete sense as x is only defined at runtime.
So I'm now wondering do I just ignore my jade files in the grunt build and let the server process them all at runtime, or is there some alternative that I'm missing to 'pre-process' my .jade files to speed up execution?
Quoting an answer of mine (Would it benefit to pre-compile jade templates):
When Jade compiles the template, the template is cached. In production environment if you warm up the cache, then there is no need to pre-compile template. Even if you don't, the template will be cached after its first compilation.
In short: Compiling Jade template is useless. You'd better remove grunt-contrib-jade.

Layout inheritance in jade

If you don't know what jade is.
I am having problem with the template inheritance system.My file structure is like so
/views/
|-- layout.jade
/products/
|-- index.jade
|-- product.jade
/static/
/stylesheets/
|-- style.css
The problems is that when loading the product page which receives an id as param (localhost:3000/product/:id if not for the /id it would load just fine), although the layout still extends correctly it does not load the stylesheet properly (the path is broken). I am doing half of it right though, in the index page of products the stylesheet loads just fine.
Layout.jade
head
link(rel='stylesheet', href='stylesheets/style.css')
It's probably the relative path in your href. Digging around the express documentation, I'm finding that the most popular approach is to reference the stylesheet from the base of the site like this (notice the / preceding stylesheets):
link(rel='stylesheet','/stylesheets/style.css')
This has the benefit of being easy, and working across routes of multiple depths (/about, /about/me, etc). However, it has the negative of not supporting app directory depth. For example, if you wanted to host your app at: http://yourserver/yourapps/yourapp this would be a problem. I don't know if you care about this or not, most of the examples for express certainly don't :-)
However, if you want to do this the right way, there is one example on the express github site: blog. https://github.com/visionmedia/express/tree/master/examples/blog
The approach here is to use a middleware component to grab the base url, and stuff it in the locals passed down to the layout view. Here's what your HTML would look like:
!!! 5
html
head
title Blog
link(rel='stylesheet', href=base + '/style.css')
body
#container!= body
The important parts to check out if you require this approach are middleware/locals.js, app.js where the middleware component is wired up, and layout.jade where the base href is used.
Happy Coding!

Resources