owned mediaウェブ制作に役立つコンテンツを発信中!

Pugでmixinやblock appendを使って値を受け渡してコンポーネントファイルの読み込みを分岐させる

最終更新日: Update!!
大量にページが存在するサイトなどを効率よくコーディングする際にはテンプレートエンジンを使うことが多いかと思いますが、このような場合にページごとにコンポーネントを分岐させたいケースもあります。今回はPugでコンポーネントファイルを読み込む際に分岐させるパターンをまとめていきたいと思います。   Pugでのコンポーネントファイルを使ったコーディング手法については過去記事「Pugのincludeとmixinの違いと使いわけについてまとめ」の記事だったり「Pugでテンプレートとデータでファイルを切り分けた開発を行う」などでも少し触れていたところもありますが、Vue.jsやReactなどでは値を受け渡して、その値をコンポーネント側で受け取り、その条件によってコンポーネントを切り分けるなどがよく行われますが、Pugの場合には外部のPugファイルを読み込む際に直接ファイルへ値を受け渡すことができないようです。   そこで、Pugの機能である「mixin」を使って引数で値を受け渡す方法と、「block append」で変数を追加更新する方法を使って実現していきたいと思います。また、Pugの環境構築については、以下の過去記事などをご参考ください。 (参考記事) ・webpackでPugのコンパイル環境を作成してみる ・GulpでJavascriptのテンプレートエンジンPugの開発環境を構築する   今回は、ページごとにそれぞれコンテンツ部分のセクションを外部コンポーネントファイルとして扱い、ページファイルにページ識別用の値を変数の中に定義するという次のような前提で進めていきます。まずは全体のベースとなるHTMLを継承元のファイルとして作成します。 【components/_layout.pug】
block variables

doctype html
html
  head
    meta(charset="utf-8")
    meta(name="viewport" content="width=device-width,initial-scale=1.0")
    title #{currentPage}
  body
    header

block pageContent

    footer
  そして、個別のHTMLとして生成されるページ用のファイルで、先ほどの全体のレイアウトを継承してページの中身を記述していきます。今回はこのファイル内で外部のコンポーネントファイルを読み込んでいきます。 【index.pug】
extends components/_layout.pug

block variables
  - var currentPage = 'home'

block pageContent
  main
   
mixinで引数に値を入れて受け渡す
1つ目の方法はmixinを使ってファイルインクルードの処理を分岐させる方法です。mixinは関数を定義できるようなもので、引数を取ることができ、この引数にページの識別用の値を使うことで、ページごとに異なるコンポーネントファイルをインクルードさせていくという形になります。   この方法ですと、読み込むファイルを条件ごとに変えるので、基本的に条件に対応したコンポーネントファイルが必要になります。ここでは異なるページ用のコンポーネントを用意しています。
components
  ┣ _layout.pug
  ┣ _home-section.pug
  ┣ _about-section.pug
  ┗ _contact-section.pug
index.pug
about.pug
contact.pug
  個別のコンポーネントファイルではそのまま読み込まれて表示される内容を静的に記述しています。基本的にコンポーネント内では分岐処理を行わないので内容はシンプルになります。
// _home-section.pug
section
  h1 トップページのコンテンツ

// _about-section.pug
section
  h1 ABOUTページのコンテンツ

// _contact-section.pug
section
  h1 CONTACTページのコンテンツ
  そして読み込む側のページファイルを見ていきます。まずページ識別用の変数を「block」内で定義します。その後に「mixin」でページごとに分岐させてコンポーネントを読み込む処理を作成していきます。その際には引数にページ識別用の値が入るようにしておき、処理の中で引数の値に応じて、「include」で対応したコンポーネントファイルを読み込んでいきます。そして表示させる箇所で定義したmixinを実行します。 【index.pug】
extends components/_layout.pug

block variables
  - var currentPage = 'home'

mixin section(page)
  if page === 'home'
    include components/_home-section.pug
  else if page === 'about'
    include components/_about-section.pug
  else if page === 'contact'
    include components/_contact-section.pug

block pageContent
  main
    +section(currentPage)
  これでコンパイルしてみるとページごとに分岐されてコンポーネントが読み込まれて、それぞれ対応したコンテンツとしてHTMLが生成されるようになります。 【index.html】※一部抜粋
......
<main>
  <section>
    <h1>トップページのコンテンツです</h1>
  </section>
</main>
......
  この方法では、コンポーネント側はすっきりとシンプルになるものの、コンポーネントを呼び出す側ではmixinの処理を定義しないといけないため、コードの量も増えてしまうので注意が必要です。    
block appendで変数を更新する
先ほどはmixinを使って条件に合わせてコンポーネントの読み込みを分岐させる処理を作成する形で切り分けてきましたが、次の方法は、「block append」を使ってコンポーネント側で定義しているページ識別用の値を利用するやり方になります。ここでは、コンポーネント側で条件分岐をさせるため、下記のようにコンポーネントファイルは条件ごとに分かれずに1つにまとめられます。
components
  ┣ _layout.pug
  ┗ _section.pug
index.pug
about.pug
contact.pug
  ページ側のファイルでは、分岐がない場合と同様に通常通りincludeで外部のコンポーネントファイルを読み込んでいきます。先ほどと同じくblockのセクションでページ識別用の値を設定しておきます。 【index.pug】
extends components/_layout.pug

block variables
  - var currentPage = 'home'

block pageContent
  main
    include components/_section.pug
  続いてコンポーネント側のファイルですが、先ほどとは異なり、こちらで条件分岐をさせていきます。先ほどのものは条件に合わせて読み込むファイルを切り分けていましたが、ここでは条件に合わせて表示させる内容を切り分けるようにする必要があります。その際にページ識別用の値を使うのですが、「block append」のセクションで先ほどの値を新たな変数に格納することで、コンポーネント内でページ識別用の値が受け渡されり、この値を利用できるようになります。 【components/_section.pug】
block append variables
  - var page = currentPage

if page === 'home'
  section
    h1 トップページのコンテンツ
else if page === 'about'
  section
    h1 ABOUTページのコンテンツ
else if page === 'contact'
  section
    h1 CONTACTページのコンテンツ
  blockというのは定義することでどのファイルでも定義した部分の内容を呼び出すことができる、いわばグローバル変数のようなイメージですが、この時に注意したいのは新たに変数を定義する際には「block append」もしくは「block prepend」として変数を使う必要があります。なぜなら、そのままblockで定義してしまうと、継承元で定義している変数が全て上書き更新されて使えなくなってしまうからです。   block appendやblock prependを使うことで、継承元の情報を維持しながら新たに変数を更新できるのですが、これらは下記のように更新するblockの内容を継承元のブロックのどこに入れるかという違いがあります。  
block append 継承元のファイルで定義されているblockの内容の最後尾に継承先で定義したものを追加してblockを更新
block prepend 継承元のファイルで定義されているblockの内容の先頭に継承先で定義したものを追加してblockを更新
  そのため、そうしないと通常通りblock記述した場合には継承先で定義した内容に変数が上書き更新されてしまい、今回の場合でページの識別ができなくなってしまいます。   この方法では読み込む側のファイルには処理を書かないのでコードはすっきりしますし、条件によってコンポーネントが増えることはないのですが、コンポーネント側では分岐処理が行われるためコンポーネント側のコードが複雑で長くなってしまいます。   mixinでインクルードの処理を切り分けるか、あるいはblockで定義した変数を追加更新するかは、分岐の内容や複雑度合い、またコンポーネントの数に合わせて使い分けるのが良いですね。分岐の条件や処理が複雑になる場合だったり、コンポーネントが比較的大きな部分が含まれる時にはmixinを使う方法が、分岐処理がシンプルでコンポーネントの数をあまり増やしたくない場合にはblockでの変数を更新する形で値を受け渡す方法がよさそうですね。   ただし、あまりにも複雑な場合や大量のコンポーネントを扱ったり、動的に切り替える必要がある場合にはJavaScriptで実装する形になりそうですし、そちらの方が楽だったりもします。  
  今回はPugでコンポーネントファイルを読み込む際に分岐させるパターンをまとめてみました。PugではVue.jsやReactとは異なり、元々コンポーネントを読み込む際に直接的に値を受け渡すことができないため、このように工夫することが必要になります。仕様に合わせてこれらをうまく使い分けて効率よくコーディングを進めていきたいですね。
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram