Browse Source

Improve documentation

merge-requests/4/head
Chi 5 years ago
parent
commit
495f34f162
  1. 16
      phpcs.xml
  2. 553
      src/TwigExtension.php

16
phpcs.xml

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<ruleset name="Twig Tweak">
<description>PHP CodeSniffer configuration for Twig Tweak module.</description>
<arg name="extensions" value="php, module, yml"/>
<rule ref="Drupal"/>
<rule ref="DrupalPractice">
<!-- Dependencies are not injected for performance reason. -->
<exclude name="DrupalPractice.Objects.GlobalDrupal.GlobalDrupal"/>
<!-- False positives. -->
<exclude name="Drupal.Commenting.InlineComment.Empty"/>
<!-- The module does not provide change records. -->
<exclude name="Drupal.Semantics.FunctionTriggerError.TriggerErrorTextLayoutRelaxed"/>
<!-- Code examples have rather long lines. -->
<exclude name="Drupal.Files.LineLength.TooLong"/>
</rule>
</ruleset>

553
src/TwigExtension.php

@ -40,27 +40,204 @@ class TwigExtension extends \Twig_Extension {
public function getFunctions() {
$context_options = ['needs_context' => TRUE];
$all_options = ['needs_environment' => TRUE, 'needs_context' => TRUE];
return [
// - Drupal View -
//
// @code
// {{ drupal_view('who_s_new', 'block_1') }}
// @endcode
new \Twig_SimpleFunction('drupal_view', 'views_embed_view'),
// - Drupal View Result -
//
// @code
// {{ drupal_view('who_s_new', 'block_1') }}
// @endcode
new \Twig_SimpleFunction('drupal_view_result', 'views_get_view_result'),
// - Drupal Block -
//
// In order to list all registered plugin IDs fetch them with block plugin
// manager. With Drush it can be done like follows:
// @code
// drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefinitions()));"
// @endcode
//
// @code
// {# Print block using default configuration. #}
// {{ drupal_block('system_branding_block') }}
//
// {# Print block using custom configuration. #}
// {{ drupal_block('system_branding_block', {label: 'Branding', use_site_name: false})
//
// {# Bypass block.html.twig theming. #}
// {{ drupal_block('system_branding_block', wrapper=false) }}
// @endcode
//
// @see https://www.drupal.org/node/2964457#block-plugin
new \Twig_SimpleFunction('drupal_block', [$this, 'drupalBlock']),
// - Drupal Region -
//
// @code
// {# Print 'Sidebar First' region of the default site theme. #}
// {{ drupal_region('sidebar_first') }}
//
// {# Print 'Sidebar First' region of Bartik theme. #}
// {{ drupal_region('sidebar_first', 'bartik') }}
// @endcode
new \Twig_SimpleFunction('drupal_region', [$this, 'drupalRegion']),
// - Drupal Entity -
//
// @code
// {# Print a content block which ID is 1. #}
// {{ drupal_entity('block_content', 1) }}
//
// {# Print a node's teaser. #}
// {{ drupal_entity('node', 123, 'teaser') }}
//
// {# Print Branding block which was previously disabled on #}
// {# admin/structure/block page. #}
// {{ drupal_entity('block', 'bartik_branding', check_access=false) }}
// @endcode
new \Twig_SimpleFunction('drupal_entity', [$this, 'drupalEntity']),
// - Drupal Entity Form -
//
// @code
// {# Print edit form for node 1. #}
// {{ drupal_entity_form('node', 1) }}
//
// {# Print add form for Article content type. #}
// {{ drupal_entity_form('node', values={type: 'article'}) }}
//
// {# Print user register form. #}
// {{ drupal_entity_form('user', NULL, 'register', check_access=false) }}
// @endcode
new \Twig_SimpleFunction('drupal_entity_form', [$this, 'drupalEntityForm']),
// - Drupal Field -
//
// @code
// {{ drupal_field('field_image', 'node', 1) }}
// {{ drupal_field('field_image', 'node', 1, 'teaser') }}
// {{ drupal_field('field_image', 'node', 1, {type: 'image_url', settings: {image_style: 'large'}}) }}
// @endcode
new \Twig_SimpleFunction('drupal_field', [$this, 'drupalField']),
// - Drupal Menu -
//
// @code
// {{ drupal_menu('main') }}
// @endcode
new \Twig_SimpleFunction('drupal_menu', [$this, 'drupalMenu']),
// - Drupal Form -
//
// @code
// {{ drupal_form('Drupal\\search\\Form\\SearchBlockForm') }}
// @endcode
new \Twig_SimpleFunction('drupal_form', [$this, 'drupalForm']),
// - Drupal Image -
//
// @code
// {# Render image specified by file ID. #}
// {{ drupal_image(123) }}
//
// {# Render image specified by file UUID. #}
// {{ drupal_image('9bb27144-e6b2-4847-bd24-adcc59613ec0') }}
//
// {# Render image specified by file URI. #}
// {{ drupal_image('public://ocean.jpg') }}
//
// {# Render image using 'thumbnail' image style and custom attributes. #}
// {{ drupal_image('public://ocean.jpg', 'thumbnail', {alt: 'The alternative text'|t, title: 'The title text'|t}) }}
//
// {# Render responsive image. #}
// {{ drupal_image('public://ocean.jpg', 'wide', responsive=true) }}
// @endcode
new \Twig_SimpleFunction('drupal_image', [$this, 'drupalImage']),
// - Drupal Token -
//
// @code
// {{ drupal_token('site:name') }}
// @endcode
new \Twig_SimpleFunction('drupal_token', [$this, 'drupalToken']),
// - Drupal Config -
//
// @code
// {{ drupal_config('system.site', 'name') }}
// @endcode
new \Twig_SimpleFunction('drupal_config', [$this, 'drupalConfig']),
// - Drupal Dump -
//
// @code
// {# Basic usage. #}
// {{ drupal_dump(var) }}
//
// {# Same as above but shorter. #}
// {{ dd(var) }}
//
// {# Dump all available variables for the current template. #}
// {{ dd() }}
// @endcode
new \Twig_SimpleFunction('drupal_dump', [$this, 'drupalDump'], $context_options),
new \Twig_SimpleFunction('dd', [$this, 'drupalDump'], $context_options),
// - Drupal Title -
new \Twig_SimpleFunction('drupal_title', [$this, 'drupalTitle']),
// - Drupal URL -
//
// @code
// {# Basic usage. #}
// {{ drupal_url('node/1) }}
//
// {# Complex URL. #}
// {{ drupal_url('node/1', {query: {foo: 'bar'}, fragment: 'example', absolute: true}) }}
// @endcode
new \Twig_SimpleFunction('drupal_url', [$this, 'drupalUrl']),
// - Drupal Link -
//
// @code
// {# It supports the same options as drupal_url(), plus attributes. #}
// {{ drupal_link('View'|t, 'node/1', {attributes: {target: '_blank'}}) }}
//
// {# This link will only be shown for privileged users. #}
// {{ drupal_link('Example'|t, '/admin', check_access=true) }}
// @endcode
new \Twig_SimpleFunction('drupal_link', [$this, 'drupalLink']),
// - Drupal Messages -
new \Twig_SimpleFunction('drupal_messages', [$this, 'drupalMessages']),
// - Drupal Breadcrumb -
new \Twig_SimpleFunction('drupal_breadcrumb', [$this, 'drupalBreadcrumb']),
// - Drupal Breakpoint -
new \Twig_SimpleFunction('drupal_breakpoint', [$this, 'drupalBreakpoint'], $all_options),
// - Contextual Links -
//
// @code
// {# Basic usage. #}
// <div class="contextual-region">
// {{ contextual_links('entity.view.edit_form:view=frontpage&display_id=feed_1') }}
// {{ drupal_view('frontpage') }}
// </div>
// {# Multiple links. #}
// <div class="contextual-region">
// {{ contextual_links('node:node=123|block_content:block_content=123') }}
// {{ content }}
// </div>
// @endcode
new \Twig_SimpleFunction('contextual_links', [$this, 'contextualLinks']),
];
}
@ -69,20 +246,138 @@ class TwigExtension extends \Twig_Extension {
* {@inheritdoc}
*/
public function getFilters() {
$filters = [
// - Token Replace -
//
// @code
// {# Basic usage. #}
// {{ '<h1>[site:name]</h1><div>[site:slogan]</div>'|token_replace }}
//
// {# This is more suited to large markup (requires Twig >= 1.41). #}
// {% apply token_replace %}
// <h1>[site:name]</h1>
// <div>[site:slogan]</div>
// {% endapply %}
// @endcode
new \Twig_SimpleFilter('token_replace', [$this, 'tokenReplaceFilter']),
// - Preg Replace -
//
// @code
// {{ 'Drupal - community plumbing!'|preg_replace('/(Drupal)/', '<b>$1</b>') }}
// @endcode
//
// For simple string interpolation consider using built-in 'replace' or
// 'format' Twig filters.
new \Twig_SimpleFilter('preg_replace', [$this, 'pregReplaceFilter']),
// - Image Style -
//
// @code
// {{ 'public://images/ocean.jpg'|image_style('thumbnail') }}
// @endcode
new \Twig_SimpleFilter('image_style', [$this, 'imageStyle']),
// - Transliterate -
//
// @code
// {{ 'Привет!'|transliterate }}
// @endcod
new \Twig_SimpleFilter('transliterate', [$this, 'transliterate']),
// - Check Markup -
//
// @code
// {{ '<b>bold</b> <strong>strong</strong>'|check_markup('restricted_html') }}
// @endcode
new \Twig_SimpleFilter('check_markup', [$this, 'checkMarkup']),
// - Truncate -
//
// @code
// {{ 'Some long text'|truncate(10, true) }}
// @endcode
new \Twig_SimpleFilter('truncate', [$this, 'truncate']),
// - View -
//
// @code
// {# Do not put this into node.html.twig template to avoid recursion. #}
// {{ node|view }}
// {{ node|view('teaser') }}
//
// {{ node.field_image|view }}
// {{ node.field_image[0]|view }}
// {{ node.field_image|view('teaser') }}
// {{ node.field_image|view({settings: {image_style: 'thumbnail'}}) }}
// @endcode
new \Twig_SimpleFilter('view', [$this, 'view']),
// - With -
//
// @code
// {# Set top level value. #}
// {{ content.field_image|with('#title', 'Photo'|t) }}
//
// {# Set nested value. #}
// {{ content|with(['field_image', '#title'], 'Photo'|t) }}
// @endcode
new \Twig_SimpleFilter('with', [$this, 'with']),
// - Children -
//
// @code
// <ul>
// {% for tag in content.field_tags|children %}
// <li>{{ tag }}</li>
// {% endfor %}
// </ul>
// @endcode
new \Twig_SimpleFilter('children', [$this, 'children']),
// - File URL -
//
// For string arguments it works similar to core file_url() Twig function.
// @code
// {{ 'public://sea.jpg'|file_url }}
// @endcode
//
// When field item list passed the URL will be extracted from the first
// item. In order to get URL of specific item specify its delta explicitly
// using array notation.
// @code
// {{ node.field_image|file_url }}
// {{ node.field_image[0]|file_url }}
// @endcode
//
// Media fields are fully supported including OEmbed resources.
// @code
// {{ node.field_media|file_url }}
// @endcode
new \Twig_SimpleFilter('file_url', [$this, 'fileUrl']),
];
// PHP filter should be enabled in settings.php file.
if (Settings::get('twig_tweak_enable_php_filter')) {
// - PHP -
//
// PHP filter is disabled by default. You can enable it in settings.php
// file as follows:
// @code
// $settings['twig_tweak_enable_php_filter'] = TRUE;
// @endcode
//
// @code
// {{ 'return date('Y');'|php }}
// @endcode
//
// Using PHP filter is discouraged as it may cause security implications.
// In fact it is very rarely needed.
//
// The above code can be replaced with following.
// @code
// {{ 'now'|date('Y') }}
// @endcode
$filters[] = new \Twig_SimpleFilter('php', [$this, 'phpFilter']);
}
return $filters;
@ -98,26 +393,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Builds the render array for a block.
*
* In order to list all registered plugin IDs fetch them with block plugin
* manager. With Drush it can be done like follows:
* @code
* drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefinitions()));"
* @endcode
*
* Examples:
* @code
* {# Print block using default configuration. #}
* {{ drupal_block('system_branding_block') }}
*
* {# Print block using custom configuration. #}
* {{ drupal_block('system_branding_block', {label: 'Branding', use_site_name: false})
*
* {# Bypass block.html.twig theming. #}
* {{ drupal_block('system_branding_block', wrapper=false) }}
* @endcode
*
* @see https://www.drupal.org/node/2964457#block-plugin
*
* @param mixed $id
* The string of block plugin to render.
* @param array $configuration
@ -183,15 +458,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Builds the render array of a given region.
*
* Examples:
* @code
* {# Print 'Sidebar First' region of the default site theme. #}
* {{ drupal_region('sidebar_first') }}
*
* {# Print 'Sidebar First' region of Bartik theme. #}
* {{ drupal_region('sidebar_first', 'bartik') }}
* @endcode
*
* @param string $region
* The region to build.
* @param string $theme
@ -243,19 +509,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns the render array to represent and entity.
*
* Examples:
* @code
* {# Print a content block which ID is 1. #}
* {{ drupal_entity('block_content', 1) }}
*
* {# Print a node's teaser. #}
* {{ drupal_entity('node', 123, 'teaser') }}
*
* {# Print Branding block which was previously disabled on #}
* {# admin/structure/block page. #}
* {{ drupal_entity('block', 'bartik_branding', check_access=false) }}
* @endcode
*
* @param string $entity_type
* The entity type.
* @param mixed $id
@ -299,18 +552,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Gets the built and processed entity form for the given entity type.
*
* Examples:
* @code
* {# Print edit form for node 1. #}
* {{ drupal_entity_form('node', 1) }}
*
* {# Print add form for Article content type. #}
* {{ drupal_entity_form('node', values={type: 'article'}) }}
*
* {# Print user register form. #}
* {{ drupal_entity_form('user', NULL, 'register', check_access=false) }}
* @endcode
*
* @param string $entity_type
* The entity type.
* @param mixed $id
@ -353,13 +594,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns the render array for a single entity field.
*
* Example:
* @code
* {{ drupal_field('field_image', 'node', 1) }}
* {{ drupal_field('field_image', 'node', 1, 'teaser') }}
* {{ drupal_field('field_image', 'node', 1, {type: 'image_url', settings: {image_style: 'large'}}) }}
* @endcode
*
* @param string $field_name
* The field name.
* @param string $entity_type
@ -407,11 +641,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns the render array for Drupal menu.
*
* Example:
* @code
* {{ drupal_menu('main') }}
* @endcode
*
* @param string $menu_name
* The name of the menu.
* @param int $level
@ -456,11 +685,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Builds and processes a form for a given form ID.
*
* Example:
* @code
* {{ drupal_form('Drupal\\search\\Form\\SearchBlockForm') }}
* @endcode
*
* @param string $form_id
* The form ID.
* @param ...
@ -477,24 +701,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Builds an image.
*
* Examples:
* @code
* {# Render image specified by file ID. #}
* {{ drupal_image(123) }}
*
* {# Render image specified by file UUID. #}
* {{ drupal_image('9bb27144-e6b2-4847-bd24-adcc59613ec0') }}
*
* {# Render image specified by file URI. #}
* {{ drupal_image('public://ocean.jpg') }}
*
* {# Render image using 'thumbnail' image style and custom attributes. #}
* {{ drupal_image('public://ocean.jpg', 'thumbnail', {alt: 'The alternative text'|t, title: 'The title text'|t}) }}
*
* {# Render responsive image. #}
* {{ drupal_image('public://ocean.jpg', 'wide', responsive=true) }}
* @endcode
*
* @param mixed $property
* A property to identify the image.
* @param string $style
@ -567,11 +773,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Replaces a given tokens with appropriate value.
*
* Example:
* @code
* {{ drupal_token('site:name') }}
* @endcode
*
* @param string $token
* A replaceable token.
* @param array $data
@ -596,11 +797,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Retrieves data from a given configuration object.
*
* Example:
* @code
* {{ drupal_config('system.site', 'name') }}
* @endcode
*
* @param string $name
* The name of the configuration object to construct.
* @param string $key
@ -616,18 +812,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Dumps information about variables.
*
* Examples:
* @code
* {# Basic usage. #}
* {{ drupal_dump(var) }}
*
* {# Same as above but shorter. #}
* {{ dd(var) }}
*
* {# Dump all available variables for the current template. #}
* {{ dd() }}
* @endcode
*
* @param array $context
* Variables from the Twig template.
* @param mixed $variable
@ -662,15 +846,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Generates a URL from an internal path.
*
* Examples:
* @code
* {# Basic usage. #}
* {{ drupal_url('node/1) }}
*
* {# Complex URL. #}
* {{ drupal_url('node/1', {query: {foo: 'bar'}, fragment: 'example', absolute: true}) }}
* @endcode
*
* @param string $user_input
* User input for a link or path.
* @param array $options
@ -702,15 +877,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Generates a link from an internal path.
*
* Examples:
* @code
* {# It supports the same options as drupal_url(), plus attributes. #}
* {{ drupal_link('View'|t, 'node/1', {attributes: {target: '_blank'}}) }}
*
* {# This link will only be shown for privileged users. #}
* {{ drupal_link('Example'|t, '/admin', check_access=true) }}
* @endcode
*
* @param string $text
* The text to be used for the link.
* @param string $user_input
@ -757,21 +923,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Builds contextual links.
*
* Examples:
* @code
* {# Basic usage. #}
* <div class="contextual-region">
* {{ contextual_links('entity.view.edit_form:view=frontpage&display_id=feed_1') }}
* {{ drupal_view('frontpage') }}
* </div>
*
* {# Multiple links. #}
* <div class="contextual-region">
* {{ contextual_links('node:node=123|block_content:block_content=123') }}
* {{ content }}
* </div>
* @endcode
*
* @param string $id
* A serialized representation of a #contextual_links property value array.
*
@ -809,18 +960,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Replaces all tokens in a given string with appropriate values.
*
* Example:
* @code
* {# Basic usage. #}
* {{ '<h1>[site:name]</h1><div>[site:slogan]</div>'|token_replace }}
*
* {# This is more suited to large markup (requires Twig >= 1.41). #}
* {% apply token_replace %}
* <h1>[site:name]</h1>
* <div>[site:slogan]</div>
* {% endapply %}
* @endcode
*
* @param string $text
* An HTML string containing replaceable tokens.
*
@ -834,14 +973,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Performs a regular expression search and replace.
*
* Example:
* @code
* {{ 'Drupal - community plumbing!'|preg_replace('/(Drupal)/', '<b>$1</b>') }}
* @endcode
*
* For simple string interpolation consider using built-in 'replace' or
* 'format' Twig filters.
*
* @param string $text
* The text to search and replace.
* @param string $pattern
@ -859,11 +990,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns the URL of this image derivative for an original image path or URI.
*
* Example:
* @code
* {{ 'public://images/ocean.jpg'|image_style('thumbnail') }}
* @endcode
*
* @param string $path
* The path or URI to the original image.
* @param string $style
@ -891,11 +1017,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Transliterates text from Unicode to US-ASCII.
*
* Example:
* @code
* {{ 'Привет!'|transliterate }}
* @endcod
*
* @param string $string
* The string to transliterate.
* @param string $langcode
@ -920,11 +1041,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Runs all the enabled filters on a piece of text.
*
* Example.
* @code
* {{ '<b>bold</b> <strong>strong</strong>'|check_markup('restricted_html') }}
* @endcode
*
* @param string $text
* The text to be filtered.
* @param string|null $format_id
@ -948,11 +1064,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Truncates a UTF-8-encoded string safely to a number of characters.
*
* Example:
* @code
* {{ 'Some long text'|truncate(10, true) }}
* @endcode
*
* @param string $string
* The string to truncate.
* @param int $max_length
@ -977,15 +1088,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Adds new element to the array.
*
* Examples:
* @code
* {# Set top level value. #}
* {{ content.field_image|with('#title', 'Photo'|t) }}
*
* {# Set nested value. #}
* {{ content|with(['field_image', '#title'], 'Photo'|t) }}
* @endcode
*
* @param array $build
* The renderable array to add the child item.
* @param mixed $key
@ -1009,21 +1111,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns a render array for entity, field list or field item.
*
* Examples:
*
* Do not put this into node.html.twig template to avoid recursion.
* @code
* {{ node|view }}
* {{ node|view('teaser') }}
* @endcode
*
* @code
* {{ node.field_image|view }}
* {{ node.field_image[0]|view }}
* {{ node.field_image|view('teaser') }}
* {{ node.field_image|view({settings: {image_style: 'thumbnail'}}) }}
* @endcode
*
* @param mixed $object
* The object to build a render array from.
* @param string|array $display_options
@ -1059,15 +1146,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Filters out the children of a render array, optionally sorted by weight.
*
* Example:
* @code
* <ul>
* {% for tag in content.field_tags|children %}
* <li>{{ tag }}</li>
* {% endfor %}
* </ul>
* @endcode
*
* @param array $build
* The render array whose children are to be filtered.
* @param bool $sort
@ -1084,26 +1162,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Returns a URL path to the file.
*
* Examples:
*
* For string arguments it works similar to core file_url() Twig function.
* @code
* {{ 'public://sea.jpg'|file_url }}
* @endcode
*
* When field item list passed the URL will be extracted from the first item.
* In order to get URL of specific item specify its delta explicitly using
* array notation.
* @code
* {{ node.field_image|file_url }}
* {{ node.field_image[0]|file_url }}
* @endcode
*
* Media fields are fully supported including OEmbed resources.
* @code
* {{ node.field_media|file_url }}
* @endcode
*
* @param string|object $input
* Can be either file URI or an object that contains the URI.
*
@ -1153,25 +1211,6 @@ class TwigExtension extends \Twig_Extension {
/**
* Evaluates a string of PHP code.
*
* PHP filter is disabled by default. You can enable it in settings.php file
* as follows:
* @code
* $settings['twig_tweak_enable_php_filter'] = TRUE;
* @endcode
*
* Usage example:
* @code
* {{ 'return date('Y');'|php }}
* @endcode
*
* Using PHP filter is discouraged as it may cause security implications. In
* fact it is very rarely needed.
*
* The above code can be replaced with following.
* @code
* {{ 'now'|date('Y') }}
* @endcode
*
* @param string $code
* Valid PHP code to be evaluated.
*

Loading…
Cancel
Save