Twigのテンプレート分割
似てるやつが多い
include
extends
embed
use
macro
それぞれどういうものなのか
どういうふうに使い分けるのか良いのか
スクボのコードブロックが.tiwgに対応していないので.htmlで書いているmrsekut.icon
macro
一般的なmacroという意味でのmacro
code:macro.html
{% macro test(a1, a2) %}
a1: {{ a1 }}, a2: {{ a2|default('a2 default') }}
{% endmacro %}
includeを使わずに全部macroでいいのでは?と思っているmrsekut.icon
includeと違って、「このmodule内で必要とする引数」が明示されている
react componentにちかい
同じファイルに書いたとしてもimportしないといけない
code:twig
{% import _self as m %}
{{m.test(1,2)}}
一般的な使い分けがわからないmrsekut.icon
twigのノリ的に引数の明示とかたぶんそんな重視していないんだろうし
macroはファイルを分けなくても定義できるので、それが嬉しいとか?
docsとか見た感じ、あまり大きい単位ではやらないんだろうか
jqueryとの兼ね合いのコツ
切り出したmacro内にjqueryを書いてもscopeが切られてないので複数回呼ばれてしまう
htmlのid=と、macro内の何かしらのidで整合性を取ることになる
container的な部分にidを振っておけば、あとはselectorで特定できる
container部分にstyle用のclass、jquery用のidを書いておけば、あとは共通で使えばいい
code:twig(php)
<div id="hoge_{{Hoge.id}}">
<div class="sum"></div>
<button type="submit" class="submit">決定</button>
</div>
code:jquery.js
const container = #hoge_{{Hoge.id}} // containerを用意しておく
// container + class名で特定する
$(${container} .submit).on('click', function(){..})
$(${container} .sum).text('hoge');
これをしない場合、あらゆる要素に対し、id="hoge_{{Hoge.id}}"のように書き、同様にjqueryも$('.hoge_{{Hoge.id}}')と書かなくてはならない
ごちゃごちゃする
修正もダルい
scssのselectorも修正しないといけない
include
他の.twigファイルや.htmlファイルを埋め込む
withなどで渡す引数を制限できるが、includeされる側から見るとその明示がない
という観点において見るとmacroの方が良いと思われる
code:twig
{% include 'hoge.html'%}
{% include 'hoge.twig'%}
with
引数を明示できる
code:twig
{% include 'hoge.twig' with { 'id' : itemId } %}
微妙にこれの立ち位置を理解していないmrsekut.icon
withをつけようがつけまいが、Controllerから渡ってきた値はglobalにあるのでアクセスできる
(できてしまう)
only
呼び出し側のtemplateで回っている値を呼んだテンプレート側に渡さなくなる
withと共に指定すると、withで指定されているもののみを共有する
code:twig
{% include 'include2.twig' with { 'local': 'LOCAL' } only %}
globalの汚染をマシにする
常につけるべきでは?mrsekut.icon
ignore missing
そのファイルが無かった場合に無視する
code:twig
{% include 'sidebar.html' ignore missing %}
extends
継承して親が子を上書きする
多重継承はできない
OOPにおける継承と同じノリで考えられる
親と子が存在し、
親にdefaultで表示すべき内容を書いておく
子は、親を継承し変更したい部分のみを書き換える
子で書いていない部分は親のものが引き継がれる
プロダクト全体でページのフォーマットが決まっているなら便利かもしれない
サイドバー、ヘッダー、フッター、みたいな
例
code:p.html
<html>
<head>
<title>{% block title %}{% endblock %} - mypage</title>
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
フッター
{% endblock footer %}
</div>
</body>
</html>
code:c.html
{% extends "p.html" %}
{% block title %}タイトルだよ{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my homepage.
</p>
{% endblock %}
子では{{parent()}}とすると、親ブロックの内容を表示できる
ごちゃごちゃになりそうmrsekut.icon
略記できる
以下は同じ
code:html
{% block title %}
{{ page_title|title }}
{% endblock %}
{% block title page_title|title %}
embed
子を親が上書きする
ややこすぎるmrsekut.icon*2
Reactの考え方に慣れていたらこれが欲しくなるタイミングがわからない
せめてpropsで表示を切り替えよう、とするはず
使いたくないmrsekut.icon*2
考える順序としては、
普通のイメージで子を作る
code:c.html
{% block embed1 %}
EMBED 1 DEFAULT
{% endblock %}
{% block embed2 %}
EMBED 2 DEFAULT
{% endblock %}
その子を使いたい親が、子を使いつつも上書きができる
その際にembedを使う
code:p.html
{% block content %}
{% embed 'embed.twig' %}
{% block embed1 %}
EMBED 1 OVERWRITE
{% endblock %}
{% endembed %}
{% endblock %}
上2つのファイルの結果の表示はこうなる
code:html
EMBED 1 OVERWRITE
EMBED 2 DEFAULT
use
traitの考え方に近い
extendsは多重継承できないので、そこを解消します、みたいなノリ
docsでも言及されているが、基本は使わない
jQueryとのスコープをどうにかする
各パーツ(例えばBody)がどこから参照されているのかがわからない
twigのjQueryがファイルを分けてもscopeで切り分けられない
複数箇所で呼び出されているblock内にjqueryを書けば、その個数分実行される
例えば.hogeを1回clickするだけで処理が10回呼び出される
twigはComponentに分けているのにjqeuryは1箇所に書いているので、処理が分断している
参考