Issue #2342287 by mikeker: Allow Twig in Views token replacement
							parent
							
								
									29f441d3c2
								
							
						
					
					
						commit
						552c86ca35
					
				| 
						 | 
				
			
			@ -489,7 +489,7 @@ display:
 | 
			
		|||
            alter_text: false
 | 
			
		||||
            text: ''
 | 
			
		||||
            make_link: true
 | 
			
		||||
            path: 'admin/content/files/usage/[fid]'
 | 
			
		||||
            path: 'admin/content/files/usage/{{fid}}'
 | 
			
		||||
            absolute: false
 | 
			
		||||
            external: false
 | 
			
		||||
            replace_spaces: false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -319,6 +319,57 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
 | 
			
		|||
    return \Drupal::token()->replace($string, array('view' => $this->view), $options);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Replaces Views' tokens in a given string. It is the responsibility of the
 | 
			
		||||
   * calling function to ensure $text and $token replacements are sanitized.
 | 
			
		||||
   *
 | 
			
		||||
   * This used to be a simple strtr() scattered throughout the code. Some Views
 | 
			
		||||
   * tokens, such as arguments (e.g.: %1 or !1), still use the old format so we
 | 
			
		||||
   * handle those as well as the new Twig-based tokens (e.g.: {{ field_name }})
 | 
			
		||||
   *
 | 
			
		||||
   * @param $text
 | 
			
		||||
   *   String with possible tokens.
 | 
			
		||||
   * @param $tokens
 | 
			
		||||
   *   Array of token => replacement_value items.
 | 
			
		||||
   *
 | 
			
		||||
   * @return String
 | 
			
		||||
   */
 | 
			
		||||
  protected function viewsTokenReplace($text, $tokens) {
 | 
			
		||||
    if (empty($tokens)) {
 | 
			
		||||
      return $text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Separate Twig tokens from other tokens (e.g.: contextual filter tokens in
 | 
			
		||||
    // the form of %1).
 | 
			
		||||
    $twig_tokens = array();
 | 
			
		||||
    $other_tokens = array();
 | 
			
		||||
    foreach ($tokens as $token => $replacement) {
 | 
			
		||||
      if (strpos($token, '{{') !== FALSE) {
 | 
			
		||||
        // Twig wants a token replacement array stripped of curly-brackets.
 | 
			
		||||
        $token = trim(str_replace(array('{', '}'), '', $token));
 | 
			
		||||
        $twig_tokens[$token] = $replacement;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $other_tokens[$token] = $replacement;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Non-Twig tokens are a straight string replacement, Twig tokens get run
 | 
			
		||||
    // through an inline template for rendering and replacement.
 | 
			
		||||
    $text = strtr($text, $other_tokens);
 | 
			
		||||
    if ($twig_tokens) {
 | 
			
		||||
      $build = array(
 | 
			
		||||
        '#type' => 'inline_template',
 | 
			
		||||
        '#template' => $text,
 | 
			
		||||
        '#context' => $twig_tokens,
 | 
			
		||||
      );
 | 
			
		||||
      return drupal_render($build);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return $text;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2136,7 +2136,7 @@ abstract class DisplayPluginBase extends PluginBase {
 | 
			
		|||
 | 
			
		||||
      if ($this->getOption('link_display') == 'custom_url' && $override_path = $this->getOption('link_url')) {
 | 
			
		||||
        $tokens = $this->getArgumentsTokens();
 | 
			
		||||
        $path = strtr($override_path, $tokens);
 | 
			
		||||
        $path = $this->viewsTokenReplace($override_path, $tokens);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ($path) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -895,7 +895,7 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
 | 
			
		|||
  protected function documentSelfTokens(&$tokens) {
 | 
			
		||||
    $field = $this->getFieldDefinition();
 | 
			
		||||
    foreach ($field->getColumns() as $id => $column) {
 | 
			
		||||
      $tokens['[' . $this->options['id'] . '-' . $id . ']'] = $this->t('Raw @column', array('@column' => $id));
 | 
			
		||||
      $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -913,11 +913,11 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
 | 
			
		|||
               (is_object($item['raw']) ? (array)$item['raw'] : NULL);
 | 
			
		||||
      }
 | 
			
		||||
      if (isset($raw) && isset($raw[$id]) && is_scalar($raw[$id])) {
 | 
			
		||||
        $tokens['[' . $this->options['id'] . '-' . $id . ']'] = Xss::filterAdmin($raw[$id]);
 | 
			
		||||
        $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = Xss::filterAdmin($raw[$id]);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        // Make sure that empty values are replaced as well.
 | 
			
		||||
        $tokens['[' . $this->options['id'] . '-' . $id . ']'] = '';
 | 
			
		||||
        $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = '';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -322,7 +322,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function tokenizeValue($value, $row_index = NULL) {
 | 
			
		||||
    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
 | 
			
		||||
    if (strpos($value, '{{') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
 | 
			
		||||
      $fake_item = array(
 | 
			
		||||
        'alter_text' => TRUE,
 | 
			
		||||
        'text' => $value,
 | 
			
		||||
| 
						 | 
				
			
			@ -705,7 +705,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
        '#title' => $this->t('Text'),
 | 
			
		||||
        '#type' => 'textarea',
 | 
			
		||||
        '#default_value' => $this->options['alter']['text'],
 | 
			
		||||
        '#description' => $this->t('The text to display for this field. You may include HTML. You may enter data from this view as per the "Replacement patterns" below.'),
 | 
			
		||||
        '#description' => $this->t('The text to display for this field. You may include HTML or Twig. You may enter data from this view as per the "Replacement patterns" below.'),
 | 
			
		||||
        '#states' => array(
 | 
			
		||||
          'visible' => array(
 | 
			
		||||
            ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE),
 | 
			
		||||
| 
						 | 
				
			
			@ -852,10 +852,10 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      // Setup the tokens for fields.
 | 
			
		||||
      $previous = $this->getPreviousFieldLabels();
 | 
			
		||||
      foreach ($previous as $id => $label) {
 | 
			
		||||
        $options[t('Fields')]["[$id]"] = substr(strrchr($label, ":"), 2 );
 | 
			
		||||
        $options[t('Fields')]["{{ $id }}"] = substr(strrchr($label, ":"), 2 );
 | 
			
		||||
      }
 | 
			
		||||
      // Add the field to the list of options.
 | 
			
		||||
      $options[t('Fields')]["[{$this->options['id']}]"] = substr(strrchr($this->adminLabel(), ":"), 2 );
 | 
			
		||||
      $options[t('Fields')]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2 );
 | 
			
		||||
 | 
			
		||||
      $count = 0; // This lets us prepare the key as we want it printed.
 | 
			
		||||
      foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) {
 | 
			
		||||
| 
						 | 
				
			
			@ -869,7 +869,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      $output = '<p>' . $this->t('You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.') . '</p>';
 | 
			
		||||
      // We have some options, so make a list.
 | 
			
		||||
      if (!empty($options)) {
 | 
			
		||||
        $output = '<p>' . $this->t("The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields. If you would like to have the characters '[' and ']' use the html entity codes '%5B' or '%5D' or they will get replaced with empty space.") . '</p>';
 | 
			
		||||
        $output = '<p>' . $this->t("The following Twig replacement tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.") . '</p>';
 | 
			
		||||
        foreach (array_keys($options) as $type) {
 | 
			
		||||
          if (!empty($options[$type])) {
 | 
			
		||||
            $items = array();
 | 
			
		||||
| 
						 | 
				
			
			@ -1229,7 +1229,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
        $more_link_text = $this->options['alter']['more_link_text'] ? $this->options['alter']['more_link_text'] : $this->t('more');
 | 
			
		||||
        $more_link_text = strtr(Xss::filterAdmin($more_link_text), $tokens);
 | 
			
		||||
        $more_link_path = $this->options['alter']['more_link_path'];
 | 
			
		||||
        $more_link_path = strip_tags(String::decodeEntities(strtr($more_link_path, $tokens)));
 | 
			
		||||
        $more_link_path = strip_tags(String::decodeEntities($this->viewsTokenReplace($more_link_path, $tokens)));
 | 
			
		||||
 | 
			
		||||
        // Make sure that paths which were run through _url() work as well.
 | 
			
		||||
        $base_path = base_path();
 | 
			
		||||
| 
						 | 
				
			
			@ -1260,14 +1260,12 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Render this field as altered text, from a fieldset set by the user.
 | 
			
		||||
   * Render this field as user-defined altered text.
 | 
			
		||||
   */
 | 
			
		||||
  protected function renderAltered($alter, $tokens) {
 | 
			
		||||
    // Filter this right away as our substitutions are already sanitized.
 | 
			
		||||
    $value = Xss::filterAdmin($alter['text']);
 | 
			
		||||
    $value = strtr($value, $tokens);
 | 
			
		||||
 | 
			
		||||
    return $value;
 | 
			
		||||
    $template = Xss::filterAdmin($alter['text']);
 | 
			
		||||
    return $this->viewsTokenReplace($template, $tokens);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -1290,7 +1288,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
    $value = '';
 | 
			
		||||
 | 
			
		||||
    if (!empty($alter['prefix'])) {
 | 
			
		||||
      $value .= Xss::filterAdmin(strtr($alter['prefix'], $tokens));
 | 
			
		||||
      $value .= Xss::filterAdmin($this->viewsTokenReplace($alter['prefix'], $tokens));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $options = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -1311,7 +1309,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      // Use strip tags as there should never be HTML in the path.
 | 
			
		||||
      // However, we need to preserve special characters like " that
 | 
			
		||||
      // were removed by String::checkPlain().
 | 
			
		||||
      $path = strip_tags(String::decodeEntities(strtr($path, $tokens)));
 | 
			
		||||
      $path = strip_tags(String::decodeEntities($this->viewsTokenReplace($path, $tokens)));
 | 
			
		||||
 | 
			
		||||
      if (!empty($alter['path_case']) && $alter['path_case'] != 'none') {
 | 
			
		||||
        $path = $this->caseTransform($path, $this->options['alter']['path_case']);
 | 
			
		||||
| 
						 | 
				
			
			@ -1380,22 +1378,22 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      $options['fragment'] = $url['fragment'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $alt = strtr($alter['alt'], $tokens);
 | 
			
		||||
    $alt = $this->viewsTokenReplace($alter['alt'], $tokens);
 | 
			
		||||
    // Set the title attribute of the link only if it improves accessibility
 | 
			
		||||
    if ($alt && $alt != $text) {
 | 
			
		||||
      $options['attributes']['title'] = String::decodeEntities($alt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $class = strtr($alter['link_class'], $tokens);
 | 
			
		||||
    $class = $this->viewsTokenReplace($alter['link_class'], $tokens);
 | 
			
		||||
    if ($class) {
 | 
			
		||||
      $options['attributes']['class'] = array($class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!empty($alter['rel']) && $rel = strtr($alter['rel'], $tokens)) {
 | 
			
		||||
    if (!empty($alter['rel']) && $rel = $this->viewsTokenReplace($alter['rel'], $tokens)) {
 | 
			
		||||
      $options['attributes']['rel'] = $rel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $target = String::checkPlain(trim(strtr($alter['target'], $tokens)));
 | 
			
		||||
    $target = String::checkPlain(trim($this->viewsTokenReplace($alter['target'], $tokens)));
 | 
			
		||||
    if (!empty($target)) {
 | 
			
		||||
      $options['attributes']['target'] = $target;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1405,7 +1403,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
    if (isset($alter['link_attributes']) && is_array($alter['link_attributes'])) {
 | 
			
		||||
      foreach ($alter['link_attributes'] as $key => $attribute) {
 | 
			
		||||
        if (!isset($options['attributes'][$key])) {
 | 
			
		||||
          $options['attributes'][$key] = strtr($attribute, $tokens);
 | 
			
		||||
          $options['attributes'][$key] = $this->viewsTokenReplace($attribute, $tokens);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1416,7 +1414,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      // Convert the query to a string, perform token replacement, and then
 | 
			
		||||
      // convert back to an array form for _l().
 | 
			
		||||
      $options['query'] = UrlHelper::buildQuery($alter['query']);
 | 
			
		||||
      $options['query'] = strtr($options['query'], $tokens);
 | 
			
		||||
      $options['query'] = $this->viewsTokenReplace($options['query'], $tokens);
 | 
			
		||||
      $query = array();
 | 
			
		||||
      parse_str($options['query'], $query);
 | 
			
		||||
      $options['query'] = $query;
 | 
			
		||||
| 
						 | 
				
			
			@ -1426,7 +1424,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
      $options['alias'] = $alter['alias'];
 | 
			
		||||
    }
 | 
			
		||||
    if (isset($alter['fragment'])) {
 | 
			
		||||
      $options['fragment'] = strtr($alter['fragment'], $tokens);
 | 
			
		||||
      $options['fragment'] = $this->viewsTokenReplace($alter['fragment'], $tokens);
 | 
			
		||||
    }
 | 
			
		||||
    if (isset($alter['language'])) {
 | 
			
		||||
      $options['language'] = $alter['language'];
 | 
			
		||||
| 
						 | 
				
			
			@ -1448,7 +1446,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (!empty($alter['suffix'])) {
 | 
			
		||||
      $value .= Xss::filterAdmin(strtr($alter['suffix'], $tokens));
 | 
			
		||||
      $value .= Xss::filterAdmin($this->viewsTokenReplace($alter['suffix'], $tokens));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $value;
 | 
			
		||||
| 
						 | 
				
			
			@ -1481,10 +1479,10 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
    // Now add replacements for our fields.
 | 
			
		||||
    foreach ($this->view->display_handler->getHandlers('field') as $field => $handler) {
 | 
			
		||||
      if (isset($handler->last_render)) {
 | 
			
		||||
        $tokens["[$field]"] = $handler->last_render;
 | 
			
		||||
        $tokens["{{ $field }}"] = $handler->last_render;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $tokens["[$field]"] = '';
 | 
			
		||||
        $tokens["{{ $field }}"] = '';
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // We only use fields up to (and including) this one.
 | 
			
		||||
| 
						 | 
				
			
			@ -1568,9 +1566,10 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
 | 
			
		|||
   * fields as a list. For example, the field that displays all terms
 | 
			
		||||
   * on a node might have tokens for the tid and the term.
 | 
			
		||||
   *
 | 
			
		||||
   * By convention, tokens should follow the format of [token-subtoken]
 | 
			
		||||
   * By convention, tokens should follow the format of {{ token-subtoken }}
 | 
			
		||||
   * where token is the field ID and subtoken is the field. If the
 | 
			
		||||
   * field ID is terms, then the tokens might be [terms-tid] and [terms-name].
 | 
			
		||||
   * field ID is terms, then the tokens might be {{ terms-tid }} and
 | 
			
		||||
   * {{ terms-name }}.
 | 
			
		||||
   */
 | 
			
		||||
  protected function addSelfTokens(&$tokens, $item) { }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ abstract class Links extends FieldPluginBase {
 | 
			
		|||
      }
 | 
			
		||||
      // Make sure that tokens are replaced for this paths as well.
 | 
			
		||||
      $tokens = $this->getRenderTokens(array());
 | 
			
		||||
      $path = strip_tags(String::decodeEntities(strtr($path, $tokens)));
 | 
			
		||||
      $path = strip_tags(String::decodeEntities($this->viewsTokenReplace($path, $tokens)));
 | 
			
		||||
 | 
			
		||||
      $links[$field] = array(
 | 
			
		||||
        'url' => $path ? UrlObject::fromUri('base://' . $path) : $url,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,7 +191,7 @@ abstract class StylePluginBase extends PluginBase {
 | 
			
		|||
  public function usesTokens() {
 | 
			
		||||
    if ($this->usesRowClass()) {
 | 
			
		||||
      $class = $this->options['row_class'];
 | 
			
		||||
      if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
 | 
			
		||||
      if (strpos($class, '{{') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
 | 
			
		||||
        return TRUE;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -228,18 +228,15 @@ abstract class StylePluginBase extends PluginBase {
 | 
			
		|||
   * Take a value and apply token replacement logic to it.
 | 
			
		||||
   */
 | 
			
		||||
  public function tokenizeValue($value, $row_index) {
 | 
			
		||||
    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
 | 
			
		||||
    if (strpos($value, '{{') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
 | 
			
		||||
      // Row tokens might be empty, for example for node row style.
 | 
			
		||||
      $tokens = isset($this->rowTokens[$row_index]) ? $this->rowTokens[$row_index] : array();
 | 
			
		||||
      if (!empty($this->view->build_info['substitutions'])) {
 | 
			
		||||
        $tokens += $this->view->build_info['substitutions'];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ($tokens) {
 | 
			
		||||
        $value = strtr($value, $tokens);
 | 
			
		||||
      }
 | 
			
		||||
      $value = $this->viewsTokenReplace($value, $tokens);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -164,13 +164,13 @@ class FieldUnitTest extends ViewUnitTestBase {
 | 
			
		|||
    $row = $view->result[0];
 | 
			
		||||
 | 
			
		||||
    $name_field_0->options['alter']['alter_text'] = TRUE;
 | 
			
		||||
    $name_field_0->options['alter']['text'] = '[name]';
 | 
			
		||||
    $name_field_0->options['alter']['text'] = '{{ name }}';
 | 
			
		||||
 | 
			
		||||
    $name_field_1->options['alter']['alter_text'] = TRUE;
 | 
			
		||||
    $name_field_1->options['alter']['text'] = '[name_1] [name]';
 | 
			
		||||
    $name_field_1->options['alter']['text'] = '{{ name_1 }} {{ name }}';
 | 
			
		||||
 | 
			
		||||
    $name_field_2->options['alter']['alter_text'] = TRUE;
 | 
			
		||||
    $name_field_2->options['alter']['text'] = '[name_2] [name_1]';
 | 
			
		||||
    $name_field_2->options['alter']['text'] = '{{ name_2 }} {{ name_1 }}';
 | 
			
		||||
 | 
			
		||||
    foreach ($view->result as $row) {
 | 
			
		||||
      $expected_output_0 = $row->views_test_data_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,23 +178,48 @@ class FieldUnitTest extends ViewUnitTestBase {
 | 
			
		|||
      $expected_output_2 = "$row->views_test_data_name $row->views_test_data_name $row->views_test_data_name";
 | 
			
		||||
 | 
			
		||||
      $output = $name_field_0->advancedRender($row);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_0);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_0, format_string('Test token replacement: "!token" gave "!output"', [
 | 
			
		||||
        '!token' => $name_field_0->options['alter']['text'],
 | 
			
		||||
        '!output' => $output,
 | 
			
		||||
      ]));
 | 
			
		||||
 | 
			
		||||
      $output = $name_field_1->advancedRender($row);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_1);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_1, format_string('Test token replacement: "!token" gave "!output"', [
 | 
			
		||||
        '!token' => $name_field_1->options['alter']['text'],
 | 
			
		||||
        '!output' => $output,
 | 
			
		||||
      ]));
 | 
			
		||||
 | 
			
		||||
      $output = $name_field_2->advancedRender($row);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_2);
 | 
			
		||||
      $this->assertEqual($output, $expected_output_2, format_string('Test token replacement: "!token" gave "!output"', [
 | 
			
		||||
        '!token' => $name_field_2->options['alter']['text'],
 | 
			
		||||
        '!output' => $output,
 | 
			
		||||
      ]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $job_field = $view->field['job'];
 | 
			
		||||
    $job_field->options['alter']['alter_text'] = TRUE;
 | 
			
		||||
    $job_field->options['alter']['text'] = '[test-token]';
 | 
			
		||||
    $job_field->options['alter']['text'] = '{{ job }}';
 | 
			
		||||
 | 
			
		||||
    $random_text = $this->randomMachineName();
 | 
			
		||||
    $job_field->setTestValue($random_text);
 | 
			
		||||
    $output = $job_field->advancedRender($row);
 | 
			
		||||
    $this->assertSubString($output, $random_text, format_string('Make sure the self token (!value) appears in the output (!output)', array('!value' => $random_text, '!output' => $output)));
 | 
			
		||||
    $this->assertSubString($output, $random_text, format_string('Make sure the self token (!token => !value) appears in the output (!output)', [
 | 
			
		||||
      '!value' => $random_text,
 | 
			
		||||
      '!output' => $output,
 | 
			
		||||
      '!token' => $job_field->options['alter']['text'],
 | 
			
		||||
    ]));
 | 
			
		||||
 | 
			
		||||
    // Verify the token format used in D7 and earlier does not get substituted.
 | 
			
		||||
    $old_token = '[job]';
 | 
			
		||||
    $job_field->options['alter']['text'] = $old_token;
 | 
			
		||||
    $random_text = $this->randomMachineName();
 | 
			
		||||
    $job_field->setTestValue($random_text);
 | 
			
		||||
    $output = $job_field->advancedRender($row);
 | 
			
		||||
    $this->assertSubString($output, $old_token, format_string('Make sure the old token style (!token => !value) is not changed in the output (!output)', [
 | 
			
		||||
      '!value' => $random_text,
 | 
			
		||||
      '!output' => $output,
 | 
			
		||||
      '!token' => $job_field->options['alter']['text'],
 | 
			
		||||
    ]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ class StyleTest extends ViewTestBase {
 | 
			
		|||
    // Setup some random css class.
 | 
			
		||||
    $view->initStyle();
 | 
			
		||||
    $random_name = $this->randomMachineName();
 | 
			
		||||
    $view->style_plugin->options['row_class'] = $random_name . " test-token-[name]";
 | 
			
		||||
    $view->style_plugin->options['row_class'] = $random_name . " test-token-{{ name }}";
 | 
			
		||||
 | 
			
		||||
    $output = $view->preview();
 | 
			
		||||
    $this->storeViewPreview(drupal_render($output));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ display:
 | 
			
		|||
            alter_text: true
 | 
			
		||||
            text: 'Custom Text'
 | 
			
		||||
            make_link: true
 | 
			
		||||
            path: 'node/[nid]'
 | 
			
		||||
            path: 'node/{{nid}}'
 | 
			
		||||
            absolute: false
 | 
			
		||||
            external: false
 | 
			
		||||
            replace_spaces: false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,9 +55,9 @@ display:
 | 
			
		|||
          automatic_width: true
 | 
			
		||||
          alignment: horizontal
 | 
			
		||||
          col_class_default: true
 | 
			
		||||
          col_class_custom: 'name-[name]'
 | 
			
		||||
          col_class_custom: 'name-{{name}}'
 | 
			
		||||
          row_class_default: true
 | 
			
		||||
          row_class_custom: 'age-[age]'
 | 
			
		||||
          row_class_custom: 'age-{{ age }}'
 | 
			
		||||
      row:
 | 
			
		||||
        type: fields
 | 
			
		||||
      field_langcode: '***LANGUAGE_language_content***'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,20 +43,20 @@ class FieldUITest extends UITestBase {
 | 
			
		|||
    $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/age';
 | 
			
		||||
    $this->drupalGet($edit_handler_url);
 | 
			
		||||
    $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/fields/li');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '[age] == Age');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '{{ age }} == Age');
 | 
			
		||||
 | 
			
		||||
    $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/id';
 | 
			
		||||
    $this->drupalGet($edit_handler_url);
 | 
			
		||||
    $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/fields/li');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '[age] == Age');
 | 
			
		||||
    $this->assertEqual((string) $result[1], '[id] == ID');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '{{ age }} == Age');
 | 
			
		||||
    $this->assertEqual((string) $result[1], '{{ id }} == ID');
 | 
			
		||||
 | 
			
		||||
    $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/name';
 | 
			
		||||
    $this->drupalGet($edit_handler_url);
 | 
			
		||||
    $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/fields/li');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '[age] == Age');
 | 
			
		||||
    $this->assertEqual((string) $result[1], '[id] == ID');
 | 
			
		||||
    $this->assertEqual((string) $result[2], '[name] == Name');
 | 
			
		||||
    $this->assertEqual((string) $result[0], '{{ age }} == Age');
 | 
			
		||||
    $this->assertEqual((string) $result[1], '{{ id }} == ID');
 | 
			
		||||
    $this->assertEqual((string) $result[2], '{{ name }} == Name');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue