2

I have an express static site app. I calling my site's translation with a cookie in app.js:

// i18n
app.get('/hu', function (req, res) { // http://127.0.0.1:3000/hu
  res.cookie('locale', 'hu', { maxAge: 900000, httpOnly: true });
  res.redirect('back');
});
app.get('/en', function (req, res) { // http://127.0.0.1:3000/en
  res.cookie('locale', 'en', { maxAge: 900000, httpOnly: true });
  res.redirect('back');
});

If someone visiting http://127.0.0.1:3000/en URL, than it will store a cookie which calling the translation. hu is the default language, when someone visiting my site at the first time, there's no any cookie stored.

But how can I add a CSS class to my site when the english translation is active? I have a navigation bar with my logo in the middle which is centered horizontally. On english language, the words length different, causing even the centered flexbox elements left-nav | logo | right-nav slightly not be in the center.

Somehow I want to add a CSS class into my handlebar template from app.js (which is on the server side) when the specific cookie is presented. Is it possible?

Is it possible to solve this from app.js globally, not from the routers?

Final solution, thank you for @t.niese!

In app.js:

app.use(function(req, res, next) {
  var defaultLang = 'hu';
  var activeLang = req.cookies.locale || defaultLang;
  res.locals.langClass = activeLang + '-' + activeLang.toUpperCase();
  next();
});

In my handlebars template:

<!doctype html>
<html class="no-js lang-{{langClass}}" lang="{{langClass}}">
Lanti
  • 2,299
  • 2
  • 36
  • 69

2 Answers2

4

You would define your own middleware function that will set e.g. langClass for your template values based on the cookie value of locale:

app.use(function(req, res, next) {
  var activeLang = req.cookies.locale || defaultLang;

  req.local.langClass = 'lang-'+activeLang;

  next();
});

Then you can use this in your template as class:

<html class="{{langClass}}">
</html>

You can't solve it globally, because then the language would be the same for every visitor.

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • Thank You! This works. I updated my question with your slightly modified code. Can you check it is it ok? – Lanti Mar 25 '16 at 15:16
  • 1
    @Lanti Looks correct. Sorry somehow thought, that the cookie value was called `lang`. – t.niese Mar 25 '16 at 15:20
  • I slightly modified again. This time I adding the class to the `` tag both `class=""` and `lang=""` attributes creating an `en-EN` format. Accessibility devices will appretiate this. – Lanti Mar 25 '16 at 15:29
2

This is possible.

You can store the data needed in the app.locals variable.

// i18n
app.get('/hu', function (req, res) { // http://127.0.0.1:3000/hu
  res.cookie('locale', 'hu', { maxAge: 900000, httpOnly: true });
  app.locals.lang = 'lang-hu';
  res.redirect('back');
});

app.get('/en', function (req, res) { // http://127.0.0.1:3000/hu
  res.cookie('locale', 'en', { maxAge: 900000, httpOnly: true });
  app.locals.lang = 'lang-en';
  res.redirect('back');
});

In the route handler, the current language is available in app.locals.

app.get('/', function(req, res) {
  var langClass = app.locals.lang;
  // Do something with variable
});
gnerkus
  • 11,357
  • 6
  • 47
  • 71
  • Is it possible to ditch query strings? If user clicks on `EN` link, than it will redirect them to `http://127.0.0.1:3000/prevUrl?langclass=lang-en` URL. However if he clicks on another link on the page, the query strings will disappear causing the CSS class added by the templating engine also disappear. – Lanti Mar 25 '16 at 14:26
  • `app.locals` and `res.locals` can be used to store the CSS class inside my `app.get`? – Lanti Mar 25 '16 at 14:32
  • This is works inside the router: `if(req.cookies.locale === 'en') { var langClass = 'lang-en'; };` than `res.render('portfolio', { layout: 'main', bodyClass: langClass });` and in the handlebars template I simply call with ``. But my routers starting to look overdefined. Is it possible to move this out from the router into app.js? – Lanti Mar 25 '16 at 14:37
  • 1
    Yes, `app.locals` can be used to store the CSS class. – gnerkus Mar 25 '16 at 14:37
  • 3
    Using `app.locals.lang` is a bad idea, at least if you want to allow different users to choose different languages. With `app.locals.lang` you would change the language for all users. – t.niese Mar 25 '16 at 14:58