Skip to content

Commit

Permalink
imported code
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaracco committed Feb 22, 2017
1 parent a87f4e1 commit 8eb0431
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
]
}
}
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,63 @@
# rails-translations-webpack-plugin

Shares Rails i18n translations with your javascripts without duplicating contents

## Usage

- Install it `npm install rails-translations-webpack-plugin --save-dev`
- Require it in your `webpack.config.js`:
```js
const RailsTranslationsPlugin = require("rails-translations-webpack-plugin");
```
- Add it to your plugins block. See below for options documentation:
```js
plugins: [
new RailsTranslationsPlugin({
localesPath: path.resolve(__dirname, "../rails-app/config/locales"),
root : "src"
})
]
```
- Now you can require the translations from your code. E.g.
```js
// somewhere inside your javascripts
const translations = require("translations.json");
console.log(`English translation for hello.world key: ${translations["en"]["hello.world"]}`)
```

## Options

The followings are the available options you can set for RailsTranslationsPlugin:

- `localesPath`: Path where to look for yml files. __Default: current dir__
- `pattern`: Pattern used to find yml files. __Default: `**/*.yml`__
- `name`: Name of the generated json file. __Default: translations__
- `root`: Root path of your javascripts. __Default: current dir__

So let's say you have the following file structure:

- config/
- locales/
- en.yml
- it.yml
- client/
- app/
- index.js
- webpack.config.js

Your webpack entry point is probably `app/index.js`. This can be the configuration for RailsTranslationsPlugin:

```js
{
root: path.resolve(__dirname, "app"),
localesPath: path.resolve(__dirname, "../config/locales"),
name: "my_translations"
pattern: "*.yml"
}
```

Your `client/app/index.js` will then be able to require the translations with:

```js
const translations = require("my_translations.json")
```
53 changes: 53 additions & 0 deletions lib/RailsTranslationsLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use strict";

const _ = require("lodash");
const glob = require("glob");
const path = require("path");
const fs = require("fs");
const yaml = require("yaml-js");

class RailsTranslationsLoader {
constructor(localesPath, pattern) {
this.localesPath = localesPath || '';
this.pattern = pattern || "**/*.yml";
}

loadTranslations() {
let content = {};
_.forEach(this.listLocaleFiles(), (file) => {
let translations = this.loadTranslationsFromFile(file);
_.forEach(translations, (pairs, locale) => {
if (!content[locale]) { content[locale] = {}; }
_.assign(content[locale], pairs);
});
});
return content;
}

listLocaleFiles() {
return glob.sync(this.pattern, { cwd: this.localesPath });
}

loadTranslationsFromFile(file) {
let content = yaml.load(fs.readFileSync(path.join(this.localesPath, file)));
_.forEach(content, (data, locale) => {
content[locale] = RailsTranslationsLoader.flattenRailsTranslations(data);
});
return content;
}

static flattenRailsTranslations(data, prefix = null) {
let result = [];
_.forEach(data, (value, key) => {
let prefixKey = prefix ? `${prefix}.${key}` : key;
if (_.isPlainObject(value)) {
_.assign(result, RailsTranslationsLoader.flattenRailsTranslations(value, prefixKey));
} else {
result[prefixKey] = value;
}
});
return result;
}
}

module.exports = RailsTranslationsLoader;
17 changes: 17 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";

const path = require("path");
const VirtualModulePlugin = require("virtual-module-webpack-plugin");
const RailsTranslationsLoader = require("./RailsTranslationsLoader.js");

class RailsTranslationsPlugin extends VirtualModulePlugin {
constructor(options = {}) {
let loader = new RailsTranslationsLoader(options.localesPath, options.pattern);
super({
moduleName: path.join(options.root || '', `${options.name || "translations"}.json`),
contents : JSON.stringify(loader.loadTranslations())
});
}
}

module.exports = RailsTranslationsPlugin;
38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "rails-translations-webpack-plugin",
"version": "1.0.0",
"author": "Nicola Racco",
"description": "Shares Rails i18n translations with your javascripts without duplicating contents",
"engines": {
"node": ">= 4.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mikamai/rails-translations-webpack-plugin.git"
},
"keywords": [
"webpack",
"plugin",
"rails",
"i18n"
],
"bugs": {
"url": "https://github.com/mikamai/rails-translations-webpack-plugin/issues"
},
"homepage": "https://github.com/mikamai/rails-translations-webpack-plugin#readme",
"license": "MIT",
"scripts": {
"lint": "eslint . ./lib/",
"test": "mocha test --recursive",
"watch-test": "mocha test --recursive --watch"
},
"main": "lib/index.js",
"devDependencies": {
"chai": "^3.5.0",
"glob": "^7.1.1",
"lodash": "^4.17.4",
"mocha": "^3.2.0",
"virtual-module-webpack-plugin": "^0.1.3",
"yaml-js": "^0.1.4"
}
}
2 changes: 2 additions & 0 deletions test/fixtures/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
en:
hello: 'world'
2 changes: 2 additions & 0 deletions test/fixtures/en/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
en:
good: morning
4 changes: 4 additions & 0 deletions test/fixtures/it/it.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
it:
prova: prova
en:
whata: shouldn't be here
62 changes: 62 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use strict";

const chai = require("chai");
const expect = chai.expect;
const RailsTranslationsPlugin = require("./../lib/index.js");
const path = require("path");
const fixturesPath = path.resolve(__dirname, "./fixtures");

describe("RailsTranslationsPlugin", function() {

it("is an instance of VirtualModulePlugin", () => {
const VirtualModulePlugin = require("virtual-module-webpack-plugin");
expect(Object.getPrototypeOf(RailsTranslationsPlugin)).to
.equal(VirtualModulePlugin);
});

it("by default builds a module in ./translations.json", () => {
let plugin = new RailsTranslationsPlugin();
expect(plugin.options.moduleName).to.equal("translations.json");
});

it("can generate a json file in any desired position", () => {
let plugin = new RailsTranslationsPlugin({ root: "app", name: "foo" });
expect(plugin.options.moduleName).to.equal("app/foo.json");
});

it("stores file content as a string", () => {
let plugin = new RailsTranslationsPlugin({ localesPath: fixturesPath });
expect(plugin.options.contents).to.be.a("string");
expect(plugin.options.contents.length).to.be.above(0);
});

it("stores a JSON in the file", () => {
let plugin = new RailsTranslationsPlugin({ localesPath: fixturesPath });
expect(JSON.parse(plugin.options.contents)).to.be.a("object");
});

it("stores all translations grouped by locale code", () => {
let plugin = new RailsTranslationsPlugin({ localesPath: fixturesPath });
let json = JSON.parse(plugin.options.contents);
expect(Object.keys(json)).to.have.members(["en", "it"]);
});

it("stores all values found for a certain locale", () => {
let plugin = new RailsTranslationsPlugin({ localesPath: fixturesPath });
let json = JSON.parse(plugin.options.contents);
expect(json.en).to.eql({
good : "morning",
hello: "world",
whata: "shouldn't be here"
});
});

it("allows to change the yml pattern", () => {
let plugin = new RailsTranslationsPlugin({
localesPath: fixturesPath,
pattern : "*.yml"
});
let json = JSON.parse(plugin.options.contents);
expect(json.en).to.eql({ hello: "world" });
});
});

0 comments on commit 8eb0431

Please sign in to comment.