├── .bowerrc ├── .gitignore ├── angular ├── routes │ └── home │ │ ├── home.html │ │ └── HomeController.js ├── app.sass ├── common │ └── localeSelector │ │ ├── locale-selector.html │ │ └── locale-selector.js └── app.js ├── run.js ├── app ├── i8n │ ├── en.json │ ├── es.json │ └── fr.json ├── views │ ├── error.jade │ └── index.jade └── routes │ └── api.js ├── README.md ├── bower.json ├── package.json ├── config.coffee └── server.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /bower_components 3 | /public 4 | /.idea -------------------------------------------------------------------------------- /angular/routes/home/home.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ 'home.helloWorld' | translate }}

-------------------------------------------------------------------------------- /run.js: -------------------------------------------------------------------------------- 1 | module.exports = (function() { 2 | require('./server.js').startServer(8080, null, function() {}); 3 | })(); -------------------------------------------------------------------------------- /app/i8n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageNames": { 3 | "en": "English", 4 | "es": "Spanish", 5 | "fr": "French" 6 | }, 7 | "home": { 8 | "helloWorld": "Hello, World!" 9 | } 10 | } -------------------------------------------------------------------------------- /app/i8n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageNames": { 3 | "en": "Inglés", 4 | "es": "Español", 5 | "fr": "Francés" 6 | }, 7 | "home": { 8 | "helloWorld": "Hola Mundo!" 9 | } 10 | } -------------------------------------------------------------------------------- /app/i8n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageNames": { 3 | "en": "Anglais", 4 | "es": "Espagnol", 5 | "fr": "Français" 6 | }, 7 | "home": { 8 | "helloWorld": "Bonjour Le Monde!" 9 | } 10 | } -------------------------------------------------------------------------------- /app/views/error.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | title Page Not Found 5 | body 6 | p 404 - Page Not Found 7 | p Uh oh! Looks like you found a page that doesn't exist? -------------------------------------------------------------------------------- /angular/app.sass: -------------------------------------------------------------------------------- 1 | * 2 | box-sizing: border-box 3 | 4 | html, 5 | body 6 | width: 100% 7 | height: 100% 8 | padding: 0 9 | border: 0 10 | margin: 0 11 | background-color: white 12 | color: black 13 | 14 | .wrapper 15 | width: 100% 16 | height: 100% -------------------------------------------------------------------------------- /angular/routes/home/HomeController.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('i18nOutlandishApp') 3 | .controller('HomeController', function($scope, $rootScope) { 4 | "use strict"; 5 | 6 | $rootScope.className = 'home'; 7 | $rootScope.title = 'Home'; 8 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## An Example of Internationalisation using angular-translate, Express, and Node 2 | 3 | Please visit [our website](http://outlandish.com/blog/internationalisation-using-angular-translate-express-and-node/?post_type=blog&p=3049&preview=true "Internationalisation using angular-translate, Express, and Node") to see more details. 4 | 5 | This application uses Brunch. -------------------------------------------------------------------------------- /app/views/index.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en", ng-app="i18nOutlandishApp") 3 | head 4 | title {{ title }} 5 | base(href="/") 6 | link(rel="stylesheet", href="/css/app.css") 7 | body 8 | div(ng-view, class="wrapper {{ className }}") 9 | script(src="/js/vendor.js", type="text/javascript") 10 | script(src="/js/templates.js", type="text/javascript") 11 | script(src="/js/app.js", type="text/javascript") -------------------------------------------------------------------------------- /angular/common/localeSelector/locale-selector.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i18n-outlandish-app", 3 | "version": "1.0.0", 4 | "description": "An example of internationalisation using angular-translate.", 5 | "main": "run.js", 6 | "license": "MIT", 7 | "private": true, 8 | "dependencies": { 9 | "angular": "~1.3.8", 10 | "angular-route": "~1.3.6", 11 | "angular-translate": "~2.5.2", 12 | "angular-translate-loader-url": "~2.5.2", 13 | "angular-translate-storage-cookie": "~2.5.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/routes/api.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | app.get('/api/lang', function(req, res) { 3 | // Check endpoint called with appropriate param.: 4 | if(!req.query.lang) { 5 | res.status(500).send(); 6 | return; 7 | } 8 | 9 | try { 10 | var lang = require('../i18n/' + req.query.lang); 11 | res.send(lang); // `lang ` contains parsed JSON 12 | } catch(err) { 13 | res.status(404).send(); 14 | } 15 | }); 16 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i18n-outlandish-app", 3 | "version": "1.0.0", 4 | "description": "An example of internationalisation using angular-translate.", 5 | "private": true, 6 | "main": "run.js", 7 | "dependencies": { 8 | "angularjs-templates-brunch": "0.0.3", 9 | "auto-reload-brunch": ">=1.7.5", 10 | "autoprefixer-brunch": "^1.8.3", 11 | "autoprefixer-core": "^3.1.0", 12 | "body-parser": "^1.8.1", 13 | "express": "^4.10.4", 14 | "jade": "^1.7.0", 15 | "javascript-brunch": ">=1.7.1", 16 | "jshint-brunch": "^1.7.0", 17 | "sass-brunch": "^1.8.8" 18 | } 19 | } -------------------------------------------------------------------------------- /angular/common/localeSelector/locale-selector.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('i18nOutlandishApp') 3 | .directive('localeSelector', function($translate) { 4 | return { 5 | restrict: 'C', 6 | replace: true, 7 | templateUrl: 'angular/common/localeSelector/locale-selector.html', 8 | link: function(scope, elem, attrs) { 9 | scope.locale = $translate.proposedLanguage(); 10 | 11 | scope.setLocale = function() { 12 | $translate.use(scope.locale); 13 | }; 14 | } 15 | }; 16 | }); -------------------------------------------------------------------------------- /angular/app.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('i18nOutlandishApp', ['ngRoute', 'ngCookies', 'pascalprecht.translate', 'templates']) 3 | .config(function($routeProvider, $locationProvider, $translateProvider) { 4 | "use strict"; 5 | 6 | $routeProvider 7 | .when('/', { 8 | templateUrl: 'angular/routes/home/home.html', 9 | controller: 'HomeController' 10 | }) 11 | .otherwise({ 12 | redirectTo: '/' 13 | }); 14 | 15 | $translateProvider.useCookieStorage(); 16 | $translateProvider.useUrlLoader('/api/lang'); 17 | $translateProvider.preferredLanguage('en'); 18 | 19 | $locationProvider.html5Mode(true); 20 | }); -------------------------------------------------------------------------------- /config.coffee: -------------------------------------------------------------------------------- 1 | exports.config = 2 | modules: 3 | definition: false 4 | wrapper: false 5 | paths: 6 | public: 'public' 7 | watched: ['angular'] 8 | notifications: true 9 | files: 10 | stylesheets: 11 | joinTo: 12 | 'css/app.css': /^(angular|vendor|bower_components)/ 13 | order: 14 | before: ['angular/app.sass'] 15 | templates: 16 | joinTo: 17 | 'js/templates.js': /^angular/ 18 | javascripts: 19 | joinTo: 20 | 'js/app.js': /^angular/ 21 | 'js/vendor.js': /^bower_components/ 22 | order: 23 | before: ['angular/app.js'] 24 | server: 25 | path: 'server.js' 26 | port: 8080 27 | watcher: 28 | usePolling: true 29 | plugins: 30 | sass: 31 | mode: 'ruby' 32 | autoprefixer: 33 | browsers: ["last 1 version", "> 1%", "ie 8", "ie 7"] 34 | cascade: false 35 | minify: true -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | module.exports.startServer = function(PORT, PATH, CALLBACK) { 2 | var express = require('express'), 3 | bodyParser = require('body-parser'), 4 | path = require('path'), 5 | fs = require('fs'), 6 | app = express(), 7 | server = app.listen(PORT, CALLBACK); 8 | 9 | /******************************************************************************************************************* 10 | * EXPRESS CONFIG * 11 | ******************/ 12 | 13 | 14 | // Define where our static files will be fetched from: 15 | app.use(express.static(path.join(__dirname, 'public'))); 16 | 17 | app.use(bodyParser.json()); 18 | app.use(bodyParser.urlencoded({ extended: true })); 19 | 20 | // Tell Express where our server views (Jade files) are kept. 21 | // Then we can do render('NAME_OF_VIEW') inside an Express route request. e.g. render('index') 22 | app.set('views', path.join(__dirname, 'app/views')); 23 | app.set('view engine', 'jade'); 24 | 25 | /******************************************************************************************************************* 26 | * ROUTE CONFIG * 27 | ****************/ 28 | 29 | require('./app/routes/api')(app); 30 | 31 | app.get('/*', function (req, res) { 32 | // Render index and pass route handling to Angular 33 | res.render('index'); 34 | }); 35 | 36 | app.all('/*', function(req, res) { 37 | // Client is lost... render error page! 38 | res.render('error'); 39 | }); 40 | 41 | console.log('Application running.'); 42 | }; --------------------------------------------------------------------------------