Một trong những tính năng thú vị mà Twig mang đến cho Drupal 8 & 9 là các template có thể dễ dàng mở rộng và ghi đè hơn.
Giới thiệu về tính năng mở rộng của Twìg trong Drupal
Một trong những điều tuyệt vời của Drupal 8 và Drupal 9 là sự ra đời của Twig. Theo ý kiến cá nhân, đó là một công cụ tạo template vượt trội hơn nhiều so với PHP Template.
Đối với lập trình viên frontend, nó có một cú pháp code thân thiện hơn nhiều, gần giống với các công cụ tạo template JS khác.
Hãy tưởng tượng tình huống này (tôi chắc rằng nhiều nhà lập trình đã gặp phải điều này trước đây): bạn đang xây dựng một trang web và một số mẫu trang của bạn cần có chiều rộng đầy đủ, trong khi những mẫu khác có phần nội dung bị giới hạn chiều rộng. Hơn nữa, trên một số trang, bạn muốn thêm một class để thay đổi kiểu điều hướng của mình.
Drupal phiên bản drupal 7 cũ, sẽ giống như:
-
Lấy page.tpl.php và sao chép nó, ví dụ: page-- feature-content.tpl.php
-
Thêm mới một wrapper cho template mới
-
Xóa cache
-
Hoàn thành công việc
Điều này cũng là tốt, nhưng chắc chắn là hơi bị rối hơn và có khả năng ảnh hưởng các phần footer, header ...
Nhưng trong phiên bản mới Drupal 8 và Drupal 9 đã có twig với giải pháp nhanh gọn hơn rất nhiều bằng "blocks"
Note: Block trong Twig khác Block trong Drupal - tránh nhầm lẫn.
Block trong twig giúp bạn có thể ghi đè một phần của template bằng một subtemplate một cách dễ dàng thay vì sao chép như ở phiên bản Drupal 7.
Dưới đây là cách làm
Bước 1: Tạo một Block và đặc tên để giữ nội dung mình muốn ghi đè
{% block header %}
{% set alt_header = FALSE %}
{# Header code #}
{% endblock %}
{% block wrapper %}
{% block content %}
{# Content code #}
{% endblock %}
{% block footer %}
{# Footer code #}
{% endblock %}
{% endblock %}
Bước 2: Trong trang page--featured-content.html.twig , chúng ta chỉ cần
{% extends 'page.html.twig' %}
{% block wrapper %}
<div class="container">
{{ parent() }}
</div>
{% endblock %}
Dòng đầu tiên là nói cho Twig biết sẽ dùng template nào làm cơ sở. Block nội dung sẽ được sử dụng thay thế cho template cơ sở và phần còn lại giữ nguyên.
Dòng parent() nó yêu cầu Twig chỉ când đánh dấu nội dung của block chính trong block mới khai báo ở trên. Vì vậy bạn không cần phải code lại toàn bộ.
Nếu block lồng nhau như trong ví dụ trên, thì cũng không sao cả.
Vậy với các biến trong template thì sao ?
Ví dụ như chúng ta cần một thanh menu tối (dark nav) trong template Twig như sau :
{% set dark_nav = FALSE %}
{% block header %}
{% set nav_class = '' %}
{% if dark_nav %}
{% set nav_class = 'header--dark-nav' %}
<header class="header {{ nav_class }}">
{# header markup here #}
</header>
{% endif %}
{% endblock %}
Chúng ta chỉ cần khai báo biến trên ngoài block và trong block mới sẽ định nghĩa lại nó là được, như :
{% block header %}
{% set dark_nav = TRUE %}
{{ parent() }}
{% endblock %}
Tóm lại, đơn giản mà nói Block giúp bạn kế thừa giá trị mặc định từ template cơ sở ban đầu vào template con dễ dàng hơn.