Skip to main content

Twig教學 - Block標籤

Submitted by admin on Mon, 01/13/2020 - 09:07


0. Drupal block 與 Twig block

在開頭要提醒一下,這篇文章所講的Block指的是Twig Block,跟Drupal中的Block是兩回事。

Drupal的Block是一個顯示物件。在Drupal中,我們可以按照Views的設定顯示想呈現的各種Field,或是在透過custom block自定義我們想要的Drupal Block內容,並透過/admin/structure/block管理頁面把Drupal Block擺到我們想要的區域內。

 

1.Twig Block是什麼

Twig中的block則是一個『可能會被子模板替換掉的區塊』。我們從Twig官方網站的範例來看看這如何運作。

假設有一個base.html內容如下:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css" />
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>

我們可以在上面找到四個Twig Block的宣告,分別是{% block head %}{% block title %}{% block content %}以及{% block footer %},並分別各自對應一個{% endblock %}作為結尾。

這四個Block在這邊出現的意義是讓Twig引擎,或是一個正在閱讀這份HTML檔案的開發者知道,這個區塊有可能會被替換成別的內容。

假設有一個child.html內容如下:

{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome on my awesome homepage.
    </p>
{% endblock %}

整份child.html的文眼(?)在於第一行的extends,這個位在第一行的extends會告訴Twig先去找它的基底,也就是"base.html"。

我們可以看到這份child.html裡面一共定義了三個block,跟base.html相比,唯獨缺了footer。

因此最後我們所看到的輸出內容就是base.html所定義的大框架中,{% block head %}{% block title %}{% block content %}這幾個區塊被置換成child.html所定義的內容,而{% block footer %}維持base.html內所定義的輸出。

 

2. Twig Block在Drupal中的運作

我們可以在Drupal預設的bartik主題中找到上述規則的運作範例,在網頁安裝目錄底下前往/core/themes/bartik/templates資料夾內,可以看到block.html.twig以及block--system-branding-block.html.twig兩個檔案,分別就是基底與子模板。我們可以在後者的第一行看到{% extends "block.html.twig" %}這行引述宣告。

如果要更進一步的看Drupal中的Twig Block如何運作,可以在上述基底以及子模板的{% block content %}內各新增一行測試輸出,例如 <div> test msgA/B </div>,清除快取後觀察網頁頁面的變化。

 

3. Twig block的其他細節

可以用parent()函式在子模板中輸出基底原本的內容,例如

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}

 

可以為了有更好的可讀性,將block的名稱放置在{% endblock %}標記中,例如

{% block sidebar %}
    {% block inner_sidebar %}
        ...
    {% endblock inner_sidebar %}
{% endblock sidebar %}

 

block之外的變數可以在block之內被看到,例如

{% for item in seq %}
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}

 

對於一些比較短的內容,可以省略{% endblock %}標記,例如下面兩者是等價的

{% block title %}
    {{ page_title|title }}
{% endblock %}
{% block title page_title|title %}

 

extends接受變數、陣列輸入,或是條件選擇的變數也可以。如果是陣列輸入,第一個存在的檔案會被當做基底使用。例如

{% extends some_var %}

{% extends ['layout.html', 'base_layout.html'] %}

{% extends standalone ? "minimum.html" : "base.html" %}

 

Tags