mashpie / i18n-node

Lightweight simple translation module for node.js / express.js with dynamic json storage. Uses common __('...') syntax in app and templates.
MIT License
3.08k stars 421 forks source link

How to foreach list languages supports in express-handlebars #310

Open 2pay opened 7 years ago

2pay commented 7 years ago

am use i18n for support multi languages.

  1. I can't find documents for list languages pass to views.
{{#each languages}}
<li><button onclick="window.location.href='/{{this.langcode}}';" class="btn btn-link btn-block language-select" type="button" name="VN"><img src="/images/{{this.langcode}}.png" alt="{{this.langname}}" title="{{this.langname}}" /> {{this.langname}}</button></li>
{{/each}}
  1. how to get default data

Current i do static html:

<div id="language" class="btn-group">

                        <button class="btn-link dropdown-toggle" data-toggle="dropdown"> <span> <img src="/images/{{language}}.png" alt="Việt Nam" title="Việt Nam">{{langname}} <i class="fa fa-caret-down"></i></span></button>

                        <ul class="dropdown-menu">
                            <li>
                                <button onclick="window.location.href='/vi';" class="btn btn-link btn-block language-select" type="button" name="language"><img src="/images/vi.png" alt="Việt Nam" title="Việt Nam" /> Việt Nam</button>
                            </li>
                            <li>
                                <button onclick="window.location.href='/en';" class="btn btn-link btn-block language-select" type="button" name="GB"><img src="/images/en.png" alt="English" title="English" /> English</button>
                            </li>
                        </ul>
                    </div>

thankyou any solution

mashpie commented 7 years ago

use i18n.getLocales() https://github.com/mashpie/i18n-node#i18ngetlocales and pass the result to locals of your view.

for one view only

app.get('/setlanguage', (req, res) => {
  res.render('languagesetting', {
    languages: i18n.getLocales()
  });
});

or more generally for all view by middleware

app.use((req, res, next) => {
  res.locals.languages: i18n.getLocales();
  next();
});
2pay commented 7 years ago

Thankyou @mashpie. i18n have support language name?

Update: current i using:

var mylangs = [],
        langs = i18n.getLocales(),
        name = "",
        code = "";

    for (var lg in langs) {

        if (langs[lg] === "vi") {
            code = langs[lg];
            name = "Việt Nam";
            mylangs.push({ "code": code, "name": name });
        } else if (langs[lg] === "en") {
            code = langs[lg];
            name = "English";
            mylangs.push({ "code": code, "name": name });
        }

        console.log(mylangs);
    }
    res.locals.mylangs = mylangs;

any best solution support code and name pass to views

mashpie commented 7 years ago

erm, I think the easiest way is adding those to your translations like

en.json

{
    "en": "english",
    "de": "german"
}

de.json

{
    "en": "Englisch",
    "de": "Deutsch"
}

and using i18n helper to display (example in hbs)

{{#each languages}}
    <a href="/{{this}}">{{@root.__ this}}</a>
{{/each}}
2pay commented 7 years ago

Thankyou @mashpie This is a great support for me. My part project is completed.

Update:

How to use translate in method no req and res. I have passport login:

router.post('/login', passport.authenticate('local.login', {
    successRedirect: '/users/account',
    failureRedirect: '/users/login',
    badRequestMessage: 'Please input all fields.',
    failureFlash: true
}));

how to translate badRequestMessage: 'Please input all fields.',

app.use(function(req, res, next) {
res.locals.__ = function() {
        return function(text, render) {
            return i18n.__.apply(req, arguments);
        };
    };
});

i use ('Please input all fields.') but error `ReferenceError: is not defined`

mashpie commented 7 years ago

You'll need to wrap the passport handler within an express route handler.

I din't try out myself, but I guess it'll look something like this:

router.post('/login', (req, res) => passport.authenticate('local.login', {
    successRedirect: '/users/account',
    failureRedirect: '/users/login',
    badRequestMessage: res.__('Please input all fields.'),
    failureFlash: true
}));