helen's blog

ずっとおもしろいことしてたいな。

GulpとEJSで設定をできるだけ減らしてみた

設定ファイルを手で書くとミスるし
ストレスマッハなのでがんばって減らしてみました

ファイル構成

ページの中身をcontentsとしてURLに合わせてディレクトリを切り、
それぞれのjndex.ejsの上下にheadやらfooterやらをくっつけて使います

.
├── contents # ページの中身
│   ├── index.ejs
│   └── hoge
│       └── fuga
│           └── piyo
│               └── index.ejs
└── layouts
    ├── common # front、mypageから使う共通系パーツ
    │   ├── _navi.ejs
    │   ├── _localNavi.ejs
    │   ├── _logged.ejs
    │   └── _notLogin.ejs
    ├── front # フロントで使用するパーツ
    │   ├── _footer.ejs
    │   └── _headTag.ejs
    ├── frontAfterContent.ejs # フロントの要素の後につけるパーツ
    ├── frontBeforeContent.ejs  # フロントの要素の前につけるパーツ
    ├── mypage # ログイン後に使用するパーツ
    │   ├── _footer.ejs
    │   ├── _headTag.ejs
    │   └── _header.ejs
    ├── mypageAfterContent.ejs # ログイン後の要素の後につけるパーツ
    └── mypageBeforeContent.ejs # ログイン後の要素の前につけるパーツ

headerやfooterの間をクルクル回すのをよく見るけど
for文書くとどこで何が動いてるのかわからなくなるので、
各contentsで何を呼ぶか明示します

gulpfile

ここでfor文で回すのをよく見るけどやらず、コンパイルして拡張子をhtmlにしてるだけ
contents/**/*.ejsな感じにすると
ディレクトリ階層を維持したままコンパイルしてくれるので設定書かなくて済む

const gulp = require('gulp');
const ejs = require('gulp-ejs');
const jsonData = require('./settings.json');

gulp.task('default', ['main']);
gulp.task('main', ['ejs']);

gulp.task('ejs', function(){
    return gulp.src(
        ['contents/**/*.ejs', '!' + 'contents/**/_*.ejs']
    )
        .pipe(ejs({jsonData:jsonData}, {'ext': '.html'}))
        .pipe(gulp.dest('../'));
});

setting.json

設定をまとめて名前をつけて呼び出せるようにして

{
    "default":{
        "title":"title",
        "description":"description"
    },
    "hogefugapiyo":{
        "title":"fugaaaa",
        "isLogin":true
    }
}

こんな感じで呼び出す

<% data = jsonData.default; %>

特に個別の指定がなければdefaultとか書いとく感じ
CakePHPだとcontrollerでtitle、descriptionを決めれるから(こうあるべきかは別の話)
URLのコントローラーまでの設定を作っとけば
同じコントローラーのアクションどうしはその設定を使いまわせるっていう幸せ

呼び出し

使いたい設定の名前を変えるだけ

<% data = jsonData.default; %>
<%- include('../layouts/frontBeforeContent', data); %>
<!-- 要素 -->
<%- include('../layouts/frontAfterContent'); %>
<!-- frontAfterContentは渡すデータがないから書いてないけどdataあると今後幸せになれそう -->

で、上下のパーツは

$ cat layouts/frontBeforeContent.ejs
<!DOCTYPE html>
<html>
  <%- include('../layouts/front/_headTag', data) %>
  <body class="lo1 skin-blue">
    <%- include('../layouts/common/_gnavi') %>
    <%- include('../layouts/common/_makeNavi') %>
    <%- include('../layouts/common/_akibaNavi', data) %>
$ cat layouts/frontAfterContent.ejs
    <%- include('../layouts/front/_footer') %>
  </body>
</html>

各小パーツを呼び出すだけにして、
1箇所いじれば全部に反映されるようになってる

ログイン判定

ログイン前ログイン後で表示が変わるものは設定ファイルで管理

ログイン済みにしたいページのみsettingにこれを追加して

"isLogin":true

パーツはこんな感じにする

<% if(data.isLogins){ %>
    <%- include('../common/_logged'); %>
<% } else { %>
    <%- include('../common/_notLogin'); %>
<% } %>

まあほんとはtrue,falseで管理されてるのかわかんないけどねー
isLoginがtureってイメージしやすいからそう書いてます

json書きたくねーymlにする!って言ってたけど
最終的にymlにするのがめんどうになりました