1つのjadeから他言語ファイルをgulpビルドする方法
※(2016/10/6修正)npmモジュールの情報が不足していたので修正しました。またjadeをpugに、gulpの設定もbabelを使うように変更しました。
↓こちらのサイトを参考にしました。
参考
静的な多言語Webサイトを1ソースから作る方法 - deepblue-will’s diary
ポイント
- HTMLは1つのJADEファイルで管理
- 各言語は言語ごとにJSONファイルで管理
ながれ
- JSONファイルの設定
- JADEファイルの設定
- 必要なnpmモジュールファイルなどをインストール
- gulpファイルの設定
フォルダ構成
.babelrc gulpfile.babel.js src ├── gulpfile.js │ ├── json │ ├── sample_ja.json │ └── sample_en.json │ └── pug └── sample.pug public ├── 日本語HTML出力先 │ └── en └── 英語HTML出力先
1.JSONファイルの設定:(日/英)
(日本語) sample_ja.json
{ "title": "タイトル", "content": { "name1": "名前1", "name2": "名前2", "profile1": "プロフィール1", "profile2": "プロフィール2" } }
(英語) sample_en.json
{ "title": "TITLE", "content": { "name1": "name1", "name2": "name2", "profile1": "profile1", "profile2": "profile2" } }
2.PUGファイルの設定
JSONで定義した変数名を#{}
で囲ってpugにかきます。
(sample.pug)
doctype html html head title #{title} body dl dt #{content.name1} dd #{content.profile1} dt #{content.name2} dd #{content.profile2} dt #{content.name2} dd #{content.profile2}
3.必要なnpmモジュールファイルをインストール
この記事の内容を実行するのに最低限必要なnpmモジュールをインストールします。
- babel-preset-es2015
- babel-register
- browser-sync
- git://github.com/gulpjs/gulp.git#4.0
- gulp-pug
- gulp-watch
- read-config
npm i babel-preset-es2015 babel-register browser-sync git://github.com/gulpjs/gulp.git#4.0 gulp-pug gulp-watch read-config --save-dev
es2015へ変換するためにpresetの指定が必要なので、
ルートに.babelrc
を作って下記のように指定します。
(.babelrc)
{ "presets": ["es2015"] }
4.gulpファイルの設定
(gulpfile.babel.js)
'use strict'; import gulp from 'gulp'; import browserSync from 'browser-sync'; import watch from 'gulp-watch'; import readConfig from 'read-config'; import pug from 'gulp-pug'; const SRC = './src'; const DEST = './public'; //pugTask const pugTask = (lang) => { //出力先フォルダを設定 let destDir = DEST+'/'+lang; if(lang === 'ja') destDir = DEST+'/'; // //JSON指定 let locals = readConfig(`${SRC}/json/sample_`+lang+`.json`); return gulp.src([`${SRC}/pug/**/*.pug`]) .pipe(pug({ locals: locals, pretty: true })) .pipe(gulp.dest(`${destDir}`)); } //日本語タスク gulp.task('pug:ja', () => { return pugTask('ja'); }); //英語タスク gulp.task('pug:en', () => { return pugTask('en'); }); //日・英両タスクを1つのタスクにまとめる gulp.task('html', gulp.series('pug:ja', 'pug:en')); //serve gulp.task('browser-sync', () => { browserSync({ server: { baseDir: DEST } }); watch([ `${SRC}/pug/**/*.pug`, `${SRC}/json/**/*.json` ], gulp.series('html', browserSync.reload)); }); //実行 gulp.task('serve', gulp.series('browser-sync')); gulp.task('build', gulp.parallel('html')); gulp.task('default', gulp.series('build', 'serve'));
あとはgulp
を実行したら完了です。
あと
トップページでは「top_ja.json」と「top_en.json」を読み、 アバウトページでは「about_ja.json」と「about_en.json」を読む。 っといった感じでページごとにJSONファイルを分けたい場合はgulpの設定を下記のように変更します。
↓この部分
let locals = readConfig(`${SRC}/json/sample_`+lang+`.json`);
↓をこのようにします
//JSON指定 let locals = { 'top': readConfig(`${SRC}/json/top_`+lang+`.json`), 'about': readConfig(`${SRC}/json/about_`+lang+`.json`) }
JADE(PUG)で呼び出すときは、トップページなら#{top.title}
や#{top.content.name1}
、アバウトページなら#{about.title}
や#{about.content.name1}
、のようにします。
#{top.content.name1}
は長いので変数に入れた方が扱いやすいですね。
(例)
- var TITLE = top.title - var CONTENT = top.content doctype html html head title #{TITLE} body dl dt #{CONTENT.name1} dd #{CONTENT.profile1} dt #{CONTENT.name2} dd #{CONTENT.profile2} dt #{CONTENT.name2} dd #{CONTENT.profile2}
つまづいたところ
改行の<br>の表示でつまずきました。
”ごにょごにょ<br>ごにょごにょ”
の<br>
が
ごにょごにょ ごにょごにょ
にならずに
ごにょごにょ<br>ごにょごにょ
になったのです。
JADE(PUG)で呼び出すときに#{変数}
としてたところを!{変数}
にしたら解決しました。
Babelのes2015:メモ
書かないと覚えないのでとにかくメモしていきます。
varとletとconst
var:変数。同スコープ中での再宣言も値の代入もできる。
var i = 0; //OK var i = 1; //OK i = 2; //OK
let:同スコープ中で再宣言はできない。値の代入はできる。
let i = 0; //OK let i = 1; //NG i = 2; //OK
const:定数。同スコープ中で再宣言も値の代入もできない。
const i = 0; //OK const i = 1; //NG i = 2; //NG
参考
BabelのLearn ES6を学んでいく(2 - Qiita
exportとimport
変数やモジュールやクラスを別ファイルにしたときの「es2015」の書き方です。
export:変数などを呼び出す側
//module.js(export側) var num = 1; const name = "なまえ"; function hoge() { return "ABC" }; export{num, name, hoge};
import:読み込み側
//main.js(import側) import {num, name, hoge} from './module'; console.log(num); //1 console.log(name); //なまえ console.log(hoge()); //ABC
default export
default export
を使うと、import側で{num, name, hoge}
みたいに対象を{}
で囲わなくてよくなります。
こっちを使うことが多くなりそうです。
//module.js(export側) export default { num : 1, name: "なまえなまえ", hoge: () => {return "ABC"} };
//main.js(import側) import Variable from './module'; console.log(Variable.num); //1 console.log(Variable.name); //なまえ console.log(Variable.hoge()); //ABC
参考
class
class CustomBox{ constructor () { this.setListener(); } setListener () { console.log("でました") } } const custombox = new CustomBox();//実行
参考
extends(classの継承)
//読み込み側 import Klass from './Klass'; //クラスの読み込み const klass = new Klass(); //クラスの実行
//Klass.js class Superklass { constructor () { console.log("super"); } }; export default class Subklass extends Superklass { constructor () { super();//<-これがないとエラーになる this.init(); } init () { console.log("sub") } }
参考
ejsでHTMLを量産したときのおさらい
レイアウトが同じで「タイトル」と「メイン画像」が違うHTMLを量産するために使いました。 あまり理解できてないので、理解を深めるためにまとめようと思います。
ながれ
構想
フォルダ構成
↓こんなかんじで作ろうと思います。
src ├── __gulpfile.js__ │ ├── json │ └── __pages.json__ └── ejs └── __template.ejs__ dist └── __ejs生成HTML出力先__
JSONデータ
下記3つのデータJSONで管理しようと思います。
- 出力ファイル名(page)
- タイトル(title)
- 画像ファイル名(imageSrc)
1. JSONファイル(pages.json)をつくる
① 任意の場所に pages.json をつくります。(今回はsrcフォルダ内にjsonフォルダをつくって入れました。)
② 構想どおりにJSONデータを作成。↓こんなかんじにしました。
{ "pages": [ { "page" : "page1", "title" : "タイトル1", "imageSrc" : "000000"}, { "page" : "page2", "title" : "タイトル2", "imageSrc" : "000001"}, { "page" : "page3", "title" : "タイトル3", "imageSrc" : "000002"}, { "page" : "page4", "title" : "タイトル4", "imageSrc" : "000003"}, { "page" : "page5", "title" : "タイトル5", "imageSrc" : "000004"}, { "page" : "page6", "title" : "タイトル6", "imageSrc" : "000005"}, { "page" : "page7", "title" : "タイトル7", "imageSrc" : "000006"}, { "page" : "page8", "title" : "タイトル8", "imageSrc" : "000007"}, { "page" : "page9", "title" : "タイトル9", "imageSrc" : "000008"}, { "page" : "pag10", "title" : "タイトル10", "imageSrc" : "000009"} ] }
2. EJSファイル(template.ejs)をつくる
① 任意の場所に template.ejs をつくります。(今回はsrcフォルダ内にejsフォルダをつくって入れました。)
② template.ejsに基本のHTMLをかく。(まずはふつうのHTML)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> (以下中略) </head> <body> <!--wrapper--> <div class="wrapper"> (以下中略) </div> </body> </html>
③ ページによって書き換えたい部分を「<%= 変数名 %>」←こういう風に書く。「data.title」と「data.imageSrc」。
(*「data.title/data.imageSrc」はこのあとgulpfile.jsにEJSの設定を書くところで、JSONの「pages」の値を代入してる値。)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>サイトタイトル - <%= data.title %></title> </head> <body> <!--wrapper--> <div class="wrapper"> <img src="img/<%= data.imageSrc %>.png"> </div> </body> </html>
3.EJSの設定をgulpfile.jsに追記する
① ターミナルで
npm install gulp-ejs --save-dev
② gulpfile.jsにejsを追記
ejs = require("gulp-ejs")
③ gulpfile.jsにタスクを追記 (ここが大事)
gulp.task('ejs', function(){ // ページ生成用JSONファイルの読み込み var jsonData = require('../src/json/pages.json'); //タスクをページ毎に設定、まとめて定義 jsonData.pages.forEach(function (data, index) { //PC gulp.src("ejs/template.ejs") .pipe(ejs({ data:{ //JSONデータをテンプレートファイルに渡す name: data.page,//ページ名 title: data.title,//タイトル imageSrc: data.imageSrc,//画像ファイル名 } })) .pipe(rename(data.page+".html")) //出力ファイル名を指定 .pipe(gulp.dest("../dist/")); //ファイル出力先を設定 }); });
4.gulpタスクを起動
ターミナルでタスクを実行します
gulp ejs
distフォルダ内にHTMLファイルが生成されていれば完了です。
補足 PC/SPそれぞれのテンプレートで生成したいとき
複数のテンプレートを実行したい場合はgulpfile.jsを下記のように書き換えます。
- PC/SPそれぞれテンプレートを作成
- gulpfile.jsにSP用の記述を追記
gulp.task('ejs', function(){ // ページ生成用JSONファイルの読み込み var jsonData = require('../src/json/pages.json'); //タスクをページ毎に設定、まとめて定義 jsonData.pages.forEach(function (data, index) { //PC gulp.src("ejs/template.ejs") .pipe(ejs({ data:{ //JSONデータをテンプレートファイルに渡す name: data.page,//ページ名 title: data.title,//タイトル imageSrc: data.imageSrc,//画像ファイル名 } })) .pipe(rename(data.page+".html")) //出力ファイル名を指定 .pipe(gulp.dest("../dist/")); //ファイル出力先を設定 //SP gulp.src("ejs/m/template.ejs") .pipe(ejs({ data:{ //JSONデータをテンプレートファイルに渡す name: data.page,//ページ名 title: data.title,//タイトル imageSrc: data.imageSrc,//画像ファイル名 } })) .pipe(rename(data.page+".html")) //出力ファイル名を指定 .pipe(gulp.dest("../dist/m/")); //ファイル出力先を設定 }); });
今回使ったのはejsの<%= 変数名 %>だけでしたが、 ほかにもincludeやforなど便利な構文があるようなので折をみて使ってみたいと思います。
構文については、こちらの記事がとても勉強になりました
- テンプレートエンジンEJSで使える便利な構文まとめ - Qiita http://qiita.com/y_hokkey/items/31f1daa6cecb5f4ea4c9
参考文献
- テンプレートエンジン「EJS」とタスクランナー「Gulp.js」で爆速HTMLコーディング http://liginc.co.jp/web/html-css/html/144170
- JavaScript - gulpで手軽にEJSテンプレートをHTMLに変換 - Qiita http://qiita.com/yuichiroharai/items/63b0769bc8ebe0220018