How to provide the current route or view to the layout in ExpressJS? - node.js

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.

Related

I have created a layout and partial folder in views. I didn't understand why this code is used in app.js

app.engine('hbs',hbs({extname:'hbs',defaultLayout:'layout',layoutsDir:__dirname+'/views/layout/',partialsDir:__dirname+'/views/partials/'}))
why is hbs,extname,defaultLayout used here
app.engine(ext,callback) will takes two arguments, one is the extension and the other is a callback function. Therefore, hbs is the extension you are using to create your views.
you can also take a look at handelbars's github repository when they mentioned extname from here.
https://github.com/ericf/express-handlebars#extnamehandlebars
This link also might be helpful for you, they mentioned the defaultLayout option and what it means.
This link might help you understand why to use defaultLayout.
A layout is simply a Handlebars template with a {{{body}}} placeholder.
Usually it will be an HTML page wrapper into which views will be
rendered.
https://github.com/ericf/express-handlebars#layouts

Inject meta tag dynamically to HTML with Express

Summary:
I'm currently migrating a website on Apache + PHP stack over to Node + Express, and would like to know what is the best way/best practice (if there is one) for dynamically injecting meta tags under the new stack.
Details:
Under the existing stack, meta tags are injected dynamically by adding PHP codes into the HTML file directly. As rendering is done on server side, the tags are properly interpreted by Facebook/Google+/whatever web crawlers.
Under the new stack, after doing some research, I've come across two options:
Use template engine like Pug (Jade) to render the HTML with locals. (It seems to be an overkill to rewrite the existing HTML with Pug's syntax though? Can Pug deal with HTML, or I've to consider other template engine like EJS? What template engine do you advise me to explore?)
Use DOM manipulation plugin like Cheerio to inject the meta tags first, before rendering begins.
Between these two options, which one will have a better performance or there is no material difference? Are there any other ways that you'd otherwise recommend? Thanks!
EJS would probably be the simplest one for that and very similar to PHP.
You can also take a look at Mustache and Handlebars for other options with minimal changes to your existing HTML.
with EJS: <html><head><%= yourMetaTags %> ...
with Mustache: <html><head>{{ yourMetaTags }} ...
with Handlebars: <html><head>{{ yourMetaTags }} ...
Also doT.js is very fast.
See:
http://www.embeddedjs.com/
https://mustache.github.io/
http://handlebarsjs.com/
http://olado.github.io/doT/
Parsing the HTML and manipulating it with a DOM API just to insert meta tags would be an overkill in my opinion.
On the other hand if all you need is to insert meta tags then you could make a simple regex substitution, using something like yourHTML.replace('<head>', '<head>'+yourMetaTags); but it could potentially get more complex over time when you need more functionality. After all, everyone has made a templating engine at some point in life.

Why does React.js' API warn against inserting raw HTML?

From the tutorial
But there's a problem! Our rendered comments look like this in the
browser: "<p>This is <em>another</em> comment</p>". We want those tags
to actually render as HTML.
That's React protecting you from an XSS attack. There's a way to get
around it but the framework warns you not to use it:
...
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
This is a special API that intentionally makes it difficult to insert raw HTML, but for Showdown we'll take advantage of this backdoor.
Remember: by using this feature you're relying on Showdown to be secure.
So there exists an API for inserting raw HTML, but the method name and the docs all warn against it. Is it safe to use this? For example, I have a chat app that takes Markdown comments and converts them to HTML strings. The HTML snippets are generated on the server by a Markdown converter. I trust the converter, but I'm not sure if there's any way for a user to carefully craft Markdown to exploit XSS. Is there anything else I should be doing to make sure this is safe?
Most Markdown processors (and I believe Showdown as well) allow the writer to use inline HTML. For example a user might enter:
This is _markdown_ with a <marquee>ghost from the past</marquee>. Or even **worse**:
<script>
alert("spam");
</script>
As such, you should have a whitelist of tags and strip all the other tags after converting from markdown to html. Only then use the aptly named dangerouslySetInnerHTML.
Note that this also what Stackoverflow does. The above Markdown renders as follows (without you getting an alert thrown in your face):
This is markdown with a ghost from the past. Or
even worse:
alert("spam");
There are three reasons it's best to avoid html:
security risks (xss, etc)
performance
event listeners
The security risks are largely mitigated by markdown, but you still have to decide what you consider valid, and ensure it's disallowed (maybe you don't allow images, for example).
The performance issue is only relevant when something will change in the markup. For example if you generated html with this: "Time: <b>" + new Date() + "</b>". React would normally decide to only update the textContent of the <b/> element, but instead replaces everything, and the browser must reparse the html. In larger chunks of html, this is more of a problem.
If you did want to know when someone clicks a link in the results, you've lost the ability to do so simply. You'd need to add an onClick listener to the closest react node, and figure out which element was clicked, delegating actions from there.
If you would like to use Markdown in React, I recommend a pure react renderer, e.g. vjeux/markdown-react.

jade / express - when to use or not to use layouts

I've just started developing in express and am new to Jade as well.
I'm having trouble deciding when it's appropriate to use layouts and when not to. I'm also having trouble deciding when it's appropriate to use something like blocks vs. partials.
Any help regarding this is truly appreciated. I'm a little lost.
It's mostly a matter of preference. If you are used to something like Wordpress where you have a concept of a header and footer that you include into pages than you might not like layouts. I personally only use layouts with content blocks because the non-layout way tends to cause more repetition.
As for partials vs blocks. You use a partial for items that you want to reuse on different pages. While a block is a chunk of html that will be replaced by child templates.
An example of a partial can be the html for a product. So you have a thumbnail, the title and a description of a product. You might use this partial while listing the products in a category. But you might also use this partial for rendering a list of search results.
An example of a partial can be a main layout that contains you header and your navigation and a content area. If you want to reuse this main layout on multiple pages you will extend this it and overwrite the block in the child templates.

Using symfony layouts outside of view

I want to create a custom ./config/unavailable.php page using the layouts and styling used by the rest of my application. I could just copy the generated HTML that one of these pages renders, but then if I ever change the layout or style I would have to re-copy.
How can I render the unavailable.php page the same way I render the views?
I am using symfony 1.4.
unavailable.php is called when symfony is busy clearing its cache. You might want not to disturb it too much at this moment, that's why plain php is used. Copying html could be done by a cron task though, so if I were you I would try to combine cron, wget and sed to achieve this.
I'd suggest keeping it as manual HTML, a simple page. Whatever you need to do to copy over layouts/templates (which contain stuff that Symfony needs to execute to generate) isn't worth unless you plan having your app unavailable for most of the time. It's just easier to copy things over manually if you ever decide to make big CSS changes.

Resources