Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create multiple pages with different languages from one template?

I want to generate multiple pages which will have content on different languages from one common template. How can I do it with webpack?

I tried to use different webpack plugins like webpack-static-i18n-html, i18n-webpack-plugin but nothing works for me. The best thing I found is a webpack-static-i18n-html, but it has bad support and this plugin can't watch changes in JSON files with translated text. Below is what I have for now.

This is my code from webpack.common.js.

const Path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const StaticI18nHtmlPlugin = require("webpack-static-i18n-html");
//...

module.exports = {
    //...
    plugins: [
        //...
        new StaticI18nHtmlPlugin({
            locale: 'en',
            locales: ['en', 'ua', 'ru'],
            baseDir: Path.posix.join(__dirname, ".."),
            outputDir: 'src/localized-pages',
            outputDefault: '__lng__/__file__',
            localesPath: 'src/locales',
            files: 'src/templates/index.html'
        }),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: Path.resolve(__dirname, '../src/templates/index.html')
        }),
        new HtmlWebpackPlugin({
            filename: 'ua/index.html',
            template: Path.resolve(__dirname, '../src/localized-pages/ua/src/templates/index.html')
        }),
        new HtmlWebpackPlugin({
            filename: 'ru/index.html',
            template: Path.resolve(__dirname, '../src/localized-pages/ru/src/templates/index.html')
        }),
        //...
    ],
    //...
};

I also have webpack.dev.js and webpack.prod.js which I merge with webpack.common.js via webpack-merge plugin. As you can see, after generating pages, I have to use HtmlWebpackPlugin to serve them. It's awkward to use.

locales folder:

locales
|-en.json
|-ua.json
|-ru.json

en.json file:

{
    "key": {
        "innerKey" : "value"
    }
}

Then plugin generates from:

<p data-t>key.innerKay</p>

this

<p>value</p>

But as I said, If I change en.json nothing will regenerate. I will not use this way to generate multiple pages for different languages.

So, I would like to generate several pages from one template. Is there any way to do this with webpack?

like image 872
Taras Avatar asked Jul 21 '19 15:07

Taras


1 Answers

I was working on a multi language admin dashboard with Webpack and was wondering how could I tackle this problem until I found a way to make everything automatic with a multiple language web template.

First of all, webpack-static-i18n-html isn't a good solution because most of its packages are deprecated. But actually the mentioned package is based on a good npm package called node-static-i18n. So, the first thing you need to do is installing this npm package using this command

npm install -g static-i18n

Next, you need to make your translation file as *.json files and in json format and put them in a folder which I named "locales" and I put it in my "src" folder of my project. I need two languages for my website. One of them is English and another is Farsi or Persian. Therefore I made two file namely fa.json and en.json. So, I have folder and file structure like the picture below:

My file and folder structure in my Webpack project

  • This is part of my en.json file as an example:

{

"menu": {
    "items": {
      "dashboard": "Dashboard",
      "posts": "Posts",
      "media": "Media"
    },
    "sub": {
      "items": {
        "all-posts": "All Posts",
        "add-new-post": "Add New",
        "categories": "Categories"
      }
    }
  }

}

  • This is part of my fa.json file as an example:

{

"menu": {
    "items": {
      "dashboard": "پیشخوان",
      "posts": "نوشته ها",
      "media": "رسانه"
    },
    "sub": {
      "items": {
        "all-posts": "نوشته ها",
        "add-new-post": "افزودن نوشته",
        "categories": "دسته ها"
      }
    }
  }

}

and you can use them in your html tags like this:

<span class="className" data-t>menu.items.dashboard</span>

Please notice that for using translation you should use the attribute data-t in your tags like span then you can use key and values saved in your related json file to use translations between your tags. for more information about data-t and its usage please go to the plugin's Github page that I mentioned it earlier in this text on the plugin name.

Next, you should write needed command in the script section of your package.json file to run node-static-i18n to translate your template based on your html template file and save them in i18n folder in root of your project as below:

"scripts": {

"i18n": "static-i18n -l en -i fa -i en  src --localesPath src/locales/",

}

in the above command:

-l: The default locale.

-i: the list of locales to be generated.

--localesPath: The directory of the translations, where each file should be named LOCALE_NAME.json

Now if you run npm run i18n this command should make a folder in root path of your project called i18n containing html files in two languages in this case. it will be like the picture below:

i18n folder and translated html files in it

Next you should config your Html Webpack Plugin in your Webpack config file to show these pages in your browser like this:

    plugins: [
.
.
.
new HtmlWebpackPlugin({
  //inject: false,
  chunks: ['main'],
  template: 'i18n/index.html',
  filename: 'index.html'
}),
new HtmlWebpackPlugin({
  //inject: false,
  chunks: ['main-rtl'],
  template: 'i18n/fa/index.html',
  filename: 'fa/index.html'
})

]

because you need to see changes on your browser automatically you need another package called npm-watch to install through this command:

npm install -D npm-watch

Then, you should change script section of your package.json like this:

"scripts": {
    "i18n-watch": "watch 'npm run i18n' src",
    "i18n": "static-i18n -l en -i fa -i en  src --localesPath src/locales/",
  }

By using the command npm run i18n-watch whenever you make any changes in your locale files or your original html template in src folder it's gonna re-translate your html file based on new information and if you're running your webpack dev server you can see the result right after you save changes.

After that, to run i18n-watch command and your Webpack dev server at the same time it would be great installing another npm package for this purpose called npm-run-all by using the command below:

npm i -D npm-run-all

Finally, you can change the script section of your package.json like this to run i18n-watch and your Webpack dev server at the same time and after that if you make any changes you can see the result in the browser right after saving changes.

"scripts": {
    "i18n-watch": "watch 'npm run i18n' src",
    "i18n": "static-i18n -l en -i fa -i en  src --localesPath src/locales/",
    "webpack-dev": "webpack-dev-server --open --config=config/webpack.dev.js",

    "start": "npm-run-all --parallel webpack-dev i18n-watch"
  }

Now, if you use npm start in your terminal you will see your Webpack dev server and i18n-watch are running at the same time watching for any changes.

Hopefully this makes sense.

like image 84
Aspian Avatar answered Sep 27 '22 22:09

Aspian