【Laravel】Template engine を作ってみた

:::note info
この記事は、Laravelで使えるTemplate engine BLOCSの紹介です。
:::

# はじめに
BLOCSは、Laravelで使えるTemplate engineです。なぜBLOCSを開発するのか？「LaravelのBladeって結局プログラムをしないといけない感じがします」すべてはこの一言に集約されます。

Bladeのテンプレートでは、本の一覧表示などの繰り返し処理を以下のように記述します。せっかくHTMLは構造化されているのに、構造を活用せずにテンプレートを書くので「結局プログラムをしないといけない感」が出るのではと。HTMLの構造を活かすことで、Bladeのプログラムっぽさを減らせるのでは？と考え、BLOCSの開発を始めました。

```html:example.blade.php
@foreach($books as $book)
    <tr>
        <td>{{ $book->id }}</td>
        <td>{{ $book->title }}</td>
        ...
        <td>
            @foreach($book->tags as $bookTag)
                <span>
                    {{ $bookTag->name }}
                    <br>
                </span>
            @endforeach
        </td>
        ...
    </tr>
@endforeach
```

## BLOCSができること
HTMLを動的にする多くの場合、開始タグから終了タグまでを置換、表示・非表示、繰り返し表示などの処理をします。それなら、開始タグにデータ属性をつけて、開始タグから終了タグまでを処理をすればいいのではと考えました。BLOCSはデータ属性を開始タグに追加して、HTMLを動的に生成します。この記述方法をタグ記法と呼びます。

BLOCSを使うと、同様の処理を以下のように記述できます。テンプレートで指定したデータ属性`data-*`で、HTMLを動的に生成します。HTMLをくずさずに構造を活かして、シンプルに記述できるテンプレートエンジンを目指して、BLOCSを開発しています。

```html:example.blocs.html
<tr data-loop=$books>
    <td>{{ $book->id }}</td>
    <td>{{ $book->title }}</td>
    ...
    <td>
        <span data-loop=$book->tags data-assign=$bookTag>
            {{ $bookTag->name }}
            <br>
        </span>
    </td>
    ...
</tr>
```

:::note info
BLOCSはHTMLの構造を活かしてシンプルに書ける
:::

他のテンプレートの読み込みや、条件によるHTML表示の制御など一通りのデータ属性をそろえてはおりますが、Laravelの標準テンプレートエンジンBladeとハイブリッドで使うことができるので、開発者の嗜好に合わせて楽になりそうな部分だけBLOCSを使ってください。

# 準備
Laravelがインストールされている環境に、composerでインストールしてください。

https://github.com/blocs/blocs

:::note info
composer require blocs/blocs
:::

# テンプレートを書く
Bladeのファイル名は`*.blade.php`ですが、BLOCSのファイル名は`*.blocs.html`です。BLOCSテンプレートはHTMLとしてブラウジングできるので、拡張子を.htmlにしました。

:::note info
BLOCSテンプレートは`*.blocs.html`で作る
:::

## タグ記法
それでは、よくあるエラーがあればメッセージを表示するテンプレートを作ってみましょう。Bladeで書くとこんな感じでしょうか。

```html:example.blade.php
<html>
@if ($errorMessage)
    <div class="error">
        {{ $errorMessage }}
    </div>
@endif
</html>
```

BLOCSは、こんな感じで書けます。データ属性を開始タグに追加するだけなので、テンプレートにする前のHTMLをそのまま残しておくことができます。BLOCSテンプレートは、HTMLをくずさずにそのままブラウジングできることを目指しています。

```html:example.blocs.html
<html>
<div class="error" data-exist=$errorMessage data-val=$errorMessage>
    errorMessage
</div>
</html>
```

BladeとBLOCSをハイブリッドで、下記のように書くこともできます。お好みでBLOCSとBladeを使い分けてください。

```html:example.blocs.html
<html>
<div class="error" data-exist=$errorMessage>
    {{ $errorMessage }}
</div>
</html>
```
:::note info
タグ記法はHTMLの開始タグに属性を追加する
:::

## コメント記法
他のテンプレートを読み込む時や、HTMLタグに属性を動的に追加する時にコメント記法で書きます。データ属性`data-attribute`は、コメント記法の次にあるHTMLタグの属性値を置換します。

それでは、よくあるエラーがあれば`class`を`error`、なければ`success`とするテンプレートは作ってみましょう。Bladeではこんな感じでしょうか？

```html:example.blade.php
<html>
@if ($errorMessage)
  <div class="error">{{ $errorMessage }}</div>
@else
  <div class="success">Success</div>
@endif
</html>
```
BLOCSは、こんな感じで書けます。データ属性をコメントに書くので、HTMLをくずさずにそのままブラウジングできます。

```html:example.blocs.html
<html>
<!-- data-attribute=class data-val="error" data-exist=$errorMessage -->
<div class="success" data-val=$errorMessage>Success</div>
</html>
```

`data-attribute`は以下のように省略することもできます。
```html:example.blocs.html
<html>
<!-- :class="error" data-exist=$errorMessage -->
<div class="success" data-val=$errorMessage>Success</div>
</html>
```

:::note info
`data-attribute`などコメント記法で書くタグ属性もある
:::

# おわりに
最後まで読んでいただき、ありがとうございました。
Laravelは素晴らしいフレームワークです。Laravelと共に、BLOCSがプログラマー皆さんのアプリケーション開発をサポートできればいいなと思っています。

# 関連サイト
1. [サービスサイト](https://blocs.jp)
2. [GitHub](https://github.com/blocs/blocs)
3. [Packagist](https://packagist.org/packages/blocs/blocs)