Creating and Using Templates

A template is the best way to organize and render HTML from inside your application, whether you need to render HTML from a controller or generate the contents of an email. Templates in Symfony are created with Twig: a flexible, fast, and secure template engine.

テンプレートは、コントローラーから HTML をレンダリングする必要がある場合でも、電子メールのコンテンツを生成する必要がある場合でも、アプリケーション内から HTML を整理およびレンダリングするための最良の方法です。 Symfony のテンプレートは、柔軟で高速、かつ安全なテンプレート エンジンである Twig で作成されます。

Twig Templating Language

The Twig templating language allows you to write concise, readable templates that are more friendly to web designers and, in several ways, more powerful than PHP templates. Take a look at the following Twig template example. Even if it's the first time you see Twig, you probably understand most of it:

Twig テンプレート言語を使用すると、Web デザイナーにとってより使いやすく、いくつかの点で PHP テンプレートよりも強力な、簡潔で読みやすいテンプレートを作成できます。次の Twig テンプレートの例を見てください。 Twig を初めて目にする場合でも、ほとんどのことは理解できるでしょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
    <head>
        <title>Welcome to Symfony!</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

        {% if user.isLoggedIn %}
            Hello {{ user.name }}!
        {% endif %}

        {# ... #}
    </body>
</html>

Twig syntax is based on these three constructs:

Twig の構文は、次の 3 つの構造に基づいています。
  • {{ ... }}, used to display the content of a variable or the result of evaluating an expression;
    {{ ... }}、変数の内容または式の評価結果を表示するために使用されます。
  • {% ... %}, used to run some logic, such as a conditional or a loop;
    {% ... %} は、条件やループなどのロジックを実行するために使用されます。
  • {# ... #}, used to add comments to the template (unlike HTML comments, these comments are not included in the rendered page).
    {# ... #}、テンプレートにコメントを追加するために使用されます (HTML コメントとは異なり、これらのコメントはレンダリングされたページには含まれません)。

You can't run PHP code inside Twig templates, but Twig provides utilities to run some logic in the templates. For example, filters modify content before being rendered, like the upper filter to uppercase contents:

Twig テンプレート内で PHP コードを実行することはできませんが、Twig には、テンプレート内でいくつかのロジックを実行するためのユーティリティが用意されています。たとえば、フィルターはレンダリングされる前にコンテンツを変更します。たとえば、大文字のコンテンツへの上部フィルターのように:
1
{{ title|upper }}

Twig comes with a long list of tags, filters and functions that are available by default. In Symfony applications you can also use these Twig filters and functions defined by Symfony and you can create your own Twig filters and functions.

Twig には、デフォルトで使用可能なタグ、フィルター、関数の長いリストが付属しています。 Symfony アプリケーションでは、Symfony によって定義されたこれらの Twig フィルターと関数を使用することもでき、独自の Twig フィルターと関数を作成することもできます。

Twig is fast in the prod environment (because templates are compiled into PHP and cached automatically), but convenient to use in the dev environment (because templates are recompiled automatically when you change them).

Twig は prod 環境では高速ですが (テンプレートは PHP にコンパイルされ、自動的にキャッシュされるため)、dev 環境で使用するのは便利です (テンプレートは変更時に自動的に再コンパイルされるため)。

Twig Configuration

Twig has several configuration options to define things like the format used to display numbers and dates, the template caching, etc. Read the Twig configuration reference to learn about them.

Twig には、数値や日付の表示に使用される形式、テンプレートのキャッシュなどを定義するための構成オプションがいくつかあります。それらについては、Twig 構成リファレンスをお読みください。

Creating Templates

Before explaining in detail how to create and render templates, look at the following example for a quick overview of the whole process. First, you need to create a new file in the templates/ directory to store the template contents:

テンプレートの作成方法とレンダリング方法を詳しく説明する前に、次の例を見て、プロセス全体の概要を簡単に説明します。まず、templates/ ディレクトリに新しいファイルを作成して、テンプレートの内容を保存する必要があります。
1
2
3
{# templates/user/notifications.html.twig #}
<h1>Hello {{ user_first_name }}!</h1>
<p>You have {{ notifications|length }} new notifications.</p>

Then, create a controller that renders this template and passes to it the needed variables:

次に、このテンプレートをレンダリングし、必要な変数を渡すコントローラーを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// src/Controller/UserController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class UserController extends AbstractController
{
    // ...

    public function notifications(): Response
    {
        // get the user information and notifications somehow
        $userFirstName = '...';
        $userNotifications = ['...', '...'];

        // the template path is the relative file path from `templates/`
        return $this->render('user/notifications.html.twig', [
            // this array defines the variables passed to the template,
            // where the key is the variable name and the value is the variable value
            // (Twig recommends using snake_case variable names: 'foo_bar' instead of 'fooBar')
            'user_first_name' => $userFirstName,
            'notifications' => $userNotifications,
        ]);
    }
}

Template Naming

Symfony recommends the following for template names:

symfony はテンプレート名に以下を推奨しています:
  • Use snake case for filenames and directories (e.g. blog_posts.html.twig, admin/default_theme/blog/index.html.twig, etc.);
    ファイル名とディレクトリにはスネーク ケースを使用します (例: blog_posts.html.twig,admin/default_theme/blog/index.html.twig など)。
  • Define two extensions for filenames (e.g. index.html.twig or blog_posts.xml.twig) being the first extension (html, xml, etc.) the final format that the template will generate.
    ファイル名の 2 つの拡張子 (例: index.html.twig または blog_posts.xml.twig) を定義します。最初の拡張子 (html、xml など) は、テンプレートが生成する最終的な形式です。

Although templates usually generate HTML contents, they can generate any text-based format. That's why the two-extension convention simplifies the way templates are created and rendered for multiple formats.

テンプレートは通常 HTML コンテンツを生成しますが、任意のテキストベースの形式を生成できます。そのため、2 つの拡張子の規則により、複数の形式でテンプレートを作成してレンダリングする方法が簡素化されます。

Template Location

Templates are stored by default in the templates/ directory. When a service or controller renders the product/index.html.twig template, they are actually referring to the <your-project>/templates/product/index.html.twig file.

テンプレートはデフォルトで templates/ ディレクトリに保存されます。サービスまたはコントローラーが product/index.html.twig テンプレートをレンダリングするとき、実際には /templates/product/index.html.twig ファイルを参照しています。

The default templates directory is configurable with the twig.default_path option and you can add more template directories as explained later in this article.

デフォルトのテンプレート ディレクトリは、twig.default_path オプションで構成可能であり、この記事の後半で説明するように、さらにテンプレート ディレクトリを追加できます。

Template Variables

A common need for templates is to print the values stored in the templates passed from the controller or service. Variables usually store objects and arrays instead of strings, numbers and boolean values. That's why Twig provides quick access to complex PHP variables. Consider the following template:

テンプレートの一般的な必要性は、コントローラーまたはサービスから渡されたテンプレートに格納されている値を出力することです。変数は通常、文字列、数値、ブール値ではなく、オブジェクトと配列を格納します。これが、Twig が複雑な PHP 変数への迅速なアクセスを提供する理由です。次のテンプレートを検討してください。
1
<p>{{ user.name }} added this comment on {{ comment.publishedAt|date }}</p>

The user.name notation means that you want to display some information (name) stored in a variable (user). Is user an array or an object? Is name a property or a method? In Twig this doesn't matter.

user.name 表記は、変数 (ユーザー) に格納されている情報 (名前) を表示することを意味します。ユーザーは配列ですか、それともオブジェクトですか?name はプロパティですか、それともメソッドですか? Twig では、これは問題ではありません。

When using the foo.bar notation, Twig tries to get the value of the variable in the following order:

foo.bar 表記を使用する場合、Twig は次の順序で変数の値を取得しようとします。
  1. $foo['bar'] (array and element);
    $foo['bar'] (配列と要素);
  2. $foo->bar (object and public property);
    $foo->bar (オブジェクトとパブリック プロパティ);
  3. $foo->bar() (object and public method);
    $foo->bar() (オブジェクトと公開メソッド);
  4. $foo->getBar() (object and getter method);
    $foo->getBar() (オブジェクトと取得メソッド);
  5. $foo->isBar() (object and isser method);
    $foo->isBar() (オブジェクトと isser メソッド);
  6. $foo->hasBar() (object and hasser method);
    $foo->hasBar() (オブジェクトと hasser メソッド);
  7. If none of the above exists, use null (or throw a Twig\Error\RuntimeError exception if the strict_variables option is enabled).
    上記のいずれも存在しない場合は、null を使用します (または、strict_variables オプションが有効になっている場合は Twig\Error\RuntimeErrorexception をスローします)。

This allows to evolve your application code without having to change the template code (you can start with array variables for the application proof of concept, then move to objects with methods, etc.)

これにより、テンプレート コードを変更せずにアプリケーション コードを進化させることができます (アプリケーションの概念実証のために配列変数から始めて、メソッドなどを含むオブジェクトに移行できます)。

Linking to Pages

Instead of writing the link URLs by hand, use the path() function to generate URLs based on the routing configuration.

リンク URL を手動で記述する代わりに、path() 関数を使用して、ルーティング構成に基づいて URL を生成します。

Later, if you want to modify the URL of a particular page, all you'll need to do is change the routing configuration: the templates will automatically generate the new URL.

後で特定のページの URL を変更したい場合は、ルーティング構成を変更するだけで済みます。テンプレートによって新しい URL が自動的に生成されます。

Consider the following routing configuration:

次のルーティング構成を検討してください。
  • Attributes
    属性
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Controller/BlogController.php
namespace App\Controller;

// ...
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    #[Route('/', name: 'blog_index')]
    public function index(): Response
    {
        // ...
    }

    #[Route('/article/{slug}', name: 'blog_post')]
    public function show(string $slug): Response
    {
        // ...
    }
}

Use the path() Twig function to link to these pages and pass the route name as the first argument and the route parameters as the optional second argument:

path() Twig 関数を使用してこれらのページにリンクし、ルート名を最初の引数として、ルート パラメーターをオプションの 2 番目の引数として渡します。
1
2
3
4
5
6
7
8
9
10
11
<a href="{{ path('blog_index') }}">Homepage</a>

{# ... #}

{% for post in blog_posts %}
    <h1>
        <a href="{{ path('blog_post', {slug: post.slug}) }}">{{ post.title }}</a>
    </h1>

    <p>{{ post.excerpt }}</p>
{% endfor %}

The path() function generates relative URLs. If you need to generate absolute URLs (for example when rendering templates for emails or RSS feeds), use the url() function, which takes the same arguments as path() (e.g. <a href="{{ url('blog_index') }}"> ... </a>).

path() 関数は相対 URL を生成します。絶対 URL を生成する必要がある場合 (たとえば、電子メールや RSS フィードのテンプレートをレンダリングする場合)、url() 関数を使用します。この関数は、path() と同じ引数を取ります (例: .... )。

Linking to CSS, JavaScript and Image Assets

If a template needs to link to a static asset (e.g. an image), Symfony provides an asset() Twig function to help generate that URL. First, install the asset package:

テンプレートが静的アセット (画像など) にリンクする必要がある場合、Symfony は、その URL を生成するのに役立つ asset() Twig 関数を提供します。まず、アセット パッケージをインストールします。
1
$ composer require symfony/asset

You can now use the asset() function:

asset() 関数を使用できるようになりました。
1
2
3
4
5
6
7
8
{# the image lives at "public/images/logo.png" #}
<img src="{{ asset('images/logo.png') }}" alt="Symfony!"/>

{# the CSS file lives at "public/css/blog.css" #}
<link href="{{ asset('css/blog.css') }}" rel="stylesheet"/>

{# the JS file lives at "public/bundles/acme/js/loader.js" #}
<script src="{{ asset('bundles/acme/js/loader.js') }}"></script>

The asset() function's main purpose is to make your application more portable. If your application lives at the root of your host (e.g. https://example.com), then the rendered path should be /images/logo.png. But if your application lives in a subdirectory (e.g. https://example.com/my_app), each asset path should render with the subdirectory (e.g. /my_app/images/logo.png). The asset() function takes care of this by determining how your application is being used and generating the correct paths accordingly.

asset() 関数の主な目的は、アプリケーションの移植性を高めることです。アプリケーションがホストのルート (例: https://example.com) にある場合、レンダリングされるパスは /images/logo.png になります。ただし、アプリケーションがサブディレクトリ (例: https://example.com/my_app) にある場合、各アセット パスはサブディレクトリ (例: /my_app/images/logo.png) でレンダリングする必要があります。 asset() 関数は、アプリケーションがどのように使用されているかを判断し、それに応じて正しいパスを生成することで、これを処理します。

Tip

ヒント

The asset() function supports various cache busting techniques via the version, version_format, and json_manifest_path configuration options.

asset() 関数は、version、version_format、および json_manifest_path 構成オプションを使用して、さまざまなキャッシュ無効化手法をサポートしています。

If you need absolute URLs for assets, use the absolute_url() Twig function as follows:

アセットの絶対 URL が必要な場合は、absolute_url() Twig 関数を次のように使用します。
1
2
3
<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!"/>

<link rel="shortcut icon" href="{{ absolute_url('favicon.png') }}">

Build, Versioning & More Advanced CSS, JavaScript and Image Handling

For help building, versioning and minifying your JavaScript and CSS assets in a modern way, read about Symfony's Webpack Encore.

JavaScript および CSS アセットを最新の方法で構築、バージョン管理、縮小する方法については、Symfony の Webpack Encore を参照してください。

The App Global Variable

Symfony creates a context object that is injected into every Twig template automatically as a variable called app. It provides access to some application information:

Symfony は、すべての Twig テンプレートに app という変数として自動的に注入されるコンテキスト オブジェクトを作成します。一部のアプリケーション情報へのアクセスを提供します。
1
2
3
4
5
<p>Username: {{ app.user.username ?? 'Anonymous user' }}</p>
{% if app.debug %}
    <p>Request method: {{ app.request.method }}</p>
    <p>Application Environment: {{ app.environment }}</p>
{% endif %}

The app variable (which is an instance of AppVariable) gives you access to these variables:

app 変数 (AppVariable のインスタンス) を使用すると、次の変数にアクセスできます。
app.user
The current user object or null if the user is not authenticated.
現在のユーザー オブジェクト、またはユーザーが認証されていない場合は null。
app.request
The Request object that stores the current request data (depending on your application, this can be a sub-request or a regular request).
現在のリクエスト データを格納する Request オブジェクト (アプリケーションによっては、これがサブ リクエスタまたは通常のリクエストになる場合があります)。
app.session
The Session object that represents the current user's session or null if there is none.
現在のユーザーのセッションを表す Session オブジェクト、または存在しない場合は null。
app.flashes
An array of all the flash messages stored in the session. You can also get only the messages of some type (e.g. app.flashes('notice')).
セッションに保存されたすべてのフラッシュ メッセージの配列。特定のタイプのメッセージのみを取得することもできます (例: app.flashes('notice'))。
app.environment
The name of the current configuration environment (dev, prod, etc).
現在の構成環境の名前 (dev、prod など)。
app.debug
True if in debug mode. False otherwise.
デバッグ モードの場合は true。それ以外の場合は偽。
app.token
A TokenInterface object representing the security token.
セキュリティ トークンを表す TokenInterface オブジェクト。
app.current_route
The name of the route associated with the current request or null if no request is available (equivalent to app.request.attributes.get('_route'))
現在のリクエストに関連付けられたルートの名前、または norequest が利用可能な場合は null (app.request.attributes.get('_route') と同等)
app.current_route_parameters
An array with the parameters passed to the route of the current request or an empty array if no request is available (equivalent to app.request.attributes.get('_route_params'))
現在のリクエストのルートに渡されたパラメータを含む配列、またはリクエストが利用できない場合は空の配列 (app.request.attributes.get('_route_params') と同等)

6.2

6.2

The app.current_route and app.current_route_parameters variables were introduced in Symfony 6.2.

app.current_route および app.current_route_parameters 変数は Symfony 6.2 で導入されました。

In addition to the global app variable injected by Symfony, you can also inject variables automatically to all Twig templates.

Symfony によって注入されるグローバル アプリ変数に加えて、変数をすべての Twig テンプレートに自動的に注入することもできます。

Twig Components

Twig components are an alternative way to render templates, where each template is bound to a "component class". This makes it easier to render and re-use small template "units" - like an alert, markup for a modal, or a category sidebar.

Twig コンポーネントは、各テンプレートが「コンポーネント クラス」にバインドされている、テンプレートをレンダリングする別の方法です。これにより、アラート、モーダルのマークアップ、カテゴリ サイドバーなどの小さなテンプレート「ユニット」のレンダリングと再利用が容易になります。

For more information, see UX Twig Component.

詳細については、UX Twig コンポーネントを参照してください。

Twig components also have one other superpower: they can become "live", where they automatically update (via Ajax) as the user interacts with them. For example, when your user types into a box, your Twig component will re-render via Ajax to show a list of results!

Twig コンポーネントには、もう 1 つのスーパーパワーがあります。それらは「ライブ」になり、ユーザーが操作すると (Ajax を介して) 自動的に更新されます。たとえば、ユーザーがボックスに入力すると、Twig コンポーネントが Ajax を介して再レンダリングされ、結果のリストが表示されます!

To learn more, see UX Live Component.

詳細については、UX Live コンポーネントを参照してください。

Rendering Templates

Rendering a Template in Controllers

If your controller extends from the AbstractController, use the render() helper:

コントローラーが AbstractController から拡張されている場合は、render() ヘルパーを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// src/Controller/ProductController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    public function index(): Response
    {
        // ...

        // the `render()` method returns a `Response` object with the
        // contents created by the template
        return $this->render('product/index.html.twig', [
            'category' => '...',
            'promotions' => ['...', '...'],
        ]);

        // the `renderView()` method only returns the contents created by the
        // template, so you can use those contents later in a `Response` object
        $contents = $this->renderView('product/index.html.twig', [
            'category' => '...',
            'promotions' => ['...', '...'],
        ]);

        return new Response($contents);
    }
}

If your controller does not extend from AbstractController, you'll need to fetch services in your controller and use the render() method of the twig service.

コントローラーが AbstractController から拡張されていない場合は、コントローラーでサービスをフェッチし、twig サービスの render() メソッドを使用する必要があります。

Another option is to use the #[Template()] attribute on the controller method to define the template to render:

もう 1 つのオプションは、コントローラー メソッドで #[Template()] 属性を使用して、レンダリングするテンプレートを定義することです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Controller/ProductController.php
namespace App\Controller;

use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    #[Template('product/index.html.twig')]
    public function index()
    {
        // ...

        // when using the #[Template()] attribute, you only need to return
        // an array with the parameters to pass to the template (the attribute
        // is the one which will create and return the Response object).
        return [
            'category' => '...',
            'promotions' => ['...', '...'],
        ];
    }
}

6.2

6.2

The #[Template()] attribute was introduced in Symfony 6.2.

#[Template()] 属性は Symfony 6.2 で導入されました。

Rendering a Template in Services

Inject the twig Symfony service into your own services and use its render() method. When using service autowiring you only need to add an argument in the service constructor and type-hint it with the Environment class:

twig Symfony サービスを独自のサービスに注入し、そのrender() メソッドを使用します。サービス オートワイヤリングを使用する場合、サービス コンストラクターに引数を追加し、それを Environment クラスで型ヒントするだけで済みます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Service/SomeService.php
namespace App\Service;

use Twig\Environment;

class SomeService
{
    private $twig;

    public function __construct(Environment $twig)
    {
        $this->twig = $twig;
    }

    public function someMethod()
    {
        // ...

        $htmlContents = $this->twig->render('product/index.html.twig', [
            'category' => '...',
            'promotions' => ['...', '...'],
        ]);
    }
}

Rendering a Template in Emails

Read the docs about the mailer and Twig integration.

メーラーと Twig の統合に関するドキュメントを読んでください。

Rendering a Template Directly from a Route

Although templates are usually rendered in controllers and services, you can render static pages that don't need any variables directly from the route definition. Use the special TemplateController provided by Symfony:

テンプレートは通常、コントローラーとサービスでレンダリングされますが、ルート定義から直接変数を必要としない静的ページをレンダリングできます。 Symfony が提供する特別な TemplateController を使用します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# config/routes.yaml
acme_privacy:
    path:          /privacy
    controller:    Symfony\Bundle\FrameworkBundle\Controller\TemplateController
    defaults:
        # the path of the template to render
        template:  'static/privacy.html.twig'

        # the response status code (default: 200)
        statusCode: 200

        # special options defined by Symfony to set the page cache
        maxAge:    86400
        sharedAge: 86400

        # whether or not caching should apply for client caches only
        private: true

        # optionally you can define some arguments passed to the template
        context:
            site_name: 'ACME'
            theme: 'dark'

Checking if a Template Exists

Templates are loaded in the application using a Twig template loader, which also provides a method to check for template existence. First, get the loader:

テンプレートは、Twig テンプレート ローダーを使用してアプリケーションに読み込まれます。これは、テンプレートの存在を確認する方法も提供します。まず、ローダーを取得します。
1
2
3
4
5
6
7
8
9
10
11
use Twig\Environment;

class YourService
{
    // this code assumes that your service uses autowiring to inject dependencies
    // otherwise, inject the service called 'twig' manually
    public function __construct(Environment $twig)
    {
        $loader = $twig->getLoader();
    }
}

Then, pass the path of the Twig template to the exists() method of the loader:

次に、Twig テンプレートのパスをローダーの exists() メソッドに渡します。
1
2
3
4
if ($loader->exists('theme/layout_responsive.html.twig')) {
    // the template exists, do something
    // ...
}

Debugging Templates

Symfony provides several utilities to help you debug issues in your templates.

symfony は、テンプレートの問題をデバッグするのに役立ついくつかのユーティリティを提供します。

Linting Twig Templates

The lint:twig command checks that your Twig templates don't have any syntax errors. It's useful to run it before deploying your application to production (e.g. in your continuous integration server):

lint:twig コマンドは、Twig テンプレートに構文エラーがないことを確認します。アプリケーションを本番環境 (継続的インテグレーション サーバーなど) にデプロイする前に実行すると便利です。
1
2
3
4
5
6
7
8
9
# check all the application templates
$ php bin/console lint:twig

# you can also check directories and individual templates
$ php bin/console lint:twig templates/email/
$ php bin/console lint:twig templates/article/recent_list.html.twig

# you can also show the deprecated features used in your templates
$ php bin/console lint:twig --show-deprecations templates/email/

When running the linter inside GitHub Actions, the output is automatically adapted to the format required by GitHub, but you can force that format too:

リンターを GitHub Actions 内で実行すると、出力は GitHub で必要な形式に自動的に適応されますが、その形式を強制することもできます。
1
$ php bin/console lint:twig --format=github

Inspecting Twig Information

The debug:twig command lists all the information available about Twig (functions, filters, global variables, etc.). It's useful to check if your custom Twig extensions are working properly and also to check the Twig features added when installing packages:

debug:twig コマンドは、Twig に関するすべての情報 (関数、フィルター、グローバル変数など) を一覧表示します。カスタム Twig 拡張機能が適切に動作しているかどうかを確認したり、パッケージのインストール時に追加された Twig 機能を確認したりするのに役立ちます。
1
2
3
4
5
6
7
8
# list general information
$ php bin/console debug:twig

# filter output by any keyword
$ php bin/console debug:twig --filter=date

# pass a template path to show the physical file which will be loaded
$ php bin/console debug:twig @Twig/Exception/error.html.twig

The Dump Twig Utilities

Symfony provides a dump() function as an improved alternative to PHP's var_dump() function. This function is useful to inspect the contents of any variable and you can use it in Twig templates too.

symfony は、PHP の var_dump() 関数の改良版として dump() 関数を提供します。この関数は、任意の変数の内容を検査するのに役立ち、Twig テンプレートでも使用できます。

First, make sure that the VarDumper component is installed in the application:

まず、VarDumper コンポーネントがアプリケーションにインストールされていることを確認します。
1
$ composer require --dev symfony/var-dumper

Then, use either the {% dump %} tag or the {{ dump() }} function depending on your needs:

次に、必要に応じて {% dump %} タグまたは {{ dump() }} 関数を使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{# templates/article/recent_list.html.twig #}
{# the contents of this variable are sent to the Web Debug Toolbar
   instead of dumping them inside the page contents #}
{% dump articles %}

{% for article in articles %}
    {# the contents of this variable are dumped inside the page contents
       and they are visible on the web page #}
    {{ dump(article) }}

    <a href="/article/{{ article.slug }}">
        {{ article.title }}
    </a>
{% endfor %}

To avoid leaking sensitive information, the dump() function/tag is only available in the dev and test configuration environments. If you try to use it in the prod environment, you will see a PHP error.

機密情報の漏えいを避けるため、dump() 関数/タグは開発およびテスト構成環境でのみ使用できます。本番環境で使用しようとすると、PHP エラーが表示されます。

Reusing Template Contents

Including Templates

If certain Twig code is repeated in several templates, you can extract it into a single "template fragment" and include it in other templates. Imagine that the following code to display the user information is repeated in several places:

特定の Twig コードが複数のテンプレートで繰り返される場合、それを単一の「テンプレート フラグメント」に抽出して、他のテンプレートに含めることができます。ユーザー情報を表示する次のコードが複数の場所で繰り返されているとします。
1
2
3
4
5
6
7
{# templates/blog/index.html.twig #}

{# ... #}
<div class="user-profile">
    <img src="{{ user.profileImageUrl }}" alt="{{ user.fullName }}"/>
    <p>{{ user.fullName }} - {{ user.email }}</p>
</div>

First, create a new Twig template called blog/_user_profile.html.twig (the _ prefix is optional, but it's a convention used to better differentiate between full templates and template fragments).

最初に、blog/_user_profile.html.twig という名前の新しい Twig テンプレートを作成します (_ プレフィックスはオプションですが、完全なテンプレートとテンプレート フラグメントをより適切に区別するために使用される規則です)。

Then, remove that content from the original blog/index.html.twig template and add the following to include the template fragment:

次に、元の blog/index.html.twig テンプレートからそのコンテンツを削除し、以下を追加してテンプレート フラグメントを含めます。
1
2
3
4
{# templates/blog/index.html.twig #}

{# ... #}
{{ include('blog/_user_profile.html.twig') }}

The include() Twig function takes as argument the path of the template to include. The included template has access to all the variables of the template that includes it (use the with_context option to control this).

include() Twig 関数は、include するテンプレートのパスを引数として取ります。含まれるテンプレートは、それを含むテンプレートのすべての変数にアクセスできます (これを制御するには with_context オプションを使用します)。

You can also pass variables to the included template. This is useful for example to rename variables. Imagine that your template stores the user information in a variable called blog_post.author instead of the user variable that the template fragment expects. Use the following to rename the variable:

含まれているテンプレートに変数を渡すこともできます。これは、変数の名前を変更する場合などに便利です。テンプレートが、テンプレート フラグメントが期待するユーザー変数ではなく、blog_post.author という名前の変数にユーザー情報を保存するとします。以下を使用して、変数の名前を変更します。
1
2
3
4
{# templates/blog/index.html.twig #}

{# ... #}
{{ include('blog/_user_profile.html.twig', {user: blog_post.author}) }}

Embedding Controllers

Including template fragments is useful to reuse the same content on several pages. However, this technique is not the best solution in some cases.

テンプレート フラグメントを含めると、複数のページで同じコンテンツを再利用するのに役立ちます。ただし、この手法は場合によっては最善の解決策ではありません。

Imagine that the template fragment displays the three most recent blog articles. To do that, it needs to make a database query to get those articles. When using the include() function, you'd need to do the same database query in every page that includes the fragment. This is not very convenient.

テンプレート フラグメントが最新の 3 つのブログ記事を表示するとします。これを行うには、これらの記事を取得するためのデータベース クエリを作成する必要があります。 include() 関数を使用する場合、フラグメントを含むすべてのページで同じデータベース クエリを実行する必要があります。これはあまり便利ではありません。

A better alternative is to embed the result of executing some controller with the render() and controller() Twig functions.

より良い代替手段は、render() および controller() Twig 関数を使用してコントローラーを実行した結果を埋め込むことです。

First, create the controller that renders a certain number of recent articles:

最初に、特定の数の最近の記事をレンダリングするコントローラーを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
// ...

class BlogController extends AbstractController
{
    public function recentArticles(int $max = 3): Response
    {
        // get the recent articles somehow (e.g. making a database query)
        $articles = ['...', '...', '...'];

        return $this->render('blog/_recent_articles.html.twig', [
            'articles' => $articles
        ]);
    }
}

Then, create the blog/_recent_articles.html.twig template fragment (the _ prefix in the template name is optional, but it's a convention used to better differentiate between full templates and template fragments):

次に、blog/_recent_articles.html.twig テンプレート フラグメントを作成します (テンプレート名の _ 接頭辞はオプションですが、完全なテンプレートとテンプレート フラグメントをより適切に区別するために使用される規則です):
1
2
3
4
5
6
{# templates/blog/_recent_articles.html.twig #}
{% for article in articles %}
    <a href="{{ path('blog_show', {slug: article.slug}) }}">
        {{ article.title }}
    </a>
{% endfor %}

Now you can call to this controller from any template to embed its result:

これで、任意のテンプレートからこのコントローラーを呼び出して、その結果を埋め込むことができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{# templates/base.html.twig #}

{# ... #}
<div id="sidebar">
    {# if the controller is associated with a route, use the path() or url() functions #}
    {{ render(path('latest_articles', {max: 3})) }}
    {{ render(url('latest_articles', {max: 3})) }}

    {# if you don't want to expose the controller with a public URL,
       use the controller() function to define the controller to execute #}
    {{ render(controller(
        'App\\Controller\\BlogController::recentArticles', {max: 3}
    )) }}
</div>

When using the controller() function, controllers are not accessed using a regular Symfony route but through a special URL used exclusively to serve those template fragments. Configure that special URL in the fragments option:

controller() 関数を使用する場合、通常の Symfony ルートを使用してコントローラーにアクセスするのではなく、それらのテンプレート フラグメントを提供するためだけに使用される特別な URL を介してアクセスします。フラグメント オプションでその特別な URL を構成します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/framework.yaml
framework:
    # ...
    fragments: { path: /_fragment }

Caution

注意

Embedding controllers requires making requests to those controllers and rendering some templates as result. This can have a significant impact on the application performance if you embed lots of controllers. If possible, cache the template fragment.

コントローラーを埋め込むには、それらのコントローラーにリクエストを行い、結果としていくつかのテンプレートをレンダリングする必要があります。これは、多数のコントローラーを組み込む場合、アプリケーションのパフォーマンスに大きな影響を与える可能性があります。可能であれば、テンプレート フラグメントをキャッシュします。

See also

こちらもご覧ください

Templates can also embed contents asynchronously with the hinclude.js JavaScript library.

テンプレートは、hinclude.js JavaScript ライブラリを使用してコンテンツを非同期的に埋め込むこともできます。

Template Inheritance and Layouts

As your application grows you'll find more and more repeated elements between pages, such as headers, footers, sidebars, etc. Including templates and embedding controllers can help, but when pages share a common structure, it's better to use inheritance.

アプリケーションが成長するにつれて、ヘッダー、フッター、サイドバーなど、ページ間で繰り返される要素がますます多くなることがわかります。テンプレートを含めたり、コントローラーを埋め込んだりすることは役に立ちますが、ページが共通の構造を共有する場合は、継承を使用することをお勧めします。

The concept of Twig template inheritance is similar to PHP class inheritance. You define a parent template that other templates can extend from and child templates can override parts of the parent template.

Twig テンプレートの継承の概念は、PHP クラスの継承に似ています。他のテンプレートから拡張できる親テンプレートを定義すると、子テンプレートは親テンプレートの一部をオーバーライドできます。

Symfony recommends the following three-level template inheritance for medium and complex applications:

Symfony は、中規模および複雑なアプリケーションに対して、次の 3 レベルのテンプレート継承を推奨しています。
  • templates/base.html.twig, defines the common elements of all application templates, such as <head>, <header>, <footer>, etc.;
    templates/base.html.twig は、 、 、 など、すべてのアプリケーション テンプレートの共通要素を定義します。
  • templates/layout.html.twig, extends from base.html.twig and defines the content structure used in all or most of the pages, such as a two-column content + sidebar layout. Some sections of the application can define their own layouts (e.g. templates/blog/layout.html.twig);
    templates/layout.html.twig は、base.html.twig から拡張され、2 列のコンテンツ + サイドバー レイアウトなど、すべてまたはほとんどのページで使用されるコンテンツ構造を定義します。アプリケーションの一部のセクションでは、独自のレイアウトを定義できます (例: templates/blog/layout.html.twig)。
  • templates/*.html.twig, the application pages which extend from the main layout.html.twig template or any other section layout.
    templates/*.html.twig、mainlayout.html.twig テンプレートまたはその他のセクション レイアウトから拡張されたアプリケーション ページ。

In practice, the base.html.twig template would look like this:

実際には、base.html.twig テンプレートは次のようになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}My Application{% endblock %}</title>
        {% block stylesheets %}
            <link rel="stylesheet" type="text/css" href="/css/base.css"/>
        {% endblock %}
    </head>
    <body>
        {% block body %}
            <div id="sidebar">
                {% block sidebar %}
                    <ul>
                        <li><a href="{{ path('homepage') }}">Home</a></li>
                        <li><a href="{{ path('blog_index') }}">Blog</a></li>
                    </ul>
                {% endblock %}
            </div>

            <div id="content">
                {% block content %}{% endblock %}
            </div>
        {% endblock %}
    </body>
</html>

The Twig block tag defines the page sections that can be overridden in the child templates. They can be empty, like the content block or define a default content, like the title block, which is displayed when child templates don't override them.

Twig ブロック タグは、子テンプレートでオーバーライドできるページ セクションを定義します。コンテンツ ブロックのように空にすることも、タイトル ブロックのように defaultcontent を定義することもできます。これは、子テンプレートがそれらをオーバーライドしない場合に表示されます。

The blog/layout.html.twig template could be like this:

blog/layout.html.twig テンプレートは次のようになります。
1
2
3
4
5
6
7
8
{# templates/blog/layout.html.twig #}
{% extends 'base.html.twig' %}

{% block content %}
    <h1>Blog</h1>

    {% block page_contents %}{% endblock %}
{% endblock %}

The template extends from base.html.twig and only defines the contents of the content block. The rest of the parent template blocks will display their default contents. However, they can be overridden by the third-level inheritance template, such as blog/index.html.twig, which displays the blog index:

テンプレートは base.html.twig から拡張され、コンテンツ ブロックのコンテンツのみを定義します。親テンプレート ブロックの残りの部分には、デフォルトのコンテンツが表示されます。ただし、ブログのインデックスを表示する blog/index.html.twig などの第 3 レベルの継承テンプレートによってオーバーライドできます。
1
2
3
4
5
6
7
8
9
10
11
{# templates/blog/index.html.twig #}
{% extends 'blog/layout.html.twig' %}

{% block title %}Blog Index{% endblock %}

{% block page_contents %}
    {% for article in articles %}
        <h2>{{ article.title }}</h2>
        <p>{{ article.body }}</p>
    {% endfor %}
{% endblock %}

This template extends from the second-level template (blog/layout.html.twig) but overrides blocks of different parent templates: page_contents from blog/layout.html.twig and title from base.html.twig.

このテンプレートは第 2 レベルのテンプレート (blog/layout.html.twig) から拡張されていますが、別の親テンプレートのブロックをオーバーライドします: blog/layout.html.twig の page_contents と base.html.twig の title。

When you render the blog/index.html.twig template, Symfony uses three different templates to create the final contents. This inheritance mechanism boosts your productivity because each template includes only its unique contents and leaves the repeated contents and HTML structure to some parent templates.

blog/index.html.twig テンプレートをレンダリングすると、Symfony は 3 つの異なるテンプレートを使用して最終的なコンテンツを作成します。この継承メカニズムにより、各テンプレートには固有のコンテンツのみが含まれ、繰り返されるコンテンツと HTML 構造は一部の親テンプレートに残されるため、生産性が向上します。

Caution

注意

When using extends, a child template is forbidden to define template parts outside of a block. The following code throws a SyntaxError:

extends を使用する場合、子テンプレートはブロックの外側で templateparts を定義することを禁じられています。次のコードは SyntaxError をスローします。
1
2
3
4
5
6
7
8
{# app/Resources/views/blog/index.html.twig #}
{% extends 'base.html.twig' %}

{# the line below is not captured by a "block" tag #}
<div class="alert">Some Alert</div>

{# the following is valid #}
{% block content %}My cool blog posts{% endblock %}

Read the Twig template inheritance docs to learn more about how to reuse parent block contents when overriding templates and other advanced features.

テンプレートやその他の高度な機能をオーバーライドするときに親ブロックの内容を再利用する方法について詳しくは、Twig テンプレートの継承に関するドキュメントをお読みください。

Output Escaping

Imagine that your template includes the Hello {{ name }} code to display the user name. If a malicious user sets <script>alert('hello!')</script> as their name and you output that value unchanged, the application will display a JavaScript popup window.

This is known as a Cross-Site Scripting (XSS) attack. And while the previous example seems harmless, the attacker could write more advanced JavaScript code to perform malicious actions.

これは、クロスサイト スクリプティング (XSS) 攻撃として知られています。前の例は無害に見えますが、攻撃者はより高度な JavaScript コードを記述して、悪意のあるアクションを実行する可能性があります。

To prevent this attack, use "output escaping" to transform the characters which have special meaning (e.g. replace < by the &lt; HTML entity). Symfony applications are safe by default because they perform automatic output escaping:

この攻撃を防ぐには、「出力エスケープ」を使用して、特別な意味を持つ文字を変換します (例: < を < HTML エンティティに置き換える)。Symfony アプリケーションは、自動出力エスケープを実行するため、デフォルトで安全です:
1
2
3
<p>Hello {{ name }}</p>
{# if 'name' is '<script>alert('hello!')</script>', Twig will output this:
   '<p>Hello &lt;script&gt;alert(&#39;hello!&#39;)&lt;/script&gt;</p>' #}

If you are rendering a variable that is trusted and contains HTML contents, use the Twig raw filter to disable the output escaping for that variable:

信頼され、HTML コンテンツを含む変数をレンダリングする場合は、Twig raw フィルターを使用して、その変数の出力エスケープを無効にします。
1
2
3
<h1>{{ product.title|raw }}</h1>
{# if 'product.title' is 'Lorem <strong>Ipsum</strong>', Twig will output
   exactly that instead of 'Lorem &lt;strong&gt;Ipsum&lt;/strong&gt;' #}

Read the Twig output escaping docs to learn more about how to disable output escaping for a block or even an entire template.

ブロックまたはテンプレート全体の出力エスケープを無効にする方法の詳細については、Twig 出力エスケープ ドキュメントを参照してください。

Template Namespaces

Although most applications store their templates in the default templates/ directory, you may need to store some or all of them in different directories. Use the twig.paths option to configure those extra directories. Each path is defined as a key: value pair where the key is the template directory and the value is the Twig namespace, which is explained later:

ほとんどのアプリケーションはテンプレートをデフォルトのテンプレート/ディレクトリに保存しますが、それらの一部またはすべてを別のディレクトリに保存する必要がある場合があります。これらの追加ディレクトリを構成するには、twig.paths オプションを使用します。各パスは、キーと値のペアとして定義されます。キーはテンプレート ディレクトリで、値は後で説明する Twig 名前空間です。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/packages/twig.yaml
twig:
    # ...
    paths:
        # directories are relative to the project root dir (but you
        # can also use absolute directories)
        'email/default/templates': ~
        'backend/templates': ~

When rendering a template, Symfony looks for it first in the twig.paths directories that don't define a namespace and then falls back to the default template directory (usually, templates/).

テンプレートをレンダリングするとき、Symfony は最初に名前空間を定義していない twig.paths ディレクトリでそれを探し、次に defaulttemplate ディレクトリ (通常は templates/) にフォールバックします。

Using the above configuration, if your application renders for example the layout.html.twig template, Symfony will first look for email/default/templates/layout.html.twig and backend/templates/layout.html.twig. If any of those templates exists, Symfony will use it instead of using templates/layout.html.twig, which is probably the template you wanted to use.

上記の構成を使用して、アプリケーションがたとえばlayout.html.twig テンプレートをレンダリングする場合、Symfony は最初に formail/default/templates/layout.html.twig と backend/templates/layout.html.twig を探します。これらのテンプレートのいずれかが存在する場合、Symfony は、おそらくあなたが使いたかったテンプレートである usingtemplates/layout.html.twig の代わりにそれを使用します。

Twig solves this problem with namespaces, which group several templates under a logic name unrelated to their actual location. Update the previous configuration to define a namespace for each template directory:

Twig はこの問題を名前空間で解決します。名前空間は、実際の場所とは関係のないロジック名でいくつかのテンプレートをグループ化します。前の構成を更新して、各テンプレート ディレクトリの名前空間を定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
# config/packages/twig.yaml
twig:
    # ...
    paths:
        'email/default/templates': 'email'
        'backend/templates': 'admin'

Now, if you render the layout.html.twig template, Symfony will render the templates/layout.html.twig file. Use the special syntax @ + namespace to refer to the other namespaced templates (e.g. @email/layout.html.twig and @admin/layout.html.twig).

ここで、layout.html.twig テンプレートをレンダリングすると、Symfony は templates/layout.html.twig ファイルをレンダリングします。特別な構文 @ + namespace を使用して、他の名前空間テンプレートを参照します (例: @email/layout.html.twig および @admin/layout.html.twig)。

Note

ノート

A single Twig namespace can be associated with more than one template directory. In that case, the order in which paths are added is important because Twig will start looking for templates from the first defined path.

1 つの Twig 名前空間を複数のテンプレート ディレクトリに関連付けることができます。その場合、Twig は最初に定義されたパスからテンプレートを探し始めるため、パスが追加される順序は重要です。

Bundle Templates

If you install packages/bundles in your application, they may include their own Twig templates (in the Resources/views/ directory of each bundle). To avoid messing with your own templates, Symfony adds bundle templates under an automatic namespace created after the bundle name.

アプリケーションにパッケージ/バンドルをインストールすると、独自の Twig テンプレートが含まれる場合があります (各バンドルの Resources/views/ ディレクトリにあります)。独自のテンプレートをいじるのを避けるために、Symfony はバンドル名の後に作成される自動名前空間の下に bundletemplates を追加します。

For example, the templates of a bundle called AcmeFooBundle are available under the AcmeFoo namespace. If this bundle includes the template <your-project>/vendor/acmefoo-bundle/Resources/views/user/profile.html.twig, you can refer to it as @AcmeFoo/user/profile.html.twig.

たとえば、AcmeFooBundle というバンドルのテンプレートは、AcmeFoo 名前空間で利用できます。このバンドルに template/vendor/acmefoo-bundle/Resources/views/user/profile.html.twig が含まれている場合は、@AcmeFoo/user/profile.html.twig として参照できます。

Tip

ヒント

You can also override bundle templates in case you want to change some parts of the original bundle templates.

元のバンドル テンプレートの一部を変更する場合は、バンドル テンプレートを上書きすることもできます。

Learn more