├── LICENSE ├── README.md ├── index.js ├── package.json └── replace.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Florian Morel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-lang for Vue 2.x 2 | 3 | ## Installation 4 | 5 | ``` 6 | $ npm install vue-lang --save 7 | ``` 8 | 9 | ## Setup 10 | 11 | ```js 12 | import Vue from 'vue' 13 | import Lang from 'vue-lang' 14 | 15 | const locales = { 16 | 'en': require('./langs/en.json'), 17 | 'br': require('./langs/br.json'), 18 | 'nl': require('./langs/nl.json') 19 | } 20 | 21 | Vue.use(Lang, {lang: 'en', locales: locales}) 22 | ``` 23 | 24 | Where `en.json` is defined as: 25 | 26 | ```js 27 | { 28 | "hello": "World", 29 | "messages": "You have {0} {1} messages", 30 | } 31 | ``` 32 | 33 | 34 | ## Usage 35 | 36 | ### Language output 37 | 38 | ```html 39 |
Hello {{$lang.hello}}
40 |{{$lang.messages | replace countmsg 'new'}}
41 | ``` 42 | 43 | With: 44 | 45 | ```js 46 | { 47 | "data": { 48 | "countmsg": 5 49 | } 50 | } 51 | ``` 52 | 53 | Results in: 54 | 55 | ```html 56 |Hello World
57 |You have 5 new messages
58 | ``` 59 | 60 | 61 | ### Change Language (reactive) 62 | 63 | ```js 64 | Vue.$setLang('nl') 65 | this.$setLang('nl') 66 | ``` 67 | 68 | ### Available Languages 69 | 70 | ```html 71 |Hello {{$l('cities.amsterdam'}}
80 | ``` 81 | 82 | ## Credits 83 | 84 | [@Haixing-Hu](https://github.com/Haixing-Hu/) & [@kazupon](https://github.com/kazupon/) for inspiration 85 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | ; (function () { 2 | var vueLang = {}; 3 | vueLang.install = function (Vue, options) { 4 | 5 | // register the replace filter (Credits: @Haixing-Hu, https://github.com/Haixing-Hu/vue-format/) 6 | var replace = require("./replace.js"); 7 | Vue.filter("replace", replace); 8 | 9 | // Set parameters 10 | Vue.locales = options.locales || {} 11 | var lang = options.lang || "" 12 | 13 | if(!options.lang){console.warn("vue-lang: No default language given. Please specify as {lang: ..}")} 14 | 15 | if(lang){ 16 | Vue.prototype.$lang = Vue.locales[lang] 17 | }else{ 18 | Vue.prototype.$lang = {} 19 | } 20 | 21 | Vue.prototype.$langs = Object.keys(Vue.locales) 22 | 23 | Vue.prototype.$setLang = function(language) { 24 | if(language && Vue.prototype.$langs.indexOf(language) > -1){ 25 | Vue.prototype.$lang = Vue.locales[language] 26 | update(this.$root); 27 | }else{ 28 | console.warn("vue-lang: Language not given or not initialized") 29 | } 30 | } 31 | } 32 | 33 | if (typeof exports == "object") { 34 | module.exports = vueLang; 35 | } else if (typeof define == "function" && define.amd) { 36 | define([], function () { return vueLang }); 37 | } else if (window.Vue) { 38 | window.vueLang = vueLang; 39 | Vue.use(vueLang); 40 | } 41 | 42 | /** 43 | * Credits: @Haixing-Hu 44 | * 45 | * Updates all the watchers in the Vue instance of a component tree. 46 | * 47 | * This function is inspired by the "_digest()" function in the 48 | * "src/instance/scope.js" of the source of Vue.js, excepts that this function 49 | * updates the children components no matter whether it is inheritable. 50 | * 51 | * @param vm 52 | * the root of the component tree. 53 | */ 54 | function update(vm) { 55 | var i = vm._watchers.length 56 | while (i--) { 57 | vm._watchers[i].update(true); // shallow updates 58 | } 59 | var children = vm.$children; 60 | i = children.length; 61 | while (i--) { 62 | var child = children[i] 63 | update(child) 64 | } 65 | } 66 | 67 | })(); 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-lang", 3 | "version": "0.2.2", 4 | "description": "Vue.js i18n language integration", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/kvdmolen/vue-lang" 12 | }, 13 | "keywords": [ 14 | "translation", 15 | "translate", 16 | "mixin", 17 | "vuejs", 18 | "vue", 19 | "lang", 20 | "langguage", 21 | "i18n" 22 | ], 23 | "author": "kvdmolen", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/kvdmolen/vue-lang/issues" 27 | }, 28 | "homepage": "https://github.com/kvdmolen/vue-lang" 29 | } 30 | -------------------------------------------------------------------------------- /replace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Replace {0} in message. Credits: @Haixing-Hu 3 | * 4 | * @param template 5 | * the message template, which contains zero or more placeholders, e.g., 6 | * "{0}", "{1}", ... 7 | * @param arg1, arg2, ... 8 | * zero or more arguments used to replace the corresponding placeholders 9 | * in the message template. 10 | * @return 11 | * the formatted message. 12 | * @author Haixing Hu 13 | */ 14 | 15 | var PLACEHOLDER_REGEXP = /\{([0-9a-zA-Z]+)\}/g; 16 | 17 | module.exports = function() { 18 | if(arguments.length === 0) { 19 | return "" 20 | }else if(arguments.length === 1) { 21 | return arguments[0] 22 | }else{ 23 | var args = arguments 24 | var message = args[0] 25 | return message.replace(PLACEHOLDER_REGEXP, function(match, placeholder, index) { 26 | if (message[index - 1] === "{" && message[index + match.length] === "}") { 27 | return placeholder; 28 | }else{ 29 | var i = parseInt(placeholder) 30 | var result = args[i + 1] 31 | if (result === null || result === undefined) { 32 | return "" 33 | }else{ 34 | return result 35 | } 36 | } 37 | }) 38 | } 39 | } --------------------------------------------------------------------------------