
Question:
For the last few days I was looking for a viable solution in order to optimize html page titles <title>SOME_TITLE</title>
within sails.js layout files, like layout.ejs
, that by default use a static page title. <br />
Obviously, it would be way better to have dynamic page titles, e.g. Dashboard, Shopping Cart, etc... <br />
Other people were looking for this answer before and got answers for prior sails versions in <a href="https://stackoverflow.com/questions/31148841/how-can-i-set-different-title-values-for-each-template-in-ejs" rel="nofollow">Solution 1</a>, <a href="https://stackoverflow.com/questions/20267550/what-is-the-proper-way-to-integrate-dynamic-content-into-the-layout-ejs-file-in" rel="nofollow">Solution 2</a> and <a href="https://stackoverflow.com/questions/18292415/where-is-title-or-app-name-for-sails-js-using-node-js-and-express-js" rel="nofollow">Solution 3</a>.
Unfortunately, none of them seem to be appropriate for the latest version of sails.js (as of this post).
<a href="https://stackoverflow.com/questions/31148841/how-can-i-set-different-title-values-for-each-template-in-ejs" rel="nofollow">Solution 1</a> was leading in the right direction and suggested what I was looking for. But you had to define a title
for every controller and pass it into the view. Otherwise you will get
title is not defined at eval
</blockquote>So how to define a local variable that is accessible in each controller/view by default?
Answer1:So one working complete solution for the current sails.js version is the following:<br />
In your layout.ejs
file define a dynamic page title like this
<head>
<title>
<%= title %>
</title>
...
</head>
...
Create a new custom hook, e.g. api/hooks/dynamic-page-title/index.js
module.exports = function dynamicPageTitleHook(sails) {
return {
routes: {
/**
* Runs before every matching route.
*
* @param {Ref} req
* @param {Ref} res
* @param {Function} next
*/
before: {
'/*': {
skipAssets: true,
fn: async function(req, res, next){
// add page title variable to each response
if (req.method === 'GET') {
if (res.locals.title === undefined) {
res.locals.title = 'plusX';
}
}
return next();
}
}
}
}
};
};
Now overwrite the page title in every controller that should use a custom page title, e.g. view-login.ejs
module.exports = {
friendlyName: 'View login',
description: 'Display "Login" page.',
exits: {
success: {
viewTemplatePath: 'pages/entrance/login',
},
redirect: {
description: 'The requesting user is already logged in.',
responseType: 'redirect'
}
},
fn: async function (inputs, exits) {
if (this.req.me) {
throw {redirect: '/'};
}
return exits.success({title: 'Login'});
}
};