I may be completely misunderstanding how to use connect-assetmanager for my node project. But I have set up which js files I want to package up into a 'group' - but how do I refer to this group in my ejs/jade template?
Surely I need to somehow 'render' this package in my template?
I found the solution:
In your server for example, you could set up a dynamic helper like so:
app.dynamicHelpers({
'assetsCacheHashes': function(req, res) {
return assetsManagerMiddleware.cacheHashes;
}
});
where assetsManagerMiddleware represents your assetManager.
Then in your ejs template, you can render the generated asset package like so:
<script src="/js/<%= assetsCacheHashes.js || 0 %>.js"></script>
In your view source - see which path it is choosing and adjust your path accordingly.
For Jade: script(type='text/javascript', src='/the/groups/route')
Your asset groups should have a route specified. That regex is used to determine if a request is asking for the that group. If it matches, it should serve the group.
Related
Framework: node.js / express.js / Jade
Question: in production env, when a jade file is rendered by express, jade cache's it so future renders are faster.
When I start node.js app, how can I pre-compile (or) pre-render (like warmup) all the jade files so its already in cache when requests start to come in...
I can use a folder recursion, I just need to know how to pre-compile (or) pre-render.
Is this possible?
Jade has template pre-compiling and caching built in.
http://jade-lang.com/api/
Simply specify cache: true option to jade.compileFile, and iterate through all of your template files.
var options = {cache: true};
// iterate/recurse over your jade template files and compile them
jade.compileFile('./templates/foo.jade', options);
// Jade will load the compiled templates from cache (the file path is the key)
jade.renderFile('./templates/foo.jade');
If you're not using any parameters, you can compile jade templates directly to HTML with grunt or gulp and make it watch for file modifications
Try it from the command-line:
jade view/map-beacons.jade -D
If you do need to use parameters I would use something like in Andrew Lavers answer.
compileFile returns a function which you can use to pass in parameters i.e. fn({ myJsVar: 'someValue' })
There is also a client option in the command-line but I didn't find any use for it :
jade view/map-beacons.jade -cD
i do this solution, this code outside http.createServer function
let cache_index=jade.renderFile('index.jade');
and when return view
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.end(cache_index);
when use this solution server return index to 1ms
but without solution server return index between 150ms to 400ms
result:
Picture 1 with cache
Picture 2 without cache
I'm using sailsjs to build my website but decided not to use its default EJS for templating.
In ./config/views.js, I have set the the following(after npm install dustjs-linkedin & dustjs-helpers):
engine: 'dust',
In my HomeController ./api/controllers/HomeController.js, I need to do the following to get the language text from ./config/locales/en.json:
title: res.i18n('title'),
//or
siteName: res.__('siteName')
In my home template ./views/home/index.dust, I can access those string with:
<h1>{title}</h1>
<p>{siteName}</p>
However, as the number of strings grow, it will be redundant as I have to set each of the variables in controller before I can use it in my template.
So my questions are:
is there a better or correct way to use the text variables in my template from ./config/locales/en.json without having to define each of them in my controller file?
how to access & use the dustjs module in my controller so that..
I can create custom dustjs helpers? (how to create dustjs helpers?)
also, it seems I cannot configure the settings for i18n in ./config/i18n.js (objectNotation: true not working) Is this the correct place to configure i18n?
Its a long ques. I'll answer the part: I can create custom dustjs helpers? (how to create dustjs helpers?)
Ans. Yes you can. Here's how (in sailsjs):
We can create a globally accessible service in api/services/MultiplyBy2.js
MultiplyBy2.js
module.exports = {
myFunc: function (chunk, context, bodies, params) {
var number = params.num;
number = number*2;
return chunk.write(number);
}
};
And then you can use this in a dustjs template like so:
<p>10 * 2 = {#sails.services.multiplyby2.myFunc num=10/}</p>
Note: The file name (MultiplyBy2) will be lowercase. But the function name will be the same as defined (myFunc);
Hope this helps.
I also had this problem. I further dug into this and figured that it's too much hassle to resolve this issue, and that's when I switched to Handlebars on Sails.js.
Handlebars' i18n's syntax in Sails.js is {{__ 'Welcome' }} .
I'm designing an app with node.js and Express, and I was wondering if it was possible to move certain routing logic out of the app.js file. For exapmle, my app.js currently contains:
app.get('/groups',routes.groups);
app.get('/',routes.index);
Is there a way to move this logic out of the app.js file, and only have something like:
app.get('/:url',routes.get);
app.post('/:url",routes.post);
such that all GET requests would be processed by routes.get and all POST requests processed with routes.post?
You could pass a regular expression as the route definition:
app.get(/.+/, someFunction);
This would match anything. However, if you simply want to move your route definitions outside of your main app.js file, it is much clearer to do something like this:
app.js
var app = require('express').createServer();
...
require('routes').addRoutes(app);
routes.js
exports.addRoutes = function(app) {
app.get('/groups', function(req, res) {
...
});
};
This way, you're still using Express' built-in routing, rather than re-rolling your own (as you'd have to do in your example).
FULL DISCLOSURE: I am the developer of the node module mentioned below.
There is a node module that does kind of what you're asking for (and will, eventually, do more). It offers automatic routing based on convention over configuration for express. The module name is honey-express, but is currently in alpha development and not yet available on NPM (but you can get it from the source at https://github.com/jaylach/honey-express.
A short example of how it works: (Please note that this coffeescript)
# Inside your testController.coffee file. Should live inside /app/controllers
honey = require 'honey-express'
TestController = new honey.Controller
index: ->
# #view() is a helper method to automatically render the view for the action you're executing.
# As long as a view (with an extension that matches your setup view engine) lives at /app/views/controller/actionName (without method, so index and not getIndex), it will be rendered.
#view()
postTest: (data) ->
# Do something with data
Now, inside your app.js file you just have to setup some simple configuration:
# in your app.configure callback...
honey.config 'app root', __dirname + '/app'
app.use honey.router()
Now anytime a request comes in, honey will automatically look for a controller with the specified route, and then look for a matching action.. for example -
/test will automatically route to the index/getIndex() method of
testController
/ will automatically route to the index/getIndex() method of the homeController (the default controller is home), if it exists
/test/test will automatically route to the postTest() method of testController if the http method is POST.
As I mentioned, the module is currently in it's alpha state but the automatic routing works wonderfully and has been tested on two different projects now :) But since it's in alpha development, the documentation is missing. Should you decide to go this route, you can look at the sample I have up on the github, look through the code, or reach out to me and I'd be happy to help :)
EDIT: I should also note that honey-express does require the latest (BETA) version of express as it uses features that are not present in 2.x of express.
Is there a template engine for Express (node.js) which is based on Mustache or uses a similar syntax?
All I could find is haml, jade, ejs, jquery templates and one based on CoffeeScript (I write plain JS).
I want to write "normal" html, so only ejs and jqtpl would fit. I already use mustache with backbone so it would be best to also use it on the server side with Node.js
Just stumbled on this ancient thread but no one has mentioned consolidate.js, which seems to be the "right" way under Express 3 (refer to http://expressjs.com/faq.html). It also provides an easy way to switch/experiment with templating systems.
Here's a simple example - http://invitingthebell.com/2012/12/24/mustache-templates-in-express-3-0/.
Code, in case it disappears is:
var express = require('express')
, cons = require('consolidate')
, app = express();
// assign the mustache engine to .html files
app.engine('html', cons.mustache);
// set .html as the default extension
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
// test mustache
app.get('/', function(req, res){
var viewdata = { 'test' : 'Hey now.'};
res.render('index', viewdata);
});
app.listen(3000);
The index.html file in the views directory:
<html>
<head><title>Some CMS</title></head>
<body>
<h1>Mustache</h1>
<p>What do you say?</p>
<p>{{test}}</p>
</body>
</html>
You could probably add Mustache as a rendering engine by following the Express manual:
View filenames take the form “.”, where is the name of the module >that will be required. For example the view layout.ejs will tell the view system to >require(‘ejs’), the module being loaded must export the method exports.compile(str, >options), and return a Function to comply with Express.
Edit:
From the Mustache manual under Usage:
Below is quick example how to use mustache.js:
var view = {
title: "Joe",
calc: function () {
return 2 + 4;
}
};
var output = Mustache.render("{{title}} spends {{calc}}", view);
In this example, the Mustache.render function takes two parameters: 1) the mustache >template and 2) a view object that contains the data and code needed to render the >template.
From the above I suspect you could just export Mustache.render, but I haven't tested it. The object literals used as data look the same, but if they do happen to be different, you could probably just wrap Mustache.render in a function that formats it correctly.
Edit: Xomby's wrapper link contains an example of how to wrap handlebars for express, Mustache should be similar.
Try Hogan.js http://twitter.github.com/hogan.js/
I think it's what Twitter and LinkedIn uses in production.
Here's a working example/tutorial on using NodeJS, ExpressJS and MustacheJS Template Engine:
http://devcrapshoot.com/javascript/nodejs-expressjs-and-mustachejs-template-engine
You can build out a complete web page like you normally would, placing the mustacheJS fields where you like. Use express to route to the page, use node fs.readFileSync(); to get the html file, use mustache to update the data on the page then spit it out to the client.
It's kinda neat. I hope it helps!
-A-
Have you already tried stache ? It is no longer maintained but you can follow some links and get more recent stuff ..
I found Handlebars.js which is an extension of the Mustache template system/language.
And there is a really simple wrapper to use it with Express.
Sure, the best way to do this is the post here:
http://iamtherockstar.com/blog/2011/11/21/using-mustache-templates-express-apps/
So far, this has worked great for me. The only problem I have found is not using partials at the root path for views. For example partials in view/partials - the engine by default only finds partials as view. Let me know if you figure that out!
Check out Handlerbars. " Handlebars provides the power necessary to let you build semantic templates effectively with no frustration.
Handlebars is largely compatible with Mustache templates. In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates. Complete details can be found here " - Handlebars
I'm playing around with my first Node.js Express application, and as every programmer knows, the first thing you should build when testing out a new framework is a blog! Anyway, I'd like to write the articles in Markdown and then render it in the view. I saw that Jade allows for this to be done inside the view itself, using filters, but I can't get that working.
To simplify the situation, here's an example of what I'm talking about.
//app.js
res.render("article", {
md : "Hello World!\n\n*Woo*"
});
//article.jade
section
:markdown
#{md}
But, that outputs this: <section><h1>{md}</h1></section>... it isn't substituting in the variables I've passed to it.
Then I tried this:
//article.jade
section
:markdown
!{md}
And the output is this:
<section><p>Hello World!
*Woo*</p></section>
So, now it's not parsing the markdown!
I have been able to get this to work by parsing the markdown in the app.js file and then passing the HTML to the view to display, but I don't know, that seems a bit messier.
Is there a way to pass variables into Jade filters?
You can do this with a function passed in to jade from node:
var md = require("node-markdown").Markdown;
Then pass it into the view as a local:
res.render('view', { md:md, markdownContent:data });
Then render it in the jade view by calling the function:
!= md(markdownContent)
The node module node-markdown is deprecated. The marked is advanced new version. You can try like this
var md = require('marked');
Inside your router
res.render('template', { md: md });
Inside your jade template
div!= md(note.string)
I don't think jade can do this out of the box. One way to accomplish it that might feel slightly cleaner than pre-rendering the markdown is to create a helper function called markdown that takes a markdown string and returns HTML. Then you could do something like
section
!= markdown(md)
The markdown function should be included in the locals data when you render the jade template and can directly use a markdown library to convert the markdown syntax to HTML.
If you are using Scalate's Jade support you can enter:
section
:&markdown
#{md}
You can also import external files with:
section
:&markdown
#{include("MyFile.md")}