Skip to content

Instantly share code, notes, and snippets.

@dliv
Created February 14, 2017 23:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dliv/411586624c17b5100f2c5241954bccfe to your computer and use it in GitHub Desktop.
Save dliv/411586624c17b5100f2c5241954bccfe to your computer and use it in GitHub Desktop.
Example i18n Express Ap :app/categories/:category/keys/:key
const express = require('express');
const _ = require('lodash');
const bodyParser = require('body-parser');
const i18nApp = express.Router();
// parse application/x-www-form-urlencoded
// for easier testing with Postman or plain HTML forms
i18nApp.use(bodyParser.urlencoded({
extended: true,
}));
// parse application/json
i18nApp.use(bodyParser.json());
// real persistence left as a reader exercise
const data = {
'en-us': {
'wca': {
'login': {
'username': 'Username is case sensitive.',
'password': 'Password is case insensitive.'
}
},
'wsp': {
'start': {
'header': 'Get your quote in four easy steps.'
}
}
},
'es-mx': {
'wca': {
'login': {
'username': 'El nombre de usuario es sensible a mayúsculas.',
'password': 'La contraseña no distingue entre mayúsculas y minúsculas.'
}
},
'wsp': {
'start': {
'header': 'Obtenga su presupuesto en cuatro sencillos pasos.'
}
}
}
};
i18nApp.get('/', (req, res) => {
res.json(data);
});
// check `Accept-Language` header for requested locale
i18nApp.use((req, res, next) => {
const localeHeader = (req.header('accept-language') || '').toLowerCase();
const locales = localeHeader.split(',').map(s => s.trim());
const supportedLocales = _.keys(data);
const matchingLocales = _.intersection(locales, supportedLocales);
const locale = _.head(matchingLocales);
if (data[locale]) {
req.locale = locale;
next();
} else {
res.status(400).json({ message: `Missing or unrecognized header: 'accept-language'. Provided: "${localeHeader}". Expected one of: ${JSON.stringify(supportedLocales)}` });
}
});
i18nApp.get('/:app', (req, res) => {
const p = req.params;
const match = _.get(data, `${req.locale}.${p.app}`);
if (_.isEmpty(match)) {
res.status(404).json({ message: 'no matches' });
} else {
res.json(match);
}
});
i18nApp.get('/:app/categories', (req, res) => {
const p = req.params;
const match = _.keys(_.get(data, `${req.locale}.${p.app}`));
if (_.isEmpty(match)) {
res.status(404).json({ message: 'no matches' });
} else {
res.json(match);
}
});
i18nApp.get('/:app/categories/:category', (req, res) => {
const p = req.params;
const match = _.get(data, `${req.locale}.${p.app}.${p.category}`);
if (_.isEmpty(match)) {
res.status(404).json({ message: 'no matches' });
} else {
res.json(match);
}
});
i18nApp.get('/:app/categories/:category/keys', (req, res) => {
const p = req.params;
const match = _.keys(_.get(data, `${req.locale}.${p.app}.${p.category}`));
if (_.isEmpty(match)) {
res.status(404).json({ message: 'no matches' });
} else {
res.json(match);
}
});
i18nApp.get('/:app/categories/:category/keys/:key', (req, res) => {
const p = req.params;
const match = _.get(data, `${req.locale}.${p.app}.${p.category}.${p.key}`);
if (_.isEmpty(match)) {
res.status(404).json({ message: 'no matches' });
} else {
res.json(match);
}
});
i18nApp.post('/:app/categories/:category/keys/:key', (req, res) => {
const p = req.params;
const value = (req.body.value || '').toString().trim();
if (value) {
_.set(data, `${req.locale}.${p.app}.${p.category}.${p.key}`, value);
res.json({
key: `${req.locale}.${p.app}.${p.category}.${p.key}`,
value,
});
} else {
res.status(400).json({ message: `missing request param 'value'.`});
}
});
i18nApp.use((req, res) => {
res.status(404).json({ message: 'did not find endpoint' });
});
module.exports = i18nApp;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment