slogan of website

Twig coding standards

https://www.drupal.org/docs/develop/coding-standards/twig-coding-standa…

 

Note: Changes to Drupal coding standards are proposed and discussed in issues in the Coding Standards project.

The majority of Twig coding standards can be found on the Twig website along with Twig documentation. Items on this page (below) are useful when understanding how to write Twig code for Drupal.

Also see our preprocess function documentation standards.

The DocBlock

A docblock at the top of a Twig template should be identical to the docblock at the top of a PHPTemplate file (see Drupal API documentation standards for theme template files), with the entire docblock wrapped in the twig comment markers, {# and #}.

Twig template docblocks should only include @ingroup themeable if the template is providing the default themeable output. For themes overriding default output the @ingroup themeable line should not be included.

{#
/**
 * @file
 * Default theme implementation for a region.
 *
 * Available variables:
 * - content: The content for this region, typically blocks.
 * - attributes: Remaining HTML attributes for the element, including:
 *   - class: HTML classes that can be used to style contextually through CSS.
 *
 * @see template_preprocess_region()
 *
 * @ingroup themeable
 */
#}

이미지가 제거되었습니다.이미지가 제거되었습니다.

Variables in the DocBlock

Variables in a twig template docblock should be referenced by name. They will not be surrounded by the Twig print indicators {{ and }} and will not be preceded by the PHP variable indicator $. There should be no separate "Other variables" section.

A good rule of thumb for converting docs at the top of templates is as follows

  • Start from what we had in Drupal 7.
  • If you see a section of variables titled "Other variables", delete the title and the extra line above.
  • if/when variables get deleted from preprocess, delete them from the Twig docs.
  • if/when a variable looks useful and is not in the Twig docs, document it.
  • if/when you can improve, or reduce the verbosity of the D7 docs, do it.

Variable definitions in the DocBlock

Variable definitions should not include any information about the type of variable (array, object, string) since people working in template files should not have to care about type. Everything that can be printed in a Twig template will end up printing as a string.

Variables referenced inline in the DocBlock

When a variable is referenced in-line in paragraphs the variable name should be wrapped in single quotes, as follows:

 * Field variables: for each field instance attached to the node a corresponding
 * variable is defined; for example, 'node.body' becomes 'body'. When needing to
 * access a field's raw values, developers/themers are strongly encouraged to
 * use these variables. Otherwise they will have to explicitly specify the
 * desired field language; for example, 'node.body.en', thus overriding any
 * language negotiation rule that was previously applied.

이미지가 제거되었습니다.이미지가 제거되었습니다.

Expressions

Twig expressions are very similar to regular PHP expressions, and are most commonly used in Drupal to check if variables are available for printing, for looping, and for setting new variables within templates.

Expressions: Checking if variables are available for printing

Sometimes you only want to print a markup container if there is a value to be printed inside it. The way we do this in Drupal is as follows:

{% if foo %}
  <div>{{ foo }}</div>
{% endif %}

이미지가 제거되었습니다.이미지가 제거되었습니다.

You do not need to use 'is defined' after your variable to determine if it is available.

There are sometimes issues with using this method for determining emptiness. Discussion and workarounds on https://www.drupal.org/project/drupal/issues/953034 .

Expressions: looping

Twig uses for loops, and in Drupal we are used to using foreach loops.

If you don't need array keys, your loop should look like this:

{% for item in navigation %}
  <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}

이미지가 제거되었습니다.이미지가 제거되었습니다.

If you need both a keys and values, your loop syntax will look like this:

{% for key, value in items %}
  <div class="{{ key }}">{{ value }}</div>
{% endfor %}

이미지가 제거되었습니다.이미지가 제거되었습니다.

Expressions: setting variables

Expressions can also be used for setting variables directly in template files.

{% set list = ['Alice', 'Bob'] %}
{% set text = ':person is a Twig fan'|t({':person': list[0] }) %}

이미지가 제거되었습니다.이미지가 제거되었습니다.

HTML attributes

HTML attributes in Drupal 8 are drillable. This means that you can print all of them at once by printing {{ attributes }} or you can print each attribute individually, like so:

<div id="{{ attributes.id }}" class="{{ attributes.class }}"{{ attributes }}>
  {{ content }}
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

If you choose to print out individual attributes within a HTML tag, you should still include the complete {{ attributes }} at the end, so that attributes added by modules are still also printed.

In Drupal core, we will print only the class attribute specially, all the others will be printed as part of {{ attributes }}. The reason for this is that it needs to be very easy for front end developers to be able to add a class, anywhere. By printing the class="" attribute directly in the template file, people familiar with HTML and CSS will see and recognize the correct way to add a class without needing to read documentation, or understand that Drupal has a preprocess layer.

<div class="{{ attributes.class }}"{{ attributes }}>
  {{ content }}
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

More advanced theme developers may choose to add their classes in preprocess and remove these separately printed classes from templates. This will prevent the empty class="" attribute from being printed when an element has no classes.

<div{{ attributes }}>
  {{ content }}
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

Whitespace Control
 

---
Outdated. This section needs to be updated. 
@see https://www.drupal.org/project/drupal/issues/3094850
@see https://symfony.com/blog/better-white-space-control-in-twig-templates
---

There are two whitespace control features in Twig: the spaceless filter (used with the apply tag) and the dash character (-). The spaceless filter removes any whitespace between HTML and Twig tags, while the dash character -, when set on the inside of Twig tags, removes any whitespace surrounding that tag in the direction of the dash. The spaceless filter is more general and its effects are "inward" facing. The dash is more precise and its effects are "outward" facing.

The spaceless filter

The spaceless filter (used with the apply tag) is helpful for removing all non-text whitespace between several tags and statements. It is Drupal core's preferred method for controlling whitespace in blocks of code. However each use introduces one extra level of indentation.

(The spaceless filter can also be used with a pipe | to remove whitespace between HTML tags.)

The "dash" (-) whitespace modifier

The - dash modifier is a more precise (and sometimes confusing) way of selectively removing whitespace from around one or more sides of a tag. We do not need to use the - dash modifier very often. Code is usually easier to read when using the spaceless filter.

Whitespace control features will generally be used sparingly in core.

Example usage:

{% if block.show %}
<div class="admin-panel">
  {% apply spaceless %}
    {% if block.title %}
      {{ title_prefix }}
      <h3>{{ block.title }}</h3>
      {{ title_suffix }}
    {% endif %}
  {% endapply %}

  {% if block.content %}
    <div class="body">{{ block.content }}</div>
  {% elseif block.description %}
    <div class="description">{{ block.description }}</div>
  {% endif %}
</div>
{% endif %}

이미지가 제거되었습니다.이미지가 제거되었습니다.

The indented markup should appear as follows:

<div class="admin-panel">
  <h3>Title</h3>
  <div class="body">Content</div>
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

We may revisit this decision about use of whitespace controllers later, after converting everything to twig and examining our resulting Twig code, and the markup that is produced. For now, our main goal is not to confuse people who are new to Twig, and that may mean using Twig's built-in tools less frequently.

DOs and DON'Ts for using spaces and whitespace controllers and spaceless filters in Twig templates:

Examples:

  • If you can remove the whitespace legibly, do so.
    • Remove the space before attributes <div{{ attributes }}>
    • Never remove spaces or add a whitespace controllers around classes class="no {{ attributes.class }} no"
  • If you can't remove the whitespace legibly, consider using the spaceless filter. Examples:
    • Apply the spaceless filter around commands ({% if foo %} ...)
    • Apply the spaceless filter around comments {# this is a comment #}

Caveat regarding newlines at the end of files

Git requires that twig files need a newline at the end of the file. This can break tests or may be not wanted in your template output.
The recommendation to change this:

  • Change the test if it needs to pass.
  • Or add a twig template tag to the end.

If you're not in Drupal Core contrib you can just remove the newline character.

Filters

Some of the most common Drupal functions like t and url have been made available in your twig templates as filters. Filters are triggered by using the pipe character | .

This is how you would use the t() function as a filter in a twig template.

<div class="preview-image-wrapper">
  {{ 'Original'|t }} 
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

See also: spaceless filter.

Please do not put spaces on either side of the pipe.

Comments

All comments will be surrounded by the twig comment indicator {# and #}.

Comments that span one line will have the comment indicators on the same line as the comment.

<div class="image-widget-data">
  {# Render widget data without the image preview that was output already. #}
  {{ data|without('preview') }}
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

Comments that span more than one line will have the comment indicators on separate lines. Comments should be wrapped so the line is less than 80 characters.

{#
  This is a very long comment. It spans more than one line. This is a very
  long comment. It spans more than one line. This is a very long comment. It
  spans more than one line. This is a very long comment. It spans more than
  one line. 
#}
<div class="{{ attributes.class }}"{{ attributes }}>
  {{ content }}
</div>

이미지가 제거되었습니다.이미지가 제거되었습니다.

태그

댓글

https://www.drupal.org/docs/contributed-modules/twig-tweak-2x/twig-twea…

Twig Tweak's drupal_view() method provide's access to embed views within any Twig code, including dynamically from within each row of another view. This feature provides an alternate method to accomplish the nesting provided by the Views field view module. 

The most basic syntax for Twig Tweak's view embed simply specifies the view and the machine name you wish to embed, as follows:

{{ drupal_view('who_s_new', 'block_1') }}

You can, however, also specify additional parameters which map to contextual filters you have configured in your view.

{{ drupal_view('who_s_new', 'block_1', arg_1, arg_2, arg_3) }}

Nested View Example

There are a lot of cases in views where you want to embed a list inside of each row. For example, when you have a list of product categories (taxonomy terms) and for each category, you want to list the 3 newest products. In this example, assume your content type is 'product', and has a reference field to a taxonomy named 'product categories'. 

Step1: Create your child view

Create a view of the content of type 'product', and choose to create a block displaying an unformatted list of teasers, with 3 items per block. In this example, we'll use a view name of 'products_by_category'.  Once the view is created, choose advanced and add a relationship to the taxonomy term that references 'product categories', and choose to require the relationship.  Next, choose to add a "Contextual Filter" for "Term ID", and choose an action for when the filter value is not available (e.g. display contents of no results found).  Set your desired sort and save your view.

Step 2: Create your parent view
Create a view of taxonomy terms of type 'product categories', and choose to create a page which displays an unformatted list of fields.  Once this is created, you should see the preview showing all of the product categories.  Choose to add a field of type "Term ID", and choose "Exclude from display"; this is necessary to make the term id available to the next field which uses Twig Tweak.  Now, choose to add a field of type "Custom text" from the "Global" category.  Inside that field, enter the Twig Tweak call to display the child view we created above, passing the tid as a contextual filter, as such:

{{ drupal_view('products_by_category', 'block_1', tid) }}

You should now save your view, and be able to access the URL you assigned and see a list of product categories, each followed by the three most recent products within each.

This example can be applied to any nested view scenario, including multiple-levels of nesting. 

Check if View has Results

{% if drupal_view_result('related', 'block_1') is not empty %}
  {{ drupal_view('related', 'block_1') }}
{% endif %}
X