I've been working on an API in Node.js for the first time, and of course I needed a test page so I decided to whip one up in Node as well for the hell of it.
After wracking my mind to come up with a good way to load the header, body and footer files (Jade syntax files) and have them be friends and render together, I came up with a recursive solution.
function assemblePage(name,markup)
{
markup = markup || '';
if (markup=='')
fs.readFile('header.jade', function(err,data){assemblePage(name,markup+data)});
else if (name != 'footer')
fs.readFile(name+'.jade', function(err,data){assemblePage('footer',markup+data)});
else
fs.readFile('footer.jade', function(err,data){console.log(markup+data);__res.send(jade.render(markup+data))});
}
So all I have to call is:
assemblePage('home');
Is this the best way to go about things?
I think you should be using expressjs(High performance, high class web development for Node.js) to render your templates.
It has a very sophisticated View Rendering. I think what you need is called view partials. In the screencasts section you can watch a screencast about view partials
Related
I'm looking to use Express to render raw strings as HTML, with the ability to reference static files in a specified directory (CSS, images, and other resources).
I've done a lot of research, but I haven't seen anything that approaches what I'm trying to do. For example, I thought perhaps writing a custom templating engine that only pretended to load a file would cut it, but that doesn't seem to do the trick.
What's the best way to approach this?
There are many ways to do it.
It can done in any other templating engine as well but here i am guiding you to implement same using EJS(Embedded Javascript).
Use Express Generator to create an ExpressJS app with EJS templating Engine.
command :
express --ejs AppName
For more information about express Generator refer to doc here
Now EJS has tags such as :
1. <% code %> - Code that is evaulated without "echo" it is not printed out.
2. <%= code %> - Code that is evaluated and printed out and escaped!
3. <%- Code %> - Code that is evaluated printed out and not escaped!
So in your case you can use 3rd the third tag that i have mentioned above.
Render EJS views in the usual way from your route config:
res.render('index.ejs', {
// data you want to pass ..
});
Code sample
Some time ago i was playing around with EJS, i developed a very small blogApp for practice.
You can look into this view, line number 33, for more practical way of implementing same.
Looking for a solution for a few days. Need help.
Source:
node.js + express.js + jade template engine
Problem:
Can't understand how I can render 1+ dynamic blocks on one page.
For example:
We have a page: News main page
Blocks on page: Latest news (list 20 itens), hot news (list 4 items), most viewed news (4 items), block with news categories (it can display current category on the page with page with card of one selected novelty, so it is dynamic block too), and block with some user auth data.
"block" i mean a widget as we can see on site, not a block of code.
What can I do in express? I can route special url to special function in routes.
So as I see, if a want to render all this blocks on the one page I have to call all functions rendering each block in only one function of route.
I mean it seems that I have to do something like this (sure in libs but doesn't matter here)
app.get('/news', function(req, res){
call_last_news(funcion(){
call_hot_news(function(){
call_get_user_info(function(){
...
...
...
template.render.here();
final_here();
});
});
});
});
This looks real but so unuseful and unsupportable code that .. That's bad.
I can see solution in calls from template engine to render some blocks on the page. But not just include because all blocks can use db or cookies, session data etc. all blocks are dynamic. But I have no idea how to create such engine using express.js + jade
Well I'm not certain I understood all of the problem but based on the pseudo code, it looks like the main concern here is that you have a deeply nested set of potentially independent and reusable functions. There are two approaches to this problem that come to mind:
Use a control flow library
Use something like async series, parallel, etc. (which function depends on the nature of your code – are all of the call_ functions independent?) That will clean up your code and make it more maintainable.
Use ajax
Another approach you can take is to quickly render the page without all of the call_ functions and just make several ajax calls from the client to fill in the data. You could have routes which look like '/news/last', and '/news/hot', etc. This is nice because you can separate out all of the logic for each of these units into reusable URLs so you can mix and match them on any page.
I'm using Ember.js and Handlebars.js for a project I'm working on at the moment. Server-side is Node.js + express and I make use of the Jade templating engine.
Now, whenever I want to tie actions to DOM elements, I use the {{action}} attribute of Ember.js. Currently, this is how my code looks in Jade:
script(type='text/x-handlebars', data-template-name='frontpage')
div.logo(''='{{action goToFrontpage}}')
The above does work, however, the ''='{{action goToFrontpage}}' part seems somewhat hackish.
Is there any other way of doing this? Perhaps a best-practice when combining Ember.js, Handlebars.js, and Jade?
Sometimes it's better to just use html in Jade.
<div {{action GoToFrontpage}} class="logo"></div>
An other example I see a lot is the strong tag.
.stuff
| This is an
strong important
| message.
You can write this
.stuff This is an <strong>important</strong> message.
I find the second a lot more readable and concise.
After doing some research, everyone seems to advise learning and using some form of a templating language with node.js. Why? Couldn't you just use HTML, and if so, how? I'm new to Node, so I downloaded Express and immediately I asked myself, "What is .jade?"
There is no requirement, but it can be much nicer. You can just as easily manually output HTML, but then you are forced to keep all of your HTML inside of JS strings at all times, or keep it in a file.
You'd do something like this:
res.send("<html><body>" + content + "</body></html>");
As soon as you want to have dynamic HTML, you either need to include it directly in your code, or you need to have it in a template. The difficulty is that you can't just throw standard HTML in a file, because that essentially makes it impossible to dynamically alter the page. To solve this problem, usually you'd dynamically generate HTML using some kind of templating language like jade.
For a tiny one-off app, it may not be a big deal, but separating your presentation HTML from your code becomes very important as the size of the app you are developing grows.
If your're using express use the code below
var express = require('express');
var app = express.createServer(
express.static(__dirname + '/public')
);
app.listen(3000);
Then put all your html files in the /public folder. That's it.
I want to be able to dynamically reference JavaScript and Stylesheets depending on which page a user is on in Express. I thinking the best way to do so (though I'm open to suggestions) is to pass the current view to the layout page.
For example;
Given the url http://example.com/trees
I would want to have some logic in layout.jade that said something to the effect of:
script(src="/javascripts/{view}.js")
Which would get rendered as:
<script src="/javascripts/trees.js"></script>
Any suggestions or best practices for doing this?
req.route is the matched route, so things like req.route.path etc are available, or of course req.url which may be parsed. With express 2x you can expose these values to views automatically using "dynamic helpers" or res.local()
There are no best practices for doing this, since Express doesn't provide Rails like url helpers, so I think you're approach is fine.
The easy answer is to just put ALL your javascript into a single file and be done with it. Ditto for CSS. See the Ruby on Rails asset pipeline for details. You are probably making your life more complicated than necessary and also less efficient by having different javascripts on different pages.
However, since you asked, the answer for javascripts is easy. Just put the extra <script> tags in the view, not the layout. Problem solved. CSS doesn't work as cleanly because the <link> tags need to be inside the <head>. In this case, I define the styles I need as an array of strings and loop over that in my layout template. So in my route I set up a local variable such as
locals.css = ['/css/one.css', '/css/two.css']
Then just loop over that in your template and generate one <link> tag for each.