Commit d9d34180 authored by Tancredi D'Onofrio's avatar Tancredi D'Onofrio
Browse files

Issue #3277213: Render 'render arrays' as strings and process

parent af47f7cc
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -12,9 +12,9 @@ INTRODUCTION
------------

The Twig Typography module provides a Twig filter that integrates the PHP
Typography library and applies it to strings. An example use case is for
protecting against widowed words in titles. This could be applied in the
page-title.html.twig template like this:
Typography library and applies it to strings or render arrays. An example
use case is for protecting against widowed words in titles. This could be
applied in the page-title.html.twig template like this:

```<h1{{ title_attributes.addClass('page-title') }}>{{ title|typography }}</h1>```

@@ -81,9 +81,7 @@ CONFIGURATION
A typography filter is provided and is used on strings with the pipe character:
```{{ title|typography }}```

As it only operates on strings (or objects which cast to strings) it may be
necessary to render a render array first using the render Twig function:
```{{ content|render|typography }}```
The filter will attempt to render a render array if passed to the filter.

The typography filter can accept parameters to modify the defaults. For example,
to render the page title with typographic enhancements but without the de-widows
@@ -95,3 +93,4 @@ MAINTAINERS
-----------

 * Tancredi D'Onofrio (tanc) - https://www.drupal.org/u/tanc
 * mandclu - https://www.drupal.org/u/mandclu
+15 −6
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace Drupal\twig_typography\TwigExtension;

use Twig\TwigFilter;
use Twig\Extension\AbstractExtension;
use PHP_Typography\Settings;
use PHP_Typography\PHP_Typography;
use Symfony\Component\Yaml\Yaml;
@@ -11,14 +13,14 @@ use Symfony\Component\Yaml\Yaml;
 *
 * @package Drupal\twig_typography\TwigExtension
 */
class Typography extends \Twig_Extension {
class Typography extends AbstractExtension {

  /**
   * Generates a list of all Twig filters that this extension defines.
   */
  public function getFilters() {
    return [
      new \Twig_SimpleFilter('typography', [$this, 'applyTypography'], ['is_safe' => ['html']]),
      new TwigFilter('typography', [$this, 'applyTypography'], ['is_safe' => ['html']]),
    ];
  }

@@ -32,8 +34,8 @@ class Typography extends \Twig_Extension {
  /**
   * Runs the PHP-Typography.
   *
   * @param string $string
   *   The string of text to apply the filter to.
   * @param string|array $string
   *   The string of text to apply the filter to. If an array will be rendered.
   * @param array $arguments
   *   An optional array containing the settings for the typography library.
   *   This should be set as a hash (key value pair) in twig template.
@@ -50,7 +52,13 @@ class Typography extends \Twig_Extension {
   */
  public static function applyTypography($string, array $arguments = [], $use_defaults = TRUE) {
    if (is_array($string)) {
      throw new \Exception(t('The typography twig filter can only operate on strings or rendered markup but an (render) array was passed.'));
      // Assume the $string is a render array and render it to a string.
      try {
        $string = \Drupal::service('renderer')->render($string);
      }
      catch (\Exception $e) {
        $string = \Drupal::service('renderer')->renderPlain($string);
      }
    }
    $settings = new Settings($use_defaults);
    // Load the defaults from the theme and merge them with any
@@ -101,7 +109,8 @@ class Typography extends \Twig_Extension {
   *   The file path to the typography_defaults.yml file.
   */
  public static function getFilePath($theme_name) {
    return drupal_get_path('theme', $theme_name) . '/typography_defaults.yml';
    $path = \Drupal::service('extension.list.theme')->getPath($theme_name);
    return $path . '/typography_defaults.yml';
  }

}
+40 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\twig_typography\Functional;

use Drupal\Tests\BrowserTestBase;

/**
 * Tests the twig typography extension.
 *
 * @group twig_typography
 * @group Template
 */
class TwigTypographyBrowserTest extends BrowserTestBase {

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = ['twig_typography', 'twig_typography_test'];

  /**
   * Theme to enable.
   *
   * @var string
   */
  protected $defaultTheme = 'stark';

  /**
   * Tests that a render array gets rendered to a string and used.
   */
  public function testTypographyRenderArray() {
    $this->drupalGet('/twig-typography-test');
    $assert = $this->assertSession();
    $assert->responseContains('Test <span class="push-double"></span>​<span class="pull-double">“</span>curly dou­ble quotes” and <span class="push-single"></span>​<span class="pull-single">‘</span>curly sin­gle quotes’');
    $assert->responseContains('Test for hang­ing&nbsp;widow');
    $assert->responseContains('Test a <span class="push-double"></span>​<span class="pull-double">“</span>ren­der&nbsp;array”');
  }

}
+45 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\twig_typography\Kernel;

use Drupal\KernelTests\KernelTestBase;
use Drupal\twig_typography\TwigExtension\TestTypography;

/**
 * Tests the twig typography extension.
 *
 * @group twig_typography
 * @group Template
 */
class TwigTypographyKernelTest extends KernelTestBase {

  /**
   * The system under test.
   *
   * @var \Drupal\Core\Template\TwigExtension
   */
  protected $systemUnderTest;

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();

    $this->systemUnderTest = new TestTypography();
  }

  /**
   * Tests that a render array gets rendered to a string using renderPlain().
   *
   * In a try/catch statement the page level render() function is tried first
   * and then renderPlain() used as a fallback.
   */
  public function testTypographyRenderArray() {
    $render_array = [
      '#markup' => '<h1 class="page-title">Test "the" page \'title\'</h1>',
    ];
    $this->assertSame('<h1 class="page-title">Test <span class="push-double"></span>​<span class="pull-double">“</span>the” page <span class="push-single"></span>​<span class="pull-single">‘</span>title’</h1>', $this->systemUnderTest->applyTypography($render_array, []));
  }

}
+7 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ use Drupal\Tests\UnitTestCase;
use Drupal\twig_typography\TwigExtension\TestTypography;

/**
 * Tests the twig extension.
 * Tests the twig typography extension.
 *
 * @group twig_typography
 * @group Template
@@ -23,7 +23,7 @@ class TwigTypographyTest extends UnitTestCase {
  /**
   * {@inheritdoc}
   */
  public function setUp() {
  public function setUp(): void {
    parent::setUp();

    $this->systemUnderTest = new TestTypography();
@@ -107,6 +107,11 @@ class TwigTypographyTest extends UnitTestCase {
 */
class TwigExtensionTestString {

  /**
   * The string.
   *
   * @var string
   */
  protected $string;

  /**
Loading