Grunt Locales- Manually Translation Required? - angularjs

I need my app internationalized and have setting grunt-locales. Simply by adding the data-localize directive the text inside should be translated. My initConfig is configured as such-
locales: {
options: {
locales: ['en_US', 'de_DE']
},
update: {
src: 'app/views/*.html',
dest: 'app/js/locales/{locale}/i18n.json'
},
build: {
src: 'app/js/locales/**/i18n.json',
dest: 'app/js/locales/{locale}/i18n.js'
},
'export': {
src: 'app/js/locales/**/i18n.json',
dest: 'app/js/locales/{locale}/i18n.csv'
},
'import': {
src: 'app/js/locales/**/i18n.csv',
dest: 'app/js/locales/{locale}/i18n.json'
}
},
And data-localized is used in one case in the app here-
<a href="#" data-localize>Forgot your username or password?</a>
What that's done when grunt locales are built is create this file under app/js/locales/de_DE/i18n.json
{
"Forgot your username or password?": "Forgot your username or password?"
}
Which I don't have to tell you is not translated. So will I need to go through and translate this for every language or am I missing something?

Yes, grunt-locales is a tool used for extracting the necessary information from your templates and js files to build the above json objects for all locales that the developer specifies. You will need a translator to go through and translate the strings within the json objects.
Once they have done so, you simply re-build the i18n.json files to create i18n.js files using grunt locales:build. The i18n.js files are used by the localize directive service and filters.
Very late answer, but if you are still interested I hope this helps.

Related

How to include a utility lib in an AngularJS app using Browserify?

I have a large AngularJS/Express app where I'd like to begin sharing code between client and server, mainly small utility libraries, e.g:
// Name: utilities.js
module.exports.testUtilities = function () {
console.log('testUtilities: Hello world!');
};
I'm now trying to set up Browserify using grunt-browserify:
// Name: Gruntfile.js
browserify: {
client: {
src: ['crossplatform/**/*.js'],
dest: 'app/scripts/crossplatformBrowserify.js'
}
},
I successfully build a crossplatformBundle.js which I include in my index.html.
But I fail at accessing my Browserified code from the AngularJS client:
// Name: MyAngularController.js
var utilities = require('./utilities');
utilities.testUtilities();
Error message: require is undefined.
I see many Browserify questions where the answer is to bundle up ALL the client-side scripts, but I'd rather avoid that if I can, since I want separate JS files in development mode.
Thankful for any tips I can get!
The solution was to define a “standalone” bundle for Browserify:
browserify: {
client: {
src: ['crossplatform/**/*.js'],
dest: 'app/scripts/crossplatform.js',
options: {
browserifyOptions: {
standalone: 'crossplatform'
},
}
}
},
...which allows me to call the method with window.crossplatform.testUtilities() in the browser.
Update: see this thread for more examples of how to bundle multiple libraries/modules.

How angular-translate-loader for webpack works?

I'm trying to integrate the webpack loader: angular-translate-loader to my project.
The documentation lacks a full example and I can't figure out how to make everything works together.
What I want:
Have a "languages" folder at the same level of my root component that will contain the locales for other languages like:
locale-fr.json
locale-sp.json
What I tried:
I added this in my webpack.config.js (as per documentation)
module.exports = {
module: {
preLoaders: [{
test: /\.json$/,
loader: 'json'
}],
loaders: [{
test: /\.json$/,
loader: 'angular-translate?module=translations'
}]
},
angularTranslate: {
namespaces: ['app'],
sep: '.',
defaultLocale: 'en'
}
};
And in the root component of my application I got this:
$translateProvider.translations('en', {
TITLE: "Translation is working",
ANOTHER_TEXT: "But is it really working"
})
.translations('fr', localFr)
.registerAvailableLanguageKeys(['en', 'cn', 'fr', 'sp'], {
'gb': 'en',
'es': 'sp'
})
.preferredLanguage('en')
//See http://angular-translate.github.io/docs/#/guide/19_security for more details about Sanitize
.useSanitizeValueStrategy('escape')
//Remember the choice of Language in the local storage
.useLocalStorage();
The default language obviously works (en) but not the others.
I'm missing something but I can't figure out why.
Does someone know of a sample project using angular-translate-loader and webpack ?
I was stuck on the same thing the whole day, but after a lot of trial and error I've finally found a working solution. I have a similiar set-up as you: I have a folder assets/languages at the root of my project, containing languates in JSON files with the format locale-nl.json.
What worked for me was to import angular-translate directly (together with some extra dependencies) instead of using angular-translate-loader:
npm install --save angular-translate angular-sanitize angular-cookies
I then added this to my app.module.js file (which is what I use instead of index.js):
// No "real" module support yet for angular-translate, wo we have to load these manually.
// Reference: https://github.com/angular-translate/angular-translate/issues/1517
import "angular-sanitize";
import "angular-cookies";
import "angular-translate";
import "angular-translate/dist/angular-translate-loader-static-files/angular-translate-loader-static-files.js";
import "angular-translate/dist/angular-translate-storage-cookie/angular-translate-storage-cookie.js";
Then, I define my module and configure the $translate service as follows:
angular.module(MODULE_NAME, [ "pascalprecht.translate", "ngSanitize", "ngCookies" ])
.config(['$translateProvider', function($translateProvider) {
$translateProvider
.useStaticFilesLoader({
prefix: "../assets/languages/locale-",
suffix: ".json"
})
.preferredLanguage('en')
.useCookieStorage()
.useSanitizeValueStrategy('sanitize');
}])
My translation files, e.g. locale-nl.json all contain a single object in this format:
{
"PASSWORD": "Wachtwoord",
"FORGOTPASSWORD": "Wachtwoord vergeten",
"SETTINGS": "Instellingen",
"LOGOUT": "Uitloggen",
"LASTNAME": "Achternaam",
"FIRSTNAME": "Voornaam",
"BIRTHYEAR": "Geboortejaar"
}
Finally, in my HTML code, I call the translations through the $translate directive:
<span translate="SETTINGS">Settings</span>
I don't have time now to create a sample project, but since there were no responses to your question yet I wanted to at least let you what worked for me. I'll see if I have the time to create a sample project this weekend.

Compile all angular templates to one js file

I am trying to compile all angulara templates into a single js file.
Something like what ember does with ember-cli.
So I successfully managed to minify and concat all the javascript files.
I have just 2 files now vendor.js and application.js and whole lot of template files which I want to cram into templates.js.
How do I go about it? If some one could give step by step explanation, please. Any links would be appreciated too.
Surprisingly there is no information about this anywhere.
I am using mimosa as build tool, it seemed to me the easiest.
Here is my mimosa config:
exports.config = {
modules: [
"copy",
"stylus",
"minify-css",
"minify-js",
"combine",
"htmlclean",
"html-templates"
],
watch: {
sourceDir: "app",
compiledDir: "public",
javascriptDir: "js",
exclude: [/[/\\](\.|~)[^/\\]+$/]
},
vendor: {
javascripts: "vendor/js"
},
stylus: {
sourceMap: false
},
combine: {
folders: [
{
folder:"vendor/js",
output:"vendor.js",
order: [
"angular.js"
]
},
{
folder:"js",
output:"main.js",
order: [
"application/main.js"
]
}
]
},
htmlclean: {
extensions:["html"]
},
htmlTemplates: {
extensions: ["tpl"]
},
template: {
outputFileName: "templates"
}
}
It does generate templates.js file without any errors. But when I link it, angular spits a bunch of errors.
Once compiled, how do I actually call those templates from ng-include and from the route provider?
I assume that it is the same as I would call a script template using the id which in my case is derived from template original file name, right?
Maybe I am missing some important steps.
The build tool is not important here although desirable. If some one could show how to do it manually without a build tool I would figure out the rest.
Thanks.
I'm using Gulp as my build tool, and in that, there's a plugin gulp-angular-templatecache which pre-compiles and registers all templates for your module in the angular $templateCache - no changes are required to any of the calling code to use these. EDIT: The Angular documentation for $templateCache explains how the templateCache works.
It might be worth reading through the documentation for gulp-angular-templatecache to see how that pre-populates the $templateCache to see if you can crib something that would work with your build process.
Here's my gulp task that does the job:
var templateCache = require('gulp-angular-templatecache');
gulp.task('buildjstemplates', function () {
return gulp.src(['public/javascripts/app/**/*.html'])
.pipe(templateCache({module: 'app'}))
.pipe(gulp.dest('public/javascripts/app/'));
});

how to activate debugInfoEnabled only for Unit tests?

In my angularjs 1.3 app, i disabled debug info to increase performance :
$compileProvider.debugInfoEnabled(false);
But when i launch my Jasmine tests with Karma, i got error with isolateScope :
var isoScope = element.isolateScope();
I know that it is completely normal,
but i'm looking for a way to reactivate the debug just for testing.
Can i do it programmatically ?
Can i define that in the karma-unit.conf.js ?
My approach to this was to create a set of config files, the load specific files via grunt or gulp, depending on the task or environment variables.
example config:
// configFileLocal.js
angular.module('myapp.config')
.constant('apiUrl', 'https://myapi.com/api')
.constant('debugInfoState', true);
an excerpt from Gruntfile:
copy: {
test: {
src: (function () {
var filename;
if (process.env.REMOTE_TESTS) {
filename = './config-files/configFileTestsRemote.js';
} else {
filename = './config-files/configFileTestsLocal.js';
}
return filename;
})(),
dest: '<%= yeoman.app %>/scripts/root/config.js',
},
dev: {
src: './config-files/configFileLocal.js',
dest: '<%= yeoman.app %>/scripts/root/config.js',
},
...
then of course you need to load it in your app like this:
angular.module('myapp')
.config(function ($compileProvider, debugInfoState) {
$compileProvider.debugInfoEnabled(debugInfoState);
});
so /app/scripts/root/config.js is overwritten every time.
in index.html, the only file that is loaded is /app/scripts/root/config.js
this task should be run before any concatenation tasks.
Answer from wiherek is good but it isn't necessary to use your grun/gulp to manage this. Just transform snippet from Angular documentation to something like this
beforeEach(function() {
module('myApp', function (_$compileProvider_) {
_$compileProvider_.debugInfoEnabled(true);
});
});
Here's how I do it:
$compileProvider.debugInfoEnabled(!!window.__karma__);
To debug an application after disabling debugInfo, you should open your console and run this code directly from your console:
angular.reloadWithDebugInfo();
This will reload your page with all debugging info.

Backbone.js and Handlebars - Using grunt-contrib-handlebars

I'm just wondering if anyone has had experience using this plugin in a backbone project.
Instead of having all my script template tags in a single index file, I wanted to house my templates in the same directory as my views that required them.
So I was hoping i could use the node option to require the local template and render to it and then append to an #id on my index file (which I'll sort out laster).
So basically I have my handlebars template (template.hbs) and its compiled js (template.js) alongside my backbone view, index.coffee.
public
|_ coffee
|_views
|_card
|_list
index.coffee
template.hbs
template.js
Just as a reference, my grunt file looks like this:
handlebars: {
compile: {
options: {
namespace: 'MyApp.Templates',
node: true
},
files: {
"public/coffee/views/card/list/template.js": "public/coffee/views/card/list/template.hbs"
}
}
},
In my backbone view (index.coffee) I was hoping to require the handlebars template like so:
class CardList extends Backbone.View
template: require('./template')
…
do some other shiz
…
render: =>
template = Handlebars.compile($(this.template).html())
html = template
model: this.model
$(this.el).html(html)
Rendering this is spitting out this error in the inspector:
Uncaught [object Object]
> template = handlebars.compile($(this.template).html());
I obviously dont know what I'm doing, so I'm hoping someone could shed some light on how I can use this plugin properly.
I'm using grunt-contrib-handlebars v0.3.5
Any help is appreciated.
Thanks
You might be able to achieve that by building the files object dynamically.
Maybe something like this, although I'm not sure if cwd supports globbing patterns. I'm also not sure if dest is relative to cwd. If this is not the case, this will not work, but it's worth a shot.
handlebars: {
dist: {
options: {
namespace: 'MyApp.Templates',
node: true
},
// Glob for a directory of files, builds the files object, then map each
// one to a new destination file.
expand: true,
cwd: './public/coffee/views/*',
src: '**/*.hbs',
dest: './',
ext: '.js'
}
},
Look inside your template.js file that you're including. grunt-comtrib-handlbars should have precompiled it into a Javascript function for you, so there's no need to call Handlebars.compile anymore. You could just remove that template = Handlebars.compile line.

Resources