grunt-translate-compile
A pre-compiler for angular-translate based on TL: a simple write-less markup specially designed for angular-translate.
1. Translation Markup - TL
The translation markup intends to drastically reduce the amount of typing needed to translate your app, by keeping it simpler and improving it's maintenance.
Briefing: A translation file begins with the declaration of all supported languages of your application. A custom numeric code (key) must be assigned to each one of the declared languages. In the sample that comes next, we're saying that [american english code is 1], [brazilian portuguese is 2] and [spanish from spain is 3]. Translation values are assigned directly to the language key.
Tabs must be used for indentation. Spaces are not yet allowed. Indentation must be respected to avoid unwanted results.
1.1 - Hello World from TL
LANGUAGES
1:english
2:deutsch
HELLO
WORLD
1:Hello World
2:Hallo Welt
Compiled:
var angTranslations = {
"english": {
"HELLO": {
"WORLD": "Hello World"
}
},
"deutsch": {
"HELLO": {
"WORLD": "Hallo Welt"
}
}
};
1.2 - Type translations keys only once for all your languages
LANGUAGES
1:english
2:deutsch
3:spanish
4:portuguese
UNITED_STATES
NAME
1:United States
2:Vereinigte Staaten
3,4:Estados Unidos
LANGUAGE
1:English
2:Englisch
3:Inglés
4:Inglês
SPAIN
NAME
1:Spain
2:Spanien
3:España
4:Espanha
LANGUAGE
1:Spanish
2:Spanisch
3:Español
4:Espanhol
BRAZIL
NAME
1:Brazil
2:Brasilien
3,4:Brasil
LANGUAGE
1:Portuguese
2:Portugiesisch
3:Portugués
4:Português
Compiled:
var angTranslations = {
"english": {
"UNITED_STATES": {
"NAME": "United States",
"LANGUAGE": "English"
},
"SPAIN": {
"NAME": "Spain",
"LANGUAGE": "Spanish"
},
"BRAZIL": {
"NAME": "Brazil",
"LANGUAGE": "Portuguese"
}
},
"deutsch": {
"UNITED_STATES": {
"NAME": "Vereinigte Staaten",
"LANGUAGE": "Englisch"
},
"SPAIN": {
"NAME": "Spanien",
"LANGUAGE": "Spanisch"
},
"BRAZIL": {
"NAME": "Brasilien",
"LANGUAGE": "Portugiesisch"
}
},
"spanish": {
"UNITED_STATES": {
"NAME": "Estados Unidos",
"LANGUAGE": "Inglés"
},
"SPAIN": {
"NAME": "España",
"LANGUAGE": "Español"
},
"BRAZIL": {
"NAME": "Brasil",
"LANGUAGE": "Portugués"
}
},
"portuguese": {
"UNITED_STATES": {
"NAME": "Estados Unidos",
"LANGUAGE": "Inglês"
},
"SPAIN": {
"NAME": "Espanha",
"LANGUAGE": "Espanhol"
},
"BRAZIL": {
"NAME": "Brasil",
"LANGUAGE": "Português"
}
}
};
Notice how the writing was significantly reduced as it's no longer needed to rewrite every key for each language, we are also skipping blocks and quotes. Thus we can focus on what really matters: the translations. Maintenance is also greatly improved, as adding a new key will no longer be a hunt for the right spot of each language.
1.3 - Type repeated translation values only once too
LANGUAGES
1:enUS
2:ptBR
3:esES
CREDIT_CARD
NAME
1:Credit Card
2:Cartão de Crédito
3:Tarjeta de Crédito
FLAG
VISA
1,2,3:Visa
MASTERCARD
1,2,3:Mastercard
AMEX
1,2,3:American Express
DINERS
1,2,3:Diners
Compiled:
var angTranslations = {
"enUS": {
"CREDIT_CARD": {
"NAME": "Credit Card",
"FLAG": {
"VISA": "Visa",
"MASTERCARD": "Mastercard",
"AMEX": "American Express",
"DINERS": "Diners"
}
}
},
"ptBR": {
"CREDIT_CARD": {
"NAME": "Cartão de Crédito",
"FLAG": {
"VISA": "Visa",
"MASTERCARD": "Mastercard",
"AMEX": "American Express",
"DINERS": "Diners"
}
}
},
"esES": {
"CREDIT_CARD": {
"NAME": "Tarjeta de Crédito",
"FLAG": {
"VISA": "Visa",
"MASTERCARD": "Mastercard",
"AMEX": "American Express",
"DINERS": "Diners"
}
}
}
};
1.4 - Organize your translations into multiple files
Although we recommend you to include language declarations in all your translation files, they are only required in the first read translation file. Language declarations will often serve you as legend for language keys/values.
File 1: menu.tl
LANGUAGES
1:enUs
2:ptBr
3:esEs
MENU
CART
EMPTY
1:Empty Cart
2:Esvaziar Carrinho
3:Vaciar Carrito
CHECKOUT
1:Checkout
2:Fechar Pedido
3:Realizar Pedido
USER
LABEL
1:User
2:Usuário
3:Usuario
DROPDOWN
EDIT
1:Edit
2,3:Editar
LOGOUT
1:Logout
2:Sair
3:Finalizar la Sesión
File 2: country.tl
LANGUAGES
1:enUs
2:ptBr
3:esEs
COUNTRY
USA
NAME
1:United States
2,3:Estados Unidos
LANGUAGE
1:English
2:Inglês
3:Inglés
BRAZIL
NAME
1:Brazil
2,3:Brasil
LANGUAGE
1:Portuguese
2:Português
3:Portugués
SPAIN
NAME
1:Spain
2:Espanha
3:España
LANGUAGE
1:Spanish
2:Espanhol
3:Español
File 3: us-states.tl
LANGUAGES
1:enUs
2:ptBr
3:esEs
COUNTRY
USA
STATES
CALIFORNIA
NAME
1,3:California
2:Califórnia
ACRONYM
1,2,3:CA
NEW_YORK
NAME
1:New York
2:Nova Iorque
3:Nueva York
ACRONYM
1,2,3:NY
NORTH_CAROLINA
NAME
1:North Carolina
2:Carolina Do Norte
3:Carolina del Norte
ACRONYM
1,2,3:NC
Compiled Result:
var angTranslations = {
"enUs": {
"COUNTRY": {
"USA": {
"NAME": "United States",
"LANGUAGE": "English",
"STATES": {
"CALIFORNIA": {
"NAME": "California",
"ACRONYM": "CA"
},
"NEW_YORK": {
"NAME": "New York",
"ACRONYM": "NY"
},
"NORTH_CAROLINA": {
"NAME": "North Carolina",
"ACRONYM": "NC"
}
}
},
"BRAZIL": {
"NAME": "Brazil",
"LANGUAGE": "Portuguese"
},
"SPAIN": {
"NAME": "Spain",
"LANGUAGE": "Spanish"
}
},
"MENU": {
"CART": {
"EMPTY": "Empty Cart",
"CHECKOUT": "Checkout"
},
"USER": {
"LABEL": "User",
"DROPDOWN": {
"EDIT": "Edit",
"LOGOUT": "Logout"
}
}
}
},
"ptBr": {
"COUNTRY": {
"USA": {
"NAME": "Estados Unidos",
"LANGUAGE": "Inglês",
"STATES": {
"CALIFORNIA": {
"NAME": "Califórnia",
"ACRONYM": "CA"
},
"NEW_YORK": {
"NAME": "Nova Iorque",
"ACRONYM": "NY"
},
"NORTH_CAROLINA": {
"NAME": "Carolina Do Norte",
"ACRONYM": "NC"
}
}
},
"BRAZIL": {
"NAME": "Brasil",
"LANGUAGE": "Português"
},
"SPAIN": {
"NAME": "Espanha",
"LANGUAGE": "Espanhol"
}
},
"MENU": {
"CART": {
"EMPTY": "Esvaziar Carrinho",
"CHECKOUT": "Fechar Pedido"
},
"USER": {
"LABEL": "Usuário",
"DROPDOWN": {
"EDIT": "Editar",
"LOGOUT": "Sair"
}
}
}
},
"esEs": {
"COUNTRY": {
"USA": {
"NAME": "Estados Unidos",
"LANGUAGE": "Inglés",
"STATES": {
"CALIFORNIA": {
"NAME": "California",
"ACRONYM": "CA"
},
"NEW_YORK": {
"NAME": "Nueva York",
"ACRONYM": "NY"
},
"NORTH_CAROLINA": {
"NAME": "Carolina del Norte",
"ACRONYM": "NC"
}
}
},
"BRAZIL": {
"NAME": "Brasil",
"LANGUAGE": "Portugués"
},
"SPAIN": {
"NAME": "España",
"LANGUAGE": "Español"
}
},
"MENU": {
"CART": {
"EMPTY": "Vaciar Carrito",
"CHECKOUT": "Realizar Pedido"
},
"USER": {
"LABEL": "Usuario",
"DROPDOWN": {
"EDIT": "Editar",
"LOGOUT": "Finalizar la Sesión"
}
}
}
}
};
2. Grunt Plugin
2.1 - Getting Started
This plugin requires Grunt ~0.4.5
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
npm install grunt-translate-compile --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
grunt.loadNpmTasks('grunt-translate-compile');
2.2 - The "translate_compile" task - Overview
1. Add the task
In your project's Gruntfile, add a section named translate_compile
to the data object passed into grunt.initConfig()
.
grunt.initConfig({
translate_compile: {
compile: {
options: {
// task-specific options go here. refer to options topic
},
files: {
// post-compiling file to the left, pre-compiling files to the right
'compiled-translations.js': ['translations/*.tl']
}
}
}
});
2. Let your server know about it
Remember to include "translate_compile" inside your server task so the compilation takes place when you start it (connect/express). Something like:
grunt.registerTask('serve', function (target) {
grunt.task.run([
'clean:server',
'translate_compile:compile', // <-- here it is
'bowerInstall',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});
3. Watch it
For a better experience, watch for any changes made to your translation files (requires grunt-contrib-watch). Something like:
watch: {
tl: {
files: ['translations/*.tl'],
tasks: ['translate_compile:compile'],
options: {
livereload: true
}
}
},
4. Take to your build
Add the "translate_compile" to your build task. Something like:
grunt.registerTask('build', [
'clean:dist'
'bowerInstall',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngmin',
'translate_compile:compile', // <-- here it is
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
You should now be good to go!
2.3 - Options
options.translationVar
Type: String
Default value: 'angTranslations'
Determines the name of the compiled variable. Ex: var angTranslations = {"usEn":{...}}
options.multipleObjects
Type: Boolean
Default value: false
If multipleObjects
is set to true
there will no longer be only one root variable like angTranslations
. Translations will now be splitted into one object per language. Ex: var enUs = {...}; var ptBr = {...}; var esEs = {...};
Variable names will the ones declared in the LANGUAGES
section.
options.asJson
Type: Boolean
Default value: false
Should this value be set to true there will be no variable assignment inside the file, only the resulting json will be there.
3. Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.
4. Release History
(Nothing yet)