├── test
├── fixtures
│ ├── data
│ │ ├── i18n.json
│ │ ├── license.json
│ │ ├── i18n
│ │ │ ├── en.json
│ │ │ ├── fr.json
│ │ │ └── es.json
│ │ └── i18n-alt.json
│ └── templates
│ │ ├── layouts
│ │ ├── alt.hbs
│ │ └── default.hbs
│ │ ├── without-plugin
│ │ └── index.hbs
│ │ ├── index.hbs
│ │ └── with-plugin
│ │ └── index.hbs
├── actual
│ ├── without-plugin
│ │ ├── en.html
│ │ ├── es.html
│ │ ├── fr.html
│ │ └── index.html
│ ├── with-permalinks
│ │ ├── en
│ │ │ └── index.html
│ │ ├── fr
│ │ │ └── index.html
│ │ └── es
│ │ │ └── index.html
│ ├── with-list-of-languages
│ │ ├── index-en.html
│ │ ├── index-fr.html
│ │ └── index-es.html
│ └── with-plugin
│ │ ├── index-en.html
│ │ ├── index-fr.html
│ │ └── index-es.html
└── main-test.js
├── .travis.yml
├── .gitignore
├── .gitattributes
├── .editorconfig
├── .verb.md
├── index.js
├── lib
└── i18n.js
├── package.json
├── Gruntfile.js
└── README.md
/test/fixtures/data/i18n.json:
--------------------------------------------------------------------------------
1 | {
2 | "languages": [
3 | "en",
4 | "es",
5 | "fr"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | before_script:
5 | - npm install -g grunt-cli
6 |
--------------------------------------------------------------------------------
/test/fixtures/data/license.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "MIT",
3 | "copyright": "Copyright (c) 2014 Assemble, contributors. Released under the MIT license"
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 | node_modules
3 | *.sublime-*
4 | *.swp
5 |
6 | # Ignore the staging dir for docs
7 |
8 | tmp
9 | docs
10 | vendor
11 | TODO.md
12 | *.rar
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Enforce Unix newlines
2 | * text eol=lf
3 |
4 | # binaries
5 | *.ai binary
6 | *.psd binary
7 | *.jpg binary
8 | *.gif binary
9 | *.png binary
10 | *.jpeg binary
--------------------------------------------------------------------------------
/test/fixtures/templates/layouts/alt.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{i18n "title"}}
5 |
6 |
7 | {{> body }}
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/data/i18n/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "lang": "en",
3 | "title": "i18n - English",
4 | "description": "This example demonstrates the creation of multiple pages based on one template and many i18n files"
5 | }
--------------------------------------------------------------------------------
/test/fixtures/data/i18n/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "lang": "fr",
3 | "title": "i18n - Français",
4 | "description": "Cet exemple démontre la création de multiple page basée sur un modèle et plusieurs fichiers i18n."
5 | }
--------------------------------------------------------------------------------
/test/fixtures/data/i18n/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "lang": "es",
3 | "title": "i18n - Español",
4 | "description": "Este ejemplo muestra la creación de una página múltiple basada en el número de modelo y los archivos i18n."
5 | }
--------------------------------------------------------------------------------
/test/fixtures/templates/layouts/default.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{i18n "title"}}
6 |
7 |
8 | {{> body }}
9 |
10 |
--------------------------------------------------------------------------------
/test/actual/without-plugin/en.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 | Is english your language of choice?
9 |
10 |
--------------------------------------------------------------------------------
/test/actual/without-plugin/es.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 | ¿Es español el idioma de su elección?
9 |
10 |
--------------------------------------------------------------------------------
/test/actual/without-plugin/fr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 | Est-français la langue de votre choix?
9 |
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [test/fixtures/*]
16 | insert_final_newline = false
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/test/fixtures/templates/without-plugin/index.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | lang: <%= language %>
3 | copyright: Copyright (c) 2014 Assemble, contributors. Released under the MIT license
4 | footnote: My language is set to <%= language %>
5 | ---
6 | {{i18n "title"}}
7 | {{i18n "description"}}
8 |
9 | {{ footnote }}
10 | {{ copyright }}
11 |
12 |
--------------------------------------------------------------------------------
/test/fixtures/templates/index.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | lang: <%= language %>
3 | copyright: Copyright (c) 2014 Assemble, contributors. Released under the MIT license
4 | footnote: My language is set to <%= language %>
5 | ---
6 | {{i18n "title"}}
7 | {{i18n "description"}}
8 |
9 | {{ footnote }}
10 | {{ copyright }}
11 | {{ footnote }}
12 |
13 |
--------------------------------------------------------------------------------
/.verb.md:
--------------------------------------------------------------------------------
1 | # {%= name %} {%= badge("fury") %} {%= badge("travis") %}
2 |
3 | > {%= description %}
4 |
5 | {%= include("install", {save: '--save'}) %}
6 |
7 | ## Other grunt-assemble plugins
8 | {%= related(verb.related.list, {remove: name}) %}
9 |
10 | ## Contributing
11 | {%= include("contributing") %}
12 |
13 | ## Author
14 | {%= include("author") %}
15 |
16 | ## License
17 | {%= copyright() %}
18 | {%= license() %}
19 |
20 | ***
21 |
22 | {%= include("footer") %}
23 |
--------------------------------------------------------------------------------
/test/actual/without-plugin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 |
9 | i18n - Français
10 | Cet exemple démontre la création de multiple page basée sur un modèle et plusieurs fichiers i18n.
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/test/actual/with-permalinks/en/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - English
6 |
7 |
8 |
9 | i18n - English
10 | This example demonstrates the creation of multiple pages based on one template and many i18n files
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/actual/with-permalinks/fr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 |
9 | i18n - Français
10 | Cet exemple démontre la création de multiple page basée sur un modèle et plusieurs fichiers i18n.
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/actual/with-list-of-languages/index-en.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - English
6 |
7 |
8 |
9 | i18n - English
10 | This example demonstrates the creation of multiple pages based on one template and many i18n files
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/actual/with-list-of-languages/index-fr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 |
9 | i18n - Français
10 | Cet exemple démontre la création de multiple page basée sur un modèle et plusieurs fichiers i18n.
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/actual/with-permalinks/es/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Español
6 |
7 |
8 |
9 | i18n - Español
10 | Este ejemplo muestra la creación de una página múltiple basada en el número de modelo y los archivos i18n.
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/actual/with-list-of-languages/index-es.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Español
6 |
7 |
8 |
9 | i18n - Español
10 | Este ejemplo muestra la creación de una página múltiple basada en el número de modelo y los archivos i18n.
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/fixtures/templates/with-plugin/index.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | lang: <%= language %>
3 | copyright: <%= license.copyright %>
4 | footnote: My language is set to <%= language %>
5 | lodash: <%= i18n[language].title %>
6 | ---
7 | {{i18n "title"}}
8 | {{i18n "description"}}
9 | {{lodash}}
10 |
11 | {{ footnote }}
12 | {{ copyright }}
13 | {{ footnote }}
14 | Available languages:
15 |
16 | {{#each i18n.languages}}
17 | {{this}}
18 | {{/each}}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test/fixtures/data/i18n-alt.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "alt.hbs",
3 | "languages": [
4 | {
5 | "filename": "en",
6 | "data": "<%= _.expand('./data/i18n/en.json') %>",
7 | "content": "Is english your language of choice?"
8 | },
9 | {
10 | "filename": "es",
11 | "data": "<%= _.expand('./data/i18n/es.json') %>",
12 | "content": "¿Es español el idioma de su elección?"
13 | },
14 | {
15 | "filename": "fr",
16 | "data": "<%= _.expand('./data/i18n/fr.json') %>",
17 | "content": "Est-français la langue de votre choix?"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/test/actual/with-plugin/index-en.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - English
6 |
7 |
8 |
9 | i18n - English
10 | This example demonstrates the creation of multiple pages based on one template and many i18n files
11 | i18n - English
12 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/test/actual/with-plugin/index-fr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Français
6 |
7 |
8 |
9 | i18n - Français
10 | Cet exemple démontre la création de multiple page basée sur un modèle et plusieurs fichiers i18n.
11 | i18n - Français
12 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/test/actual/with-plugin/index-es.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | i18n - Español
6 |
7 |
8 |
9 | i18n - Español
10 | Este ejemplo muestra la creación de una página múltiple basada en el número de modelo y los archivos i18n.
11 | i18n - Español
12 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * grunt-assemble-i18n
3 | *
4 | * Copyright (c) 2014-2015, Jon Schlinkert.
5 | * Licensed under the MIT License.
6 | */
7 |
8 | var _ = require('lodash');
9 | var i18n = require('./lib/i18n');
10 | var helper = require('handlebars-helper-i18n');
11 |
12 | var options = {
13 | stage: 'assemble:post:data'
14 | };
15 |
16 | /**
17 | * postprocess
18 | * @param {Object} params
19 | * @param {Function} callback
20 | */
21 | module.exports = function (params, callback) {
22 | 'use strict';
23 |
24 | var grunt = params.grunt;
25 |
26 | grunt.verbose.subhead('Running:'.bold, '"assemble-contrib-i18n"');
27 | grunt.verbose.writeln('Stage: '.bold, '"' + params.stage + '"\n');
28 |
29 | grunt.verbose.writeln('Loading the i18n helper');
30 | params.assemble.engine.registerFunctions(helper.i18n);
31 |
32 | var opts = params.assemble.options.i18n;
33 | grunt.verbose.writeln('Options: '.bold, require('util').inspect(opts));
34 |
35 | if (opts) {
36 | var o = {};
37 | var data = params.assemble.options.data;
38 | var templates = opts.templates;
39 | var languages = opts.languages;
40 | var defaultLanguage = opts.defaultLanguage;
41 |
42 | if (opts.data) {
43 | o.data = opts.data;
44 | }
45 |
46 | if (templates) {
47 | o.templates = templates;
48 | }
49 |
50 | if (languages) {
51 | o.languages = languages;
52 | }
53 |
54 | if (defaultLanguage) {
55 | o.defaultLanguage = defaultLanguage;
56 | }
57 |
58 | var pages = i18n(data, o);
59 |
60 | grunt.verbose.writeln('Pages: '.bold, require('util').inspect(pages));
61 | params.assemble.options.pages = _.extend({}, (params.assemble.options.pages || {}), pages);
62 |
63 | }
64 |
65 | callback();
66 | };
67 |
68 | module.exports.options = options;
69 |
--------------------------------------------------------------------------------
/lib/i18n.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash');
2 | var path = require('path');
3 | var file = require('fs-utils');
4 | var matter = require('gray-matter');
5 |
6 | module.exports = function (data, options) {
7 | // Specify and exapnd the template(s) to use for each language
8 | var templates = file.expand(options.templates = options.templates || ['templates/*.hbs']);
9 |
10 | var pages = {};
11 |
12 | var languages = options.languages || [];
13 |
14 | var defaultLanguage = options.defaultLanguage || '';
15 |
16 | var process = function () {
17 | var i18n = [];
18 |
19 | //Adds the i18n context
20 | languages.forEach(function (language) {
21 | i18n[language] = _.extend({}, data[language]);
22 | });
23 |
24 | // Iterate over the languages
25 | languages.forEach(function (language) {
26 |
27 | templates.forEach(function (page) {
28 | var ext = path.extname(page);
29 | var pageObj = matter.read(page);
30 |
31 | i18n = _.extend({}, i18n, {languages: languages});
32 |
33 | var context = _.extend({}, data, {language: language, i18n: i18n}, pageObj.context);
34 | var filename = defaultLanguage !== language ? page.replace(ext, "-" + language + ext) : page;
35 |
36 | pages[filename] = {
37 | filename: filename,
38 | content: pageObj.content,
39 | data: context
40 | };
41 |
42 | });
43 | });
44 | };
45 |
46 | if (options.data) {
47 | var filepaths = file.expand(options.data);
48 |
49 | _.each(filepaths, function (filepath, index) {
50 |
51 | // Read in the data from each file
52 | var i18nData = file.readDataSync(filepath);
53 |
54 | if (i18nData.languages) {
55 | languages = _.union(languages, i18nData.languages || []);
56 | } else {
57 | var languageKey = path.basename(filepath, path.extname(filepath));
58 | data[languageKey] = i18nData;
59 | }
60 | });
61 | }
62 |
63 | process();
64 |
65 | return pages;
66 | };
67 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "grunt-assemble-i18n",
3 | "description": "Plugin for adding i18n support to Assemble projects.",
4 | "version": "0.1.1",
5 | "homepage": "https://github.com/assemble/grunt-assemble-i18n",
6 | "author": {
7 | "name": "Jon Schlinkert",
8 | "url": "https://github.com/assemble/grunt-assemble-i18n"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/assemble/grunt-assemble-i18n"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/assemble/grunt-assemble-i18n/issues"
16 | },
17 | "license": {
18 | "type": "MIT",
19 | "url": "https://github.com/assemble/assemble-contrib-permalinks/blob/master/LICENSE"
20 | },
21 | "files": [
22 | "index.js",
23 | "lib/"
24 | ],
25 | "main": "index.js",
26 | "scripts": {
27 | "test": "grunt test"
28 | },
29 | "dependencies": {
30 | "fs-utils": "~0.3.6",
31 | "gray-matter": "~0.2.8",
32 | "handlebars-helper-i18n": "^0.1.0",
33 | "lodash": "~2.4.1"
34 | },
35 | "devDependencies": {
36 | "grunt": "~0.4.2",
37 | "grunt-contrib-clean": "~0.5.0",
38 | "grunt-assemble": "~0.4.0",
39 | "grunt-assemble-permalinks": "~0.1.0",
40 | "handlebars": "~1.3.0",
41 | "grunt-mocha-test": "~0.10.0",
42 | "chai": "~1.9.1",
43 | "cheerio": "~0.13.1"
44 | },
45 | "keywords": [
46 | "assemble",
47 | "assemblecontribcollection",
48 | "assembleplugin",
49 | "i18n",
50 | "internationalize",
51 | "language",
52 | "local",
53 | "localize",
54 | "plugin"
55 | ],
56 | "verb": {
57 | "related": {
58 | "list": [
59 | "grunt-assemble",
60 | "grunt-assemble-anchors",
61 | "grunt-assemble-contextual",
62 | "grunt-assemble-decompress",
63 | "grunt-assemble-download",
64 | "grunt-assemble-i18n",
65 | "grunt-assemble-lunr",
66 | "grunt-assemble-navigation",
67 | "grunt-assemble-permalinks",
68 | "grunt-assemble-sitemap",
69 | "grunt-assemble-toc",
70 | "grunt-assemble-wordcount"
71 | ]
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 | var pages = require('./lib/i18n');
5 |
6 | var read = function(src) {
7 | return grunt.file.readJSON(src);
8 | };
9 |
10 | grunt.util._.mixin({
11 | read: read,
12 | expand: function(src) {
13 | return grunt.file.expand(src).map(read);
14 | }
15 | });
16 |
17 | // Project configuration.
18 | grunt.initConfig({
19 |
20 | i18n_alt: grunt.file.readJSON('test/fixtures/data/i18n-alt.json'),
21 |
22 | assemble: {
23 | options: {
24 | plugins: ['./index.js'],
25 | data: 'test/fixtures/data/**/*.json',
26 | flatten: true,
27 | partials: 'test/fixtures/templates/includes/*.hbs',
28 | layoutdir: 'test/fixtures/templates/layouts',
29 | layout: 'default.hbs'
30 | },
31 |
32 | "without-plugin": {
33 | options: {
34 | language: 'fr',
35 | pages: '<%= i18n_alt.languages %>'
36 | },
37 | files: {'test/actual/without-plugin/': ['test/fixtures/templates/without-plugin/*.hbs']},
38 | },
39 |
40 | "with-plugin": {
41 | options: {
42 | i18n: {
43 | data: ['test/fixtures/data/i18n.json', 'test/fixtures/data/i18n/*.json'],
44 | templates: ['test/fixtures/templates/with-plugin/*.hbs']
45 | }
46 | },
47 | dest: 'test/actual/with-plugin/',
48 | src: '!*.*'
49 | },
50 |
51 | "with-permalinks": {
52 | options: {
53 | plugins: ['index.js', 'grunt-assemble-permalinks'],
54 | i18n: {
55 | data: 'test/fixtures/data/i18n.json',
56 | templates: ['test/fixtures/templates/*.hbs']
57 | },
58 | permalinks: {
59 | structure: ':language/index.html'
60 | }
61 | },
62 | dest: 'test/actual/with-permalinks/',
63 | src: '!*.*'
64 | },
65 |
66 | "with-list-of-languages": {
67 | options: {
68 | i18n: {
69 | languages: ["en", "fr", "es"],
70 | templates: ['test/fixtures/templates/*.hbs']
71 | }
72 | },
73 | dest: 'test/actual/with-list-of-languages/',
74 | src: '!*.*'
75 | }
76 |
77 | },
78 |
79 | /**
80 | * Run mocha tests.
81 | */
82 | mochaTest: {
83 | tests: {
84 | options: {
85 | reporter: 'spec'
86 | },
87 | src: ['test/**/*-test.js']
88 | }
89 | },
90 |
91 | // Before creating new files, remove files from previous build.
92 | clean: ['test/actual/**/*.html']
93 |
94 | });
95 |
96 | // Load npm plugins to provide necessary tasks.
97 | grunt.loadNpmTasks('grunt-assemble');
98 | grunt.loadNpmTasks('grunt-contrib-clean');
99 | grunt.loadNpmTasks('grunt-mocha-test');
100 |
101 | grunt.registerTask('test', ['mochaTest']);
102 |
103 | // Default task to be run.
104 | grunt.registerTask('default', ['clean', 'assemble', 'test']);
105 | };
106 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # grunt-assemble-i18n [](http://badge.fury.io/js/grunt-assemble-i18n) [](https://travis-ci.org/assemble/grunt-assemble-i18n)
2 |
3 | > Plugin for adding i18n support to Assemble projects.
4 |
5 | ```sh
6 | $ npm i grunt-assemble-i18n --save
7 | ```
8 |
9 | ## Other grunt-assemble plugins
10 |
11 | * [grunt-assemble](https://www.npmjs.com/package/grunt-assemble): Static site generator for Grunt.js, Yeoman and Node.js. Used by Zurb Foundation, Zurb Ink, H5BP/Effeckt,… [more](https://www.npmjs.com/package/grunt-assemble) | [homepage](http://assemble.io)
12 | * [grunt-assemble-anchors](https://www.npmjs.com/package/grunt-assemble-anchors): Assemble plugin for creating anchor tags from headings in generated html using Cheerio.js. | [homepage](https://github.com/assemble/grunt-assemble-anchors)
13 | * [grunt-assemble-contextual](https://www.npmjs.com/package/grunt-assemble-contextual): Generates a JSON file with the context of each page. Basic plugin to help see… [more](https://www.npmjs.com/package/grunt-assemble-contextual) | [homepage](https://github.com/assemble/grunt-assemble-contextual)
14 | * [grunt-assemble-decompress](https://www.npmjs.com/package/grunt-assemble-decompress): Assemble plugin for extracting zip, tar and tar.gz archives. | [homepage](https://github.com/assemble/grunt-assemble-decompress)
15 | * [grunt-assemble-download](https://www.npmjs.com/package/grunt-assemble-download): Assemble plugin for downloading files from GitHub. | [homepage](https://github.com/assemble/grunt-assemble-download)
16 | * [grunt-assemble-lunr](https://www.npmjs.com/package/grunt-assemble-lunr): Assemble plugin for adding search capabilities to your static site, with lunr.js. | [homepage](http://assemble.io)
17 | * [grunt-assemble-navigation](https://www.npmjs.com/package/grunt-assemble-navigation): Assemble navigation plugin. Automatically generate Bootstrap-style, multi-level side nav. See the sidenav on assemble.io for… [more](https://www.npmjs.com/package/grunt-assemble-navigation) | [homepage](https://github.com/assemble/grunt-assemble-navigation)
18 | * [grunt-assemble-permalinks](https://www.npmjs.com/package/grunt-assemble-permalinks): Permalinks plugin for Assemble, the static site generator for Grunt.js, Yeoman and Node.js. This plugin… [more](https://www.npmjs.com/package/grunt-assemble-permalinks) | [homepage](https://github.com/assemble/grunt-assemble-permalinks)
19 | * [grunt-assemble-sitemap](https://www.npmjs.com/package/grunt-assemble-sitemap): Sitemap plugin for Assemble | [homepage](http://assemble.io/plugins)
20 | * [grunt-assemble-toc](https://www.npmjs.com/package/grunt-assemble-toc): Assemble middleware for adding a Table of Contents (TOC) to any HTML page. | [homepage](http://assemble.io)
21 | * [grunt-assemble-wordcount](https://www.npmjs.com/package/grunt-assemble-wordcount): Assemble plugin for displaying wordcount and average reading time to blog posts or pages. | [homepage](https://github.com/assemble/grunt-assemble-wordcount)
22 |
23 | ## Contributing
24 |
25 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/assemble/grunt-assemble-i18n/issues/new).
26 |
27 | ## Author
28 |
29 | **Jon Schlinkert**
30 |
31 | + [github/assemble](https://github.com/assemble)
32 | + [twitter/assemble](http://twitter.com/assemble)
33 |
34 | ## License
35 |
36 | Copyright © 2015 Jon Schlinkert
37 | Released under the MIT license.
38 |
39 | ***
40 |
41 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 25, 2015._
--------------------------------------------------------------------------------
/test/main-test.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * grunt-assemble-i18n
3 | *
4 | * Copyright (c) 2014-2015, Jon Schlinkert.
5 | * Licensed under the MIT License.
6 | */
7 |
8 | // Node.js
9 | var path = require('path');
10 |
11 | // node modules
12 | var expect = require('chai').expect;
13 | var cheerio = require('cheerio');
14 | var file = require('fs-utils');
15 |
16 | /**
17 | * Initilize an object of {filename: true}
18 | * pairs used for expect later
19 | *
20 | * @param {[Array]} files - List of base files
21 | * @return {[Object]} - Object of {filename: true}
22 | */
23 | var initFileList = function (files) {
24 | var list = {};
25 | files.forEach(function (f) {
26 | list[f.filename] = true;
27 | });
28 | return list;
29 | };
30 |
31 | /**
32 | * Validate that each file in the list exists.
33 | *
34 | * @param {[Object]} files - List of base files
35 | * @param {[String]} base - Base path to look for filenames
36 | * @return {[Object]} - Object of {filename: (true|false)}
37 | */
38 | var validateFileListExists = function (files, base) {
39 | var list = {};
40 | files.forEach(function (f) {
41 | list[f.filename] = file.exists(base, f.filename);
42 | });
43 | return list;
44 | };
45 |
46 | var validateLanguageAttribute = function (files, base) {
47 | for (var i = 0; i < files.length; i++) {
48 | var f = files[i];
49 | var filepath = path.join(base, f.filename);
50 | var contents = file.readFileSync(filepath);
51 | var $ = cheerio.load(contents);
52 | var actual = $('html[lang="' + f.language + '"]');
53 | expect(actual.length).to.eql(1);
54 | };
55 | };
56 |
57 | var validateLodashYFMContent = function (files, base) {
58 | for (var i = 0; i < files.length; i++) {
59 | var f = files[i];
60 | var filepath = path.join(base, f.filename);
61 | var contents = file.readFileSync(filepath);
62 | var $ = cheerio.load(contents);
63 | var actual = $('#lodash-parsed');
64 | var expected = $('title');
65 | expect(actual.text()).to.eql(expected.text());
66 | };
67 | };
68 |
69 | // tests
70 | describe('assemble-contrib-i18n', function() {
71 |
72 | describe('when no plugin is used', function() {
73 |
74 | // this metadata shows there are some issues
75 | // with the regular data or front-matter
76 | // when adding pages through the pages collection
77 | // on assemble options
78 | var metadata = [
79 | { filename: 'en.html', language: 'fr' },
80 | { filename: 'es.html', language: 'fr' },
81 | { filename: 'fr.html', language: 'fr' },
82 | { filename: 'index.html', language: 'fr' }
83 | ];
84 |
85 | it('it should create four files', function() {
86 | var expected = initFileList(metadata);
87 | var actual = validateFileListExists(metadata, 'test/actual/without-plugin');
88 | expect(actual).to.eql(expected);
89 | });
90 |
91 | it('it should contain a language attribute on the html tag', function() {
92 | validateLanguageAttribute(metadata, 'test/actual/without-plugin');
93 | });
94 |
95 | });
96 |
97 | describe('when i18n plugin is used', function() {
98 |
99 | var metadata = [
100 | { filename: 'index-en.html', language: 'en' },
101 | { filename: 'index-es.html', language: 'es' },
102 | { filename: 'index-fr.html', language: 'fr' }
103 | ];
104 |
105 | it('it should create three index-{lang}.html files', function() {
106 | var expected = initFileList(metadata);
107 | var actual = validateFileListExists(metadata, 'test/actual/with-plugin');
108 | expect(actual).to.eql(expected);
109 | });
110 |
111 | it('it should contain a language attribute on the html tag', function () {
112 | validateLanguageAttribute(metadata, 'test/actual/with-plugin');
113 | });
114 |
115 | it('with data it should contain language-specific lodash parsed string', function() {
116 | validateLodashYFMContent(metadata, 'test/actual/with-plugin');
117 | });
118 |
119 | });
120 |
121 | describe('when i18n and permalinks plugins are used', function() {
122 |
123 | var metadata = [
124 | { filename: 'en/index.html', language: 'en' },
125 | { filename: 'es/index.html', language: 'es' },
126 | { filename: 'fr/index.html', language: 'fr' }
127 | ];
128 |
129 | it('it should create three {lang}/index.html files', function() {
130 | var expected = initFileList(metadata);
131 | var actual = validateFileListExists(metadata, 'test/actual/with-permalinks');
132 | expect(actual).to.eql(expected);
133 | });
134 |
135 | it('it should contain a language attribute on the html tag', function () {
136 | validateLanguageAttribute(metadata, 'test/actual/with-permalinks');
137 | });
138 |
139 | });
140 |
141 | describe('when i18n plugin is used with a list of languages', function() {
142 |
143 | var metadata = [
144 | { filename: 'index-en.html', language: 'en' },
145 | { filename: 'index-es.html', language: 'es' },
146 | { filename: 'index-fr.html', language: 'fr' }
147 | ];
148 |
149 | it('it should create three index-{lang}.html files', function() {
150 | var expected = initFileList(metadata);
151 | var actual = validateFileListExists(metadata, 'test/actual/with-plugin');
152 | expect(actual).to.eql(expected);
153 | });
154 |
155 | it('it should contain a language attibute on the html tag', function () {
156 | validateLanguageAttribute(metadata, 'test/actual/with-plugin');
157 | });
158 |
159 | });
160 | });
161 |
--------------------------------------------------------------------------------