1

I'm new to the whole nodejs ecosystem so kindly speak slowly and use small words.

In the past when developing a website with PHP I would typically have header.php and footer.php includes. The header include typically contains the HTML head element, so to define default values for the title and meta tags, in header.php I have typically implemented logic like this:

if (title is not defined) {
    use some default title;
}

This allows me to catch the case where I haven't set title or meta description tags for some individual pages, and use some default global values.

I'm trying to do the same thing now in sails.js and I'm getting some strange results. In some view (e.g. "test.ejs") I have:

<%
    var pg_title = 'test';
%>
<%- include header.ejs %>

and then in the header I have:

<%
    console.log(pg_title);
%>

This works. (i.e. it echoes "test")

However, if header.ejs contains any kind of test for whether pg_title has been defined, then the value of pg_title that was set in test.ejs is always ignored (it echoes "undefined").

At the moment, header.ejs contains the following code, but I've tried several different things.

if (typeof pg_title == 'undefined') {
    var pg_title = __('pg_title_default');    
}

The above condition will always evaluate to true. If I remove "var" in header.ejs as Ravi suggests below, I get a "pg_title is not defined" error.

What am I doing wrong?

Naeem Shaikh
  • 15,331
  • 6
  • 50
  • 88
jasper
  • 137
  • 1
  • 9
  • 1
    Well, for one, try removing var before pg_title declaration. – Ravi Dec 20 '14 at 05:55
  • Ravi's likely right here. It sounds as though the scopes aren't the same, so declaring a variable in a template only applies to that template (and not any includes). Removing the `var` keyword will essentially make it a global value. That said, I'm not at all familiar with EJS. –  Dec 20 '14 at 12:07
  • but I quote directly from https://github.com/tj/ejs#includes : "The included file(s) are literally included into the template, no IO is performed after compilation, thus local variables are available to these included templates." – jasper Dec 20 '14 at 12:24
  • @Ravi: I tried your suggestion, but then if pg_title is not included in test.ejs, I get an error. – jasper Dec 20 '14 at 12:25
  • @jasper i am not telling to remove it, change `var pg_title` to `pg_title`. – Ravi Dec 22 '14 at 07:58

1 Answers1

3

You shouldn't be setting variables in templates like this. Besides the clearly aggravating scope issues, it's just muddling the layers of your app and giving you one more place to have to check when things go wrong. Set your view locals in:

If you need to set some defaults for view locals, a policy would be a good place.

So, what you're trying to do is bad practice. As for the reason why it's not working, it's the second var that's the problem, as in var pg_title = __('pg_title_default'). It's causing some of those aggravating scoping issues I mentioned, when ejs tries to eval that code block.

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • Thanks sgress (and everyone else)-- I would have thought that putting the second var in a condition would have prevented any problems, but I guess not. – jasper Dec 26 '14 at 08:53