Problem/Motivation

Entity token implementations do not consider that base fields may be translatable. node.tokens.inc only considers body and summary to be multilingual, not title, author, changed or created. (URLs are generated appropriate for the language though). taxonomy.tokens.inc does not consider any of the fields translatable, eg. title, description, URL, etc. are not displayed in the appropriate language.

Proposed resolution

1. Compile a list of affected tokens.
2. Load the appropriate translation like node.tokens.inc for body and summary.
3. Tests.

Remaining tasks

Review all tokens. Fix. Tests.

User interface changes

None.

API changes

None.

Data model changes

None.

CommentFileSizeAuthor
#155 2529182-155.patch18.56 KBcorneboele
#152 2529182-152.patch18.52 KBSuresh Prabhu Parkala
#148 2529182-148.patch18.34 KBAardWolf
#137 interdiff_136-137.txt2.21 KBnikitagupta
#137 2529182-137.patch19.42 KBnikitagupta
#136 2529182-136.patch19.48 KBnikitagupta
#134 2529182-134.patch16.38 KBcgoffin
#132 interdiff_131-132.txt3.02 KBSuresh Prabhu Parkala
#132 2529182-132.patch19.5 KBSuresh Prabhu Parkala
#131 reroll_diff_2529182_128-131.txt8.06 KBankithashetty
#131 2529182-131.patch19.54 KBankithashetty
#128 interdiff_126-128.txt691 bytesravi.shankar
#128 2529182-128.patch19.63 KBravi.shankar
#126 interdiff_118-126.txt1.85 KBravi.shankar
#126 2529182-126.patch19.63 KBravi.shankar
#124 2529182-124.patch20.21 KBmegadesk3000
#118 2529182-9.1-118.patch20.24 KBaleevas
#114 2529182-114.patch20.22 KBrpayanm
#113 2529182-113.patch16.89 KBrpayanm
#107 2529182-diff-105-107.txt1.5 KBvijaycs85
#107 2529182-107.patch16.89 KBvijaycs85
#105 2529182-105.patch16.87 KBvijaycs85
#101 interdiff_2529182-94-100.txt3.15 KBpguillard
#100 not_all_node_taxonomy-2529182-100.patch20.04 KBpguillard
#94 not_all_node_taxonomy-2529182-94.patch16.75 KBbucefal91
#89 interdiff-2529182.txt1.01 KBeiriksm
#89 not_all_node_taxonomy-2529182-89.patch29.03 KBeiriksm
#87 not_all_node_taxonomy-2529182-87.patch29.2 KBeiriksm
#78 not_all_node_taxonomy-2529182-78.patch28.74 KBthenchev
#78 interdiff.txt2.59 KBthenchev
#65 not_all_node_taxonomy-2529182-65.patch29.54 KBthenchev
#63 interdiff.txt1.22 KBthenchev
#63 not_all_node_taxonomy-2529182-63.patch30.89 KBthenchev
#60 interdiff-56-60.txt19.21 KBlegolasbo
#60 not_all_node_taxonomy-2529182-60.patch30.2 KBlegolasbo
#56 interdiff-52-56.txt9.75 KBlegolasbo
#56 not_all_node_taxonomy-2529182-56.patch27.5 KBlegolasbo
#52 interdiff-48-52.txt20.13 KBlegolasbo
#52 not_all_node_taxonomy-2529182-52.patch27.31 KBlegolasbo
#48 not_all_node_taxonomy-2529182-48.patch33.59 KBvisabhishek
#45 interdiff-41_45.txt7.87 KBthenchev
#45 not_all_node_taxonomy-2529182-45.patch35.04 KBthenchev
#43 not_all_node_taxonomy-2529182-43.patch42.63 KBalvar0hurtad0
#41 not_all_node_taxonomy-2529182-41.patch30.8 KBthenchev
#37 not_all_node_taxonomy-2529182-37.patch30.78 KBthenchev
#37 interdiff.txt15.13 KBthenchev
#34 not_all_node_taxonomy-2529182-34.patch44.57 KBthenchev
#34 interdiff.txt4.29 KBthenchev
#32 not_all_node_taxonomy-2529182-32.patch44.24 KBthenchev
#32 interdiff.txt22.46 KBthenchev
#30 not_all_node_taxonomy-2529182-30.patch39.78 KBlegolasbo
#30 interdiff-27-30.txt9.35 KBlegolasbo
#27 not_all_node_taxonomy-2529182-26.patch39.77 KBlegolasbo
#27 interdiff-24-26.txt508 byteslegolasbo
#24 not_all_node_taxonomy-2529182-24.patch39.74 KBlegolasbo
#24 interdiff-20-24.txt26.23 KBlegolasbo
#20 interdiff.txt3.48 KBthenchev
#20 not_all_node_taxonomy-2529182-20.patch45.41 KBthenchev
#19 not_all_node_taxonomy-2529182-19.patch41.93 KBlegolasbo
#19 interdiff-18-19.txt5.75 KBlegolasbo
#18 not_all_node_taxonomy-2529182-18.patch43.07 KBlegolasbo
#18 interdiff-15-18.txt5.29 KBlegolasbo
#15 interdiff-11-15.txt9.07 KBthenchev
#15 2529182-15.patch44.16 KBthenchev
#14 2529182-diff-11-14.txt883 bytesvijaycs85
#14 2529182-14.patch36.73 KBvijaycs85
#11 not_all_node_taxonomy-2529182-11.patch36.68 KBlegolasbo
#9 not_all_node_taxonomy-2529182-9.patch4.6 KBlegolasbo
#9 interdiff-6-9.txt6.75 KBlegolasbo
#6 2529182-6-token_translate-test.patch4.06 KBthenchev
#4 2529182-4-token-translate.patch40.32 KBSweetchuck

Issue fork drupal-2529182

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

andypost’s picture

Related issue need review for a long time

Gábor Hojtsy’s picture

Title: Entity tokens are not multilingual aware » Not all node, taxonomy entity tokens are multilingual aware

Since we have #1885962: Comment tokens should use entity translation API for comments, rescoping this for node and taxonomy. Should be rescoped as more are found. @andypost do you know of other issues on multilingual tokens?

andypost’s picture

no other issues, but it makes sense to have common test class for them all

Sweetchuck’s picture

Status: Active » Needs review
FileSize
40.32 KB

This is what I have done so far. Tests for translated tokens are still missing.

Gábor Hojtsy’s picture

Looks good to me. I agree tests are needed :)

thenchev’s picture

Wanted to see if this is a starting point for tests.

legolasbo’s picture

Assigned: Unassigned » legolasbo

Working on extending these tests.

thenchev’s picture

@legolasbo Hi. I finished some part of the test. If you didn't do much work maybe its ok of I take over this part?

legolasbo’s picture

Assigned: legolasbo » Unassigned
Status: Needs review » Needs work
FileSize
6.75 KB
4.6 KB

@Denchev,

I've changed your patch to reduce code duplication and actually test for correct token replacements. Feel free to take over from here. It still needs to test for the token replacement of the other fields.

After uploading this patch I'll do a code review of the patch from #4.

Berdir’s picture

Yes, that last patch is definitely an improvement.

This is about testing tokens, not the node UI. We should be able to limit it to only use the API, just create a node with Node::create(); save, and then ->addTranslation('it') or so, save that too. Then generate tokens.

legolasbo’s picture

Patch didn't apply. Performed a basic reroll and removed some scope creep caused by array reformatting while fixing merge conflicts.

legolasbo’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 11: not_all_node_taxonomy-2529182-11.patch, failed testing.

vijaycs85’s picture

Status: Needs work » Needs review
FileSize
36.73 KB
883 bytes

Fixing failing test on #11

thenchev’s picture

FileSize
44.16 KB
9.07 KB

The tests will probably pass but its not correct yet.

Need some feedback on translating the author, and for some reason the "changed" and "created" using the service date.formater and passing the langcode didn't translate the string correctly its still in English.

mbovan’s picture

  1. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -63,73 +70,112 @@ protected function setUp() {
    +    $this->assertEqual($node->getOwner()->getUsername(), User::load($fields['uid'])->getUsername(), 'Owner username matches ');
    

    When we created the node, we set the user id to $this->user->id(). Can we use here $this->user->getUsername() instead of User::load($fields['uid'])->getUsername()?

  2. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -63,73 +70,112 @@ protected function setUp() {
    +    $token = '[node:title]';
    +    $token_replacement = \Drupal::token()->replace($token, ['node' => $node], $options);
    +    $this->assertEqual($token_replacement, $node->title->value, $token . ' replaced successfully');
    ...
    +    $this->assertEqual($token_replacement, $node->body->value, $token . ' replaced successfully');
    ...
    +    $this->assertEqual($token_replacement, $node->getOwner()->getUsername(), $token . ' replaced successfully');
    ...
    +    $this->assertEqual($token_replacement, \Drupal::service('date.formatter')->format($node->created->value, 'medium', '', NULL, $langcode), $token . ' replaced successfully');
    ...
    +    $this->assertEqual($token_replacement, \Drupal::service('date.formatter')->format($node->changed->value, 'medium', '', NULL, $langcode), $token . ' replaced successfully');
    ...
    -  protected function verifyTokensCorrectlyReplaced($node, $fields, $langcode) {
    -    foreach ($fields as $field_name => $field_value) {
    -      $token = '[node:' . $field_name . ']';
    -      // Perform unsanitized replacement for easy comparison.
    -      $options = [
    -        'langcode' => $langcode,
    -        'sanitize' => FALSE,
    -      ];
    -      $token_replacement = \Drupal::token()
    -        ->replace($token, ['node' => $node], $options);
    -      $this->assertEqual($token_replacement, $field_value, $token . ' replaced successfully');
    -    }
    -  }
    

    Can we just modify verifyTokensCorrectlyReplaced() method, pass the required values (e.g. mapping of token names - field values) and call it once as a helper method instead of calling assertEquals() multiple times? I guess it will be more readable.

legolasbo’s picture

Assigned: Unassigned » legolasbo

working on this.

legolasbo’s picture

FileSize
5.29 KB
43.07 KB

This patch addresses 16.2

legolasbo’s picture

Author translation is now properly tested. Also had a look at the created/changed fields. They are being translated properly, but the italian translations don't seem to be imported when enabling a language in the test. The date string is therefor still in English, because it falls back to English. The behaviour of the translation api is however thoroughly tested, so I think we are fine like this.

I removed the following because we don't need to test the node/translation creation. We only want to test the token replacement.

-    // Check that the node translation exists in the database.
-    $this->assertEqual($translation->language()->getId(), $langcode, 'Node has langcode: ' . $langcode);
-    $this->assertEqual($translation->title->value, $fields['title'], 'Title value matches.');
-    $this->assertEqual($translation->body->value, $fields['body'], 'Body value matches.');
-    $this->assertEqual($translation->getOwner()->getUsername(), User::load($fields['uid'])->getUsername(), 'Owner username matches ');
-
-    $this->assertEqual($translation->created->value, $fields['created'], 'Created value matches');
-    $this->assertEqual($translation->changed->value, $fields['changed'], 'Changed value matches');
thenchev’s picture

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Updates look great to me :) Thanks all for working on this!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/node/node.tokens.inc
    @@ -86,6 +85,11 @@ function node_token_info() {
    +  if ($type != 'node' || empty($data['node'])) {
    +    return [];
    +  }
    
    @@ -94,119 +98,110 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
    -  if ($type == 'node' && !empty($data['node'])) {
    

    Making this change makes the patch way harder to review.

  2. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -78,75 +96,106 @@ function testNodeTokenReplacement() {
    +  protected function replaceTokensAndCheckMetadata(array $tests, array $data, array $options, $message, array $metadata_tests) {
    ...
    +  protected function replaceTokens(array $tests, array $data, array $options, $message) {
    
    +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -156,18 +182,42 @@ function testTaxonomyTokenReplacement() {
    +  protected function replaceTokensAndCheckMetadata(array $tests, array $data, array $options, $message, array $metadata_tests) {
    ...
    +  protected function replaceTokens(array $tests, array $data, array $options, $message) {
    

    Missing docs

  3. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -78,75 +96,106 @@ function testNodeTokenReplacement() {
    +      $this->assertEqual($output, $expected, format_string($message, [
    ...
    +      $this->assertEqual($output, $expected, format_string($message, [
    
    +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -156,18 +182,42 @@ function testTaxonomyTokenReplacement() {
    +      $this->assertEqual($output, $expected, format_string($message, [
    ...
    +      $this->assertEqual($output, $expected, format_string($message, [
    

    Use SafeMarkup::format() - format_string() is deprecated.

  4. +++ b/core/modules/taxonomy/taxonomy.tokens.inc
    @@ -117,28 +136,30 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
             case 'node-count':
    -          $query = db_select('taxonomy_index');
    -          $query->condition('tid', $term->id());
    -          $query->addTag('term_node_count');
    -          $count = $query->countQuery()->execute()->fetchField();
    -          $replacements[$original] = $count;
    +          $replacements[$original] = db_select('taxonomy_index')
    +            ->condition('tid', $term->id())
    +            ->addTag('term_node_count')
    +            ->countQuery()
    +            ->execute()
    +            ->fetchField();
               break;
    

    Afaics this has not changed a thing.

legolasbo’s picture

On this!

legolasbo’s picture

Assigned: legolasbo » Unassigned
Status: Needs work » Needs review
FileSize
26.23 KB
39.74 KB

22.1 Reverted that out of scope change and also some additional out of scope code style changes. Greatly simplified the patch for review.
22.2 Documentation added
22.3 done
22.4 Did not change a thing indeed. Reverted the change.

Status: Needs review » Needs work

The last submitted patch, 24: not_all_node_taxonomy-2529182-24.patch, failed testing.

The last submitted patch, 24: not_all_node_taxonomy-2529182-24.patch, failed testing.

legolasbo’s picture

Status: Needs work » Needs review
FileSize
508 bytes
39.77 KB

Oops. forgot to restore $replacements variable.

Status: Needs review » Needs work

The last submitted patch, 27: not_all_node_taxonomy-2529182-26.patch, failed testing.

The last submitted patch, 27: not_all_node_taxonomy-2529182-26.patch, failed testing.

legolasbo’s picture

Status: Needs work » Needs review
FileSize
9.35 KB
39.78 KB

I forgot Simpletest tries to run every function which starts with test. Should pass now.

andypost’s picture

Status: Needs review » Needs work
  1. +++ b/TaxonomyTokenLanguageTest.php
    @@ -0,0 +1,115 @@
    +    // Configure the vocabulary to not hide the language selector.
    +    // TODO do we need this?
    

    I see no need in that

  2. +++ b/TaxonomyTokenLanguageTest.php
    @@ -0,0 +1,115 @@
    +  }
    +}
    

    needs empty line between

  3. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -0,0 +1,158 @@
    +  /**
    +   * @var null
    +   */
    +  private $users = NULL;
    

    needs description

  4. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -0,0 +1,158 @@
    +
    +  protected function setUp() {
    

    needs {@inheritdoc}

  5. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -0,0 +1,158 @@
    +   * @param $langcode
    +   *
    +   * @return array
    

    string $langcode
    and both needs description

  6. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -24,38 +26,52 @@ class NodeTokenReplaceTest extends TokenReplaceUnitTestBase {
    +  /**
    +   * @var NodeTypeInterface
    +   */
    +  protected $nodeType;
    

    should be full namespace and needs description

  7. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -24,38 +26,52 @@ class NodeTokenReplaceTest extends TokenReplaceUnitTestBase {
    +    $this->nodeType = entity_create('node_type', [
    

    NodeType::create([..])

  8. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -90,63 +107,125 @@ function testNodeTokenReplacement() {
    +  /**
    +   * Asserts if tokens are correctly replaced and verifies that the correct
    +   * metadata has been set.
    
    +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -156,18 +182,75 @@ function testTaxonomyTokenReplacement() {
    +   * Asserts if tokens are correctly replaced and verifies that the correct
    +   * metadata has been set.
    

    should be one-liner

  9. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -90,63 +107,125 @@ function testNodeTokenReplacement() {
    +   * @param array $tests
    +   * Expected results keyed by their respective tokens.
    +   * @param array $data
    +   * The data to perform the replacement on. @see Token::replace().
    +   * @param array $options
    +   * Aditional replacement options. @see Token::replace().
    +   * @param $message
    +   * The message to display with the assertion. Can contain replacement tokens:
    +   * - %token for the token name
    +   * - %output for the value returned by the token replacement service
    +   * - %expected for the expected result
    +   * @param array $metadata_tests
    +   * The metadata to verify. Keyed by the relevant token.
    ...
    +   * @param array $tests
    +   * Expected results keyed by their respective tokens.
    +   * @param array $data
    +   * The data to perform the replacement on. @see Token::replace().
    +   * @param array $options
    +   * Aditional replacement options. @see Token::replace().
    +   * @param $message
    +   * The message to display with the assertion. Can contain replacement tokens:
    +   * - %token for the token name
    +   * - %output for the value returned by the token replacement service
    +   * - %expected for the expected result
    
    +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -156,18 +182,75 @@ function testTaxonomyTokenReplacement() {
    +   * @param array $tests
    +   * Expected results keyed by their respective tokens.
    +   * @param array $data
    +   * The data to perform the replacement on. @see Token::replace().
    +   * @param array $options
    +   * Aditional replacement options. @see Token::replace().
    +   * @param $message
    +   * The message to display with the assertion. Can contain replacement tokens:
    +   * - %token for the token name
    +   * - %output for the value returned by the token replacement service
    +   * - %expected for the expected result
    +   * @param array $metadata_tests
    +   * The metadata to verify. Keyed by the relevant token.
    ...
    +   * @param array $tests
    +   * Expected results keyed by their respective tokens.
    +   * @param array $data
    +   * The data to perform the replacement on. @see Token::replace().
    +   * @param array $options
    +   * Aditional replacement options. @see Token::replace().
    +   * @param $message
    +   * The message to display with the assertion. Can contain replacement tokens:
    +   * - %token for the token name
    +   * - %output for the value returned by the token replacement service
    +   * - %expected for the expected result
    

    needs proper indent, looks like copy-paste

thenchev’s picture

Status: Needs work » Needs review
FileSize
22.46 KB
44.24 KB

Should address all from #31.

legolasbo’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -27,10 +27,15 @@ class NodeTokenLanguageTest extends WebTestBase {
    +   * Users for testing different language.
    

    s/language/languages

  2. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -12,10 +12,10 @@
    + * Generates text using placeholders for dummy content to check node token replacement.
    

    Exceeds 80 characters.

  3. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -147,47 +151,46 @@ function testNodeTokenReplacement() {
    +   * Asserts if tokens are correctly replaced and verifies that the correct metadata has been set.
    

    Exceeds 80 characters

  4. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -147,47 +151,46 @@ function testNodeTokenReplacement() {
    +   *   The message to display with the assertion. Can contain replacement tokens:
    

    Exceeds 80 characters

  5. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -207,16 +210,16 @@ protected function assertTokenReplacementAndCheckMetadata(array $tests, array $d
    +   *   The message to display with the assertion. Can contain replacement tokens:
    

    Exceeds 80 characters

+++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
@@ -24,129 +26,209 @@ class NodeTokenReplaceTest extends TokenReplaceUnitTestBase {
-      'body' => array(array('value' => $this->randomMachineName(32), 'summary' => $this->randomMachineName(16), 'format' => 'plain_text')),
-    ));
-    $node->save();
-
-    // Generate and test sanitized tokens.
-    $tests = array();
-    $tests['[node:nid]'] = $node->id();
-    $tests['[node:vid]'] = $node->getRevisionId();
-    $tests['[node:type]'] = 'article';
-    $tests['[node:type-name]'] = 'Article';
-    $tests['[node:title]'] = Html::escape($node->getTitle());
-    $tests['[node:body]'] = $node->body->processed;
-    $tests['[node:summary]'] = $node->body->summary_processed;
-    $tests['[node:langcode]'] = Html::escape($node->language()->getId());
-    $tests['[node:url]'] = $node->url('canonical', $url_options);
-    $tests['[node:edit-url]'] = $node->url('edit-form', $url_options);
-    $tests['[node:author]'] = Html::escape($account->getUsername());
-    $tests['[node:author:uid]'] = $node->getOwnerId();
-    $tests['[node:author:name]'] = Html::escape($account->getUsername());
-    $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId()));
-    $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId()));
-
-    $base_bubbleable_metadata = BubbleableMetadata::createFromObject($node);
-
-    $metadata_tests = [];
-    $metadata_tests['[node:nid]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:vid]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:type]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:type-name]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:title]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:body]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:summary]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:langcode]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:url]'] = $base_bubbleable_metadata;
-    $metadata_tests['[node:edit-url]'] = $base_bubbleable_metadata;
-    $bubbleable_metadata = clone $base_bubbleable_metadata;
-    $metadata_tests['[node:author]'] = $bubbleable_metadata->addCacheTags(['user:1']);
-    $metadata_tests['[node:author:uid]'] = $bubbleable_metadata;
-    $metadata_tests['[node:author:name]'] = $bubbleable_metadata;
-    $bubbleable_metadata = clone $base_bubbleable_metadata;
-    $metadata_tests['[node:created:since]'] = $bubbleable_metadata->setCacheMaxAge(0);
-    $metadata_tests['[node:changed:since]'] = $bubbleable_metadata;
-
-    // Test to make sure that we generated something for each token.
-    $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
-
-    foreach ($tests as $input => $expected) {
-      $bubbleable_metadata = new BubbleableMetadata();
-      $output = $this->tokenService->replace($input, array('node' => $node), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata);
-      $this->assertEqual($output, $expected, format_string('Sanitized node token %token replaced.', array('%token' => $input)));
-      $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
-    }
-
-    // Generate and test unsanitized tokens.
-    $tests['[node:title]'] = $node->getTitle();
-    $tests['[node:body]'] = $node->body->value;
-    $tests['[node:summary]'] = $node->body->summary;
-    $tests['[node:langcode]'] = $node->language()->getId();
-    $tests['[node:author:name]'] = $account->getUsername();
-
-    foreach ($tests as $input => $expected) {
-      $output = $this->tokenService->replace($input, array('node' => $node), array('langcode' => $this->interfaceLanguage->getId(), 'sanitize' => FALSE));
-      $this->assertEqual($output, $expected, format_string('Unsanitized node token %token replaced.', array('%token' => $input)));
-    }
-
-    // Repeat for a node without a summary.
-    $node = entity_create('node', array(
-      'type' => 'article',
+      'body' => [
+        [
+          'value' => '<blink>Blinking Body</blink>',
+          'summary' => '<blink>Blinking Summary</blink>',
+          'format' => 'plain_text',
+        ],
+      ],
+      ));
+      $node->save();
+
+      // Generate and test sanitized tokens.
+      $tests = array();
+      $tests['[node:nid]'] = $node->id();
+      $tests['[node:vid]'] = $node->getRevisionId();
+      $tests['[node:type]'] = $this->nodeType->id();
+      $tests['[node:type-name]'] = Html::escape($this->nodeType->label());
+      $tests['[node:title]'] = Html::escape($node->getTitle());
+      $tests['[node:body]'] = $node->body->processed;
+      $tests['[node:summary]'] = $node->body->summary_processed;
+      $tests['[node:langcode]'] = Html::escape($node->language()->getId());
+      $tests['[node:url]'] = $node->url('canonical', $url_options);
+      $tests['[node:edit-url]'] = $node->url('edit-form', $url_options);
+      $tests['[node:author]'] = Html::escape($account->getUsername());
+      $tests['[node:author:uid]'] = $node->getOwnerId();
+      $tests['[node:author:name]'] = Html::escape($account->getUsername());
+      $tests['[node:created:since]'] = \Drupal::service('date.formatter')
+        ->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId()));
+      $tests['[node:changed:since]'] = \Drupal::service('date.formatter')
+        ->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId()));
+
+      $base_bubbleable_metadata = BubbleableMetadata::createFromObject($node);
+      $author_bubbleable_metadata = clone $base_bubbleable_metadata;
+      $date_bubbleable_metadata = clone $base_bubbleable_metadata;
+      $metadata_tests = [];
+      $metadata_tests['[node:nid]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:vid]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:type]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:type-name]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:title]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:body]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:summary]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:langcode]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:url]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:edit-url]'] = $base_bubbleable_metadata;
+      $metadata_tests['[node:author]'] = $author_bubbleable_metadata->addCacheTags(['user:1']);
+      $metadata_tests['[node:author:uid]'] = $author_bubbleable_metadata;
+      $metadata_tests['[node:author:name]'] = $author_bubbleable_metadata;
+      $metadata_tests['[node:created:since]'] = $date_bubbleable_metadata->setCacheMaxAge(0);
+      $metadata_tests['[node:changed:since]'] = $date_bubbleable_metadata;
+
+      // Test to make sure that we generated something for each token.
+      $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
+
+      $data = ['node' => $node];
+      $options = [
+      'langcode' => $this->interfaceLanguage->getId(),
+      'sanitize' => TRUE,
+      ];
+      $msg = 'Sanitized node token %token replaced with %output. Expected is %expected';
+      $this->assertTokenReplacementAndCheckMetadata($tests, $data, $options, $msg, $metadata_tests);
+
+      // Generate and test unsanitized tokens.
+      $tests['[node:type-name]'] = $this->nodeType->label();
+      $tests['[node:title]'] = $node->getTitle();
+      $tests['[node:body]'] = $node->body->value;
+      $tests['[node:summary]'] = $node->body->summary;
+      $tests['[node:langcode]'] = $node->language()->getId();
+      $tests['[node:author]'] = $account->getUsername();
+      $tests['[node:author:name]'] = $account->getUsername();
+      $options['sanitize'] = FALSE;
+      $msg = 'Unsanitized node token %token replaced with %output. Expected is %expected';
+      $this->assertTokenReplacement($tests, $data, $options, $msg);
+
+      // Repeat for a node without a summary.
+      $node = entity_create('node', array(
+      'type' => $this->nodeType->id(),
...
-      'body' => array(array('value' => $this->randomMachineName(32), 'format' => 'plain_text')),
-    ));
-    $node->save();
-
-    // Generate and test sanitized token - use full body as expected value.
-    $tests = array();
-    $tests['[node:summary]'] = $node->body->processed;
-
-    // Test to make sure that we generated something for each token.
-    $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
+      'body' => [
+        [
+          'value' => '<blink>Blinking Body without Summary</blink>',
+          'format' => 'plain_text',
+        ],
+      ],
+      ));
+      $node->save();
+
+      // Generate and test sanitized token - use full body as expected value.
+      $tests = [
+        '[node:summary]' => $node->body->processed,
+      ];
+
+      // Test to make sure that we generated something for each token.
+      $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
+
+      $data = ['node' => $node];
+      $options['sanitize'] = TRUE;
+      $msg = 'Sanitized node token %token replaced with %output for node without a summary. Expected is %expected';
+      $this->assertTokenReplacement($tests, $data, $options, $msg);
+
+      // Generate and test unsanitized tokens.
+      $tests['[node:summary]'] = $node->body->value;
+
+      $options['sanitize'] = FALSE;
+      $msg = 'Unsanitized node token %token replaced with %output for node without a summary. Expected is %expected';
+      $this->assertTokenReplacement($tests, $data, $options, $msg);

This codestyle change makes the patch much harder to review and should be reverted.

thenchev’s picture

Status: Needs work » Needs review
FileSize
4.29 KB
44.57 KB

Addressed 1-5 and some styling errors that i noticed. Will maybe take a look later at the big one.

slashrsm’s picture

#33.6 needs to be addressed.

slashrsm’s picture

Status: Needs review » Needs work
thenchev’s picture

Status: Needs work » Needs review
FileSize
15.13 KB
30.78 KB

#33.6 Reverted changes, hope i understood that right

Status: Needs review » Needs work

The last submitted patch, 37: not_all_node_taxonomy-2529182-37.patch, failed testing.

The last submitted patch, 37: not_all_node_taxonomy-2529182-37.patch, failed testing.

legolasbo’s picture

Issue tags: +Needs reroll

@Denchev,

Patch no longer applies and needs a reroll, also found more unneeded codestyle changes.

  1. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -55,7 +57,13 @@ function testNodeTokenReplacement() {
    -      'body' => array(array('value' => $this->randomMachineName(32), 'summary' => $this->randomMachineName(16), 'format' => 'plain_text')),
    +      'body' => array(
    +        array(
    +          'value' => $this->randomMachineName(32),
    +          'summary' => $this->randomMachineName(16),
    +          'format' => 'plain_text',
    +        ),
    +      ),
    

    Codestyle changes, add review noise.

  2. +++ b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php
    @@ -18,10 +18,16 @@
    +  function createVocabulary(array $values = array()) {
    ...
    +    $vocabulary = entity_create('taxonomy_vocabulary', $values + array(
    

    Use shorthand array notation for all newly introduced/updated arrays

  3. +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -34,10 +37,25 @@ class TokenReplaceTest extends TaxonomyTestBase {
    -    $this->vocabulary = $this->createVocabulary();
    +    $this->vocabulary = $this->createVocabulary([
    +      'name' => 'V1 <strong>"&lt;name&gt;"</strong>',
    +    ]);
    

    let's put this on a single line

  4. +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -63,24 +81,29 @@ protected function setUp() {
    -    $edit = array();
    -    $node = $this->drupalCreateNode(array('type' => 'article'));
    -    $edit[$this->fieldName . '[]'] = $term2->id();
    +    $node = $this->drupalCreateNode(['type' => 'article']);
    +    $edit = [
    +      $this->fieldName . '[]' => $term2->id(),
    +    ];
    

    Codestyle changes add review noise.

  5. +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -90,29 +113,34 @@ function testTaxonomyTokenReplacement() {
    -    $bubbleable_metadata = clone $base_bubbleable_metadata;
    -    $metadata_tests['[term:vocabulary:name]'] = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags());
    ...
         $metadata_tests['[term:vocabulary]'] = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags());
    +    $metadata_tests['[term:vocabulary:name]'] = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags());
    

    Codestyle changes add review noise. And also seems to have introduced an error since $bubbleable_metadata is now nolonger set.

thenchev’s picture

Status: Needs work » Needs review
FileSize
30.8 KB

Lets try to make the patch apply. I will continue to fix whats breaks.

Status: Needs review » Needs work

The last submitted patch, 41: not_all_node_taxonomy-2529182-41.patch, failed testing.

alvar0hurtad0’s picture

Status: Needs work » Needs review
FileSize
42.63 KB

Reroll of #34

I was not really sure about what patch should I reroll.

Status: Needs review » Needs work

The last submitted patch, 43: not_all_node_taxonomy-2529182-43.patch, failed testing.

thenchev’s picture

So I went over the changes from the start and there might be some changes missing, not sure. Here I also tried fixing NodeTokenLanguageTest and NodeTokenLanguageTest by adding some changes to tokens.php. Was wondering if thats ok

Status: Needs review » Needs work

The last submitted patch, 45: not_all_node_taxonomy-2529182-45.patch, failed testing.

slashrsm’s picture

hook_tokens() is not responsible for sanitization any more (see https://www.drupal.org/node/2578365 for more info). This effectively means that we don't have $options['sanitize'] any more and we have to remove it from patch entirely.

visabhishek’s picture

Status: Needs work » Needs review
FileSize
33.59 KB

Removing $options['sanitize'] from #45 patch.

Status: Needs review » Needs work

The last submitted patch, 48: not_all_node_taxonomy-2529182-48.patch, failed testing.

Berdir’s picture

  1. +++ b/core/modules/node/node.tokens.inc
    @@ -93,13 +93,15 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
       }
    -  $replacements = array();
    +  $replacements = [];
    

    Try to remove as many unrelated changes as possible.

  2. +++ b/core/modules/node/node.tokens.inc
    @@ -113,22 +115,21 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
             case 'type':
    -          $replacements[$original] = $node->getType();
    +          $replacements[$original] = Html::escape($node->getType());
    

    All those changes are unrelated. You need to drop them, they're incorrectly merged from an updated patch.

legolasbo’s picture

Assigned: Unassigned » legolasbo

On this for a while

legolasbo’s picture

Assigned: legolasbo » Unassigned
Status: Needs work » Needs review
FileSize
27.31 KB
20.13 KB

I've removed a whole bunch of unrelated changes and all sanitize = true/false i could find. Several tests are still failing but I am out of time. Let's see how testbot thinks about it anyway.

Status: Needs review » Needs work

The last submitted patch, 52: not_all_node_taxonomy-2529182-52.patch, failed testing.

alvar0hurtad0’s picture

Issue tags: -Needs reroll

IMHO "needs reroll" tag is not needed

legolasbo’s picture

Assigned: Unassigned » legolasbo

Working on this some more.

legolasbo’s picture

Fixed the broken tests and removed some more unrelated code. Also found that the tests don't provide full test coverage where it concerns bubbleable metadata. Will improve test coverage some more.

legolasbo’s picture

Status: Needs work » Needs review

Let's have testbot take a look to see if I missed something.

The last submitted patch, 45: not_all_node_taxonomy-2529182-45.patch, failed testing.

The last submitted patch, 48: not_all_node_taxonomy-2529182-48.patch, failed testing.

legolasbo’s picture

Assigned: legolasbo » Unassigned
FileSize
30.2 KB
19.21 KB

This should do it.

I introduced AssertTokenReplacementTrait to reduce code duplication and ensure all token replacements are tested in the same way and also extended the cacheability metadata testing in TokenReplaceTest to cover all tested tokens.

slashrsm’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Utility/Token.php
    @@ -206,7 +206,7 @@ public function replace($text, array $data = array(), array $options = array(),
    -      $replacements[$token] = $value instanceof MarkupInterface ? $value : new HtmlEscapedText($value);
    +      $replacements[$token] = ($value instanceof MarkupInterface) ? $value : new HtmlEscapedText($value);
         }
    

    This seems like an unrelated change.

  2. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -0,0 +1,149 @@
    +  /**
    +   * Users for testing different languages.
    +   *
    +   * @var null
    +   */
    +  private $users = NULL;
    +
    

    This should be typehinted as \Drupal\user\UserInterface[] not null.

    Would also make sense to make it protected instead of private.

  3. +++ b/core/modules/node/src/Tests/NodeTokenLanguageTest.php
    @@ -0,0 +1,149 @@
    +    foreach (['en', 'it'] as $langcode) {
    +      $this->users[$langcode] = $this->drupalCreateUser([
    +        'create page content',
    +        'edit own page content'
    +      ]);
    +    }
    

    Is it necessary to have two identical users?

legolasbo’s picture

Thanks for the review.

61.1 - Could be unrelated, I don't know why it was added, so I guess we could try reverting the change.
61.2 - You are correct, should be changed.
61.3 - Yes it is necessary to have two "identical" users, because they will differ by username which is what we need to make sure they are properly replaced in different languages.

Unfortunately I don't have time to work on this until Friday at least.

thenchev’s picture

Status: Needs work » Needs review
FileSize
30.89 KB
1.22 KB

@slashrsm Thanks for feedback

Addressed 61.1 and 61.2

Status: Needs review » Needs work

The last submitted patch, 63: not_all_node_taxonomy-2529182-63.patch, failed testing.

thenchev’s picture

Status: Needs work » Needs review
FileSize
29.54 KB

Sorry. Missed the gitignore. Here is a new fixed patch

slashrsm’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

The last submitted patch, 45: not_all_node_taxonomy-2529182-45.patch, failed testing.

The last submitted patch, 48: not_all_node_taxonomy-2529182-48.patch, failed testing.

andypost’s picture

Would be great to get this in and re-use the same trait for #1885962: Comment tokens should use entity translation API

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 65: not_all_node_taxonomy-2529182-65.patch, failed testing.

legolasbo’s picture

Status: Needs work » Reviewed & tested by the community

Test failures seem unrelated. Back to RTBC while Retesting.

The last submitted patch, 45: not_all_node_taxonomy-2529182-45.patch, failed testing.

The last submitted patch, 48: not_all_node_taxonomy-2529182-48.patch, failed testing.

andypost’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 65: not_all_node_taxonomy-2529182-65.patch, failed testing.

Gábor Hojtsy’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/node/node.tokens.inc
    @@ -6,9 +6,9 @@
    +use Drupal\Component\Utility\Html;
    

    This does not appear to be used.

  2. +++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
    @@ -13,6 +13,8 @@
    + * Generates text using placeholders.
    + *
    
    @@ -42,7 +44,7 @@ protected function setUp() {
    -  function testNodeTokenReplacement() {
    +  public function testNodeTokenReplacement() {
    

    Out of scope changes.

  3. +++ b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php
    @@ -18,10 +18,16 @@
    +   * @return \Drupal\taxonomy\VocabularyInterface
    +   *   The new taxonomy vocabulary object.
    
    +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php
    @@ -18,10 +21,12 @@
    -   * @var \Drupal\taxonomy\VocabularyInterface
    +   * @var \Drupal\taxonomy\entity\Vocabulary
        */
       protected $vocabulary;
    
    @@ -32,10 +37,21 @@ class TokenReplaceTest extends TaxonomyTestBase {
    -    $this->vocabulary = $this->createVocabulary();
    +    $this->vocabulary = $this->createVocabulary(['name' => 'V1 <strong>"&lt;name&gt;"</strong>']);
    

    Why are we making the change to the protected property type doc? The method says it is returning the VocabularyInterface

  4. +++ b/core/modules/taxonomy/taxonomy.tokens.inc
    @@ -148,14 +152,14 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
    -    if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = $taxonomy_storage->loadParents($term->id())) {
    +    if (($parent_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = $taxonomy_storage->loadParents($term->id())) {
           $parent = array_pop($parents);
    -      $replacements += $token_service->generate('term', $vocabulary_tokens, array('term' => $parent), $options, $bubbleable_metadata);
    +      $replacements += $token_service->generate('term', $parent_tokens, ['term' => $parent], $options, $bubbleable_metadata);
         }
    

    Whilst these changes look correct I'm also not sure that they are in scope for the issue.

thenchev’s picture

Status: Needs work » Needs review
FileSize
2.59 KB
28.74 KB

Should cover everything from #77

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Yay, thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -95,10 +95,15 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
+
+  $langcode = isset($options['langcode']) ? $options['langcode'] : $langcode = NULL;
+

This looks wrong... I think it should be $langcode = isset($options['langcode']) ? $options['langcode'] : NULLl. But looking at the node code don't we need to set the language option for term urls?

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

gngn’s picture

I think alexpott is right:

$langcode = isset($options['langcode']) ? $options['langcode'] : $langcode = NULL;

smells funny.
I tried it with the proposed

$langcode = isset($options['langcode']) ? $options['langcode'] : NULL;

and it worked for me.

Berdir’s picture

+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -150,12 +154,12 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
   elseif ($type == 'vocabulary' && !empty($data['vocabulary'])) {
-    $vocabulary = $data['vocabulary'];
+    /** @var \Drupal\taxonomy\VocabularyInterface $vocabulary */
+    $vocabulary = \Drupal::entityManager()->getTranslationFromContext($data['vocabulary'], $langcode, ['operation' => 'vocabulary_tokens']);
 
     foreach ($tokens as $name => $original) {

config entities don't support this API, so this doesn't actually do anything.

it is more complicated for those, you need to switch the config translation override language and then switch it back, see user_mail()

gngn’s picture

Sorry - I just tested the 'term:parent' token. That worked.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

eiriksm’s picture

Assigned: Unassigned » eiriksm

Going to look at this today

eiriksm’s picture

OK, so did a reroll. And tried to address comments in #80 and #83.

Trying to find a way to test my changes manually, but let's see if it passes first.

eiriksm’s picture

Status: Needs work » Needs review
eiriksm’s picture

Hm, feel like this is more correct.

The token replacements works as I expect, but not sure about if I am testing all cases.

Gábor Hojtsy’s picture

Status: Needs review » Needs work
Issue tags: +SprintWeekend2017
+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -128,6 +131,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
         case 'vocabulary':
+          /** @var \Drupal\taxonomy\VocabularyInterface $vocabulary */
           $vocabulary = Vocabulary::load($term->bundle());
           $bubbleable_metadata->addCacheableDependency($vocabulary);
           $replacements[$original] = $vocabulary->label();

We don't seem to be dealing with a possibly translated vocabulary. I am fine with this if we want to not include this in the scope, but let's be clear about it.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

bucefal91’s picture

Hello, guys!

The patch #89 was no longer cleanly applying to 8.5.x so I attach its reroll. Had to manually update a few things, mostly it was about short-array syntax and a couple of test files moving from simpletest to phpunit. As far as functionality, I have changed no thing.

yogeshmpawar’s picture

Assigned: eiriksm » Unassigned
Status: Needs work » Needs review

Triggering test bots.

bucefal91’s picture

I am not sure why it failed. I ran that test locally through phpunit and through run-tests.sh both times successfully. Let me requeue it in case it was one-off failure.

Status: Needs review » Needs work

The last submitted patch, 94: not_all_node_taxonomy-2529182-94.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

bucefal91’s picture

ehmmm, I am not sure why it fails, the error message really says nothing particular and it does pass on my localhost. At the moment I do not have time to look into it.

thenchev’s picture

15:24:32 Fatal error: Trait 'Drupal\system\Tests\Utility\AssertTokenReplacementTrait' not found in /var/www/html/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php on line 19

This info might help from the jenkins console output. I don't have my dev setup currently to check it out more.

pguillard’s picture

Status: Needs work » Needs review
FileSize
20.04 KB

In fact AssertTokenReplacementTrait does not exist in core, and has been removed from patch #89 to patch #94.
Should be much better.

pguillard’s picture

The interdiff was missing

pbonnefoi’s picture

Thanks @pguillard it's working fine on Drupal 8.5.1

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

pbonnefoi’s picture

@pguillard I probably found a new buggy case. Let say I have a vocabulary like this :

Vegetables

  • Potatoes
  • Eggplants

They're all translated this way :

Légumes

  • Pommes de terre
  • Aubergines

With the patch provided by @pguillard, If I save the children then the problem is solved. But If I save the parent term, then the problem is still there (Drupal 8.6.10). I save term "Vegetables" and then I have url updated like this : /fr/ingredients/vegetables/pommes-de-terre.html

Any clue ?

vijaycs85’s picture

Rerolling against 8.8.x

#104:

I save term "Vegetables" and then I have url updated like this : /fr/ingredients/vegetables/pommes-de-terre.html

Any clue ?

Are you sure you don't have Flag other translations as outdated is checked?

Status: Needs review » Needs work

The last submitted patch, 105: 2529182-105.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vijaycs85’s picture

Status: Needs work » Needs review
FileSize
16.89 KB
1.5 KB

Fixing deprecation errors.

Status: Needs review » Needs work

The last submitted patch, 107: 2529182-107.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

ndobromirov’s picture

Added some more tags on the issue to improve visibility, as this is still relevant in late 2019.

Tokens are used for all aliases in Drupal in the context of path-auto module, current usage reported in 150k+ at time of writing. When you have content translation and path-auto you will be getting wrong URL aliases due to this.

In the context of metatag module, you will be presenting wrongly translated information on the pages. This is another module with over 100k installations as of late 2019.

megadesk3000’s picture

Hey together

The patch #107 isn't applying against 8.8.x
Do others have the same problem?

andypost’s picture

Issue tags: +Needs reroll
rpayanm’s picture

rpayanm’s picture

It was missing a file.

andypost’s picture

Issue tags: -Needs reroll
marassa’s picture

Status: Needs review » Reviewed & tested by the community

Works fine for me.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 114: 2529182-114.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

aleevas’s picture

Looks like in #114 failed test not related to patch.
I've re-rolled patch against 9.1.x.
Let's see that testing bot say

ndobromirov’s picture

Any chance to see a reroll of this in 8.x?

andypost’s picture

Probably as backport as of bug to 8.9.bugfix

sakhan’s picture

Status: Needs review » Reviewed & tested by the community

This patch in comment 118 is working on Drupal 9 and is good to go!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

This needs a reroll.

  1. +++ b/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php
    @@ -10,6 +10,8 @@
     use Drupal\Tests\system\Kernel\Token\TokenReplaceKernelTestBase;
     
     /**
    + * Generates text using placeholders.
    + *
      * Generates text using placeholders for dummy content to check node token
      * replacement.
      *
    
    +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -5,8 +5,11 @@
     /**
    + * Generates text using placeholders.
    + *
    

    Let's not make these changes here. They are not in scope.

  2. +++ b/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php
    --- /dev/null
    +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    
    +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    
    @@ -0,0 +1,84 @@
    +<?php
    +
    +/**
    + * @file
    + * Contains \Drupal\system\Tests\Utility\AssertTokenReplacementTrait.
    + */
    

    Can this be moved to core/tests/Drupal/Tests/Traits/Core

  3. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    + *
    + * Can be used by test classes that extend \Drupal\simpletest\WebTestBase.
    

    I think this line can be removed. It's wrong because WebTestBase is a thing of the past and I don't think we need to say this is for BrowserTestBase tests.

  4. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    +   * @param array $tests
    +   *   Expected results keyed by their respective tokens.
    ...
    +   * @param array $metadata_tests
    +   *   The metadata to verify. Keyed by the relevant token.
    

    This construction of passing an array of tests and an array of metadata tests is confusing.

  5. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    +   * @param $message
    +   *   The message to display with the assertion. Can contain replacement
    +   *   tokens:
    +   *   - %token for the token name
    +   *   - %output for the value returned by the token replacement service
    +   *   - %expected for the expected result
    

    I'm not sure about passing in the message here. I think we could build the message here using the $token and the key of $data.

  6. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    +      $this->assertEqual($output, new HtmlEscapedText($expected), new FormattableMarkup($message, [
    +        '%token' => $token,
    +        '%output' => $output,
    +        '%expected' => $expected,
    +      ]));
    +
    +      $this->assertEqual($bubbleable_metadata, $metadata_tests[$token]);
    

    $this->assertEquals() and the expected value should go first.

  7. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    +      $this->assertEqual($bubbleable_metadata, $metadata_tests[$token]);
    

    If this fails then it be helpful to have a message saying which token it was for. See above point about the $message param. I think we can build a message for each assertion in the test and it'll be better.

  8. +++ b/core/modules/system/src/Tests/Utility/AssertTokenReplacementTrait.php
    @@ -0,0 +1,84 @@
    +  /**
    +   * Asserts if tokens are correctly replaced.
    +   *
    +   * @param array $tests
    +   *   Expected results keyed by their respective tokens.
    +   * @param array $data
    +   *   The data to perform the replacement on. @see Token::replace().
    +   * @param array $options
    +   *   Additional replacement options. @see Token::replace().
    +   * @param $message
    +   *   The message to display with the assertion. Can contain replacement
    +   *   tokens:
    +   *   - %token for the token name
    +   *   - %output for the value returned by the token replacement service
    +   *   - %expected for the expected result
    +   */
    +  protected function assertTokenReplacement(array $tests, array $data, array $options, $message) {
    +    foreach ($tests as $token => $expected) {
    +      $output = \Drupal::token()->replace($token, $data, $options);
    +      $expected = ($expected instanceof MarkupInterface) ? $expected : new HtmlEscapedText($expected);
    +      $this->assertEqual($output, $expected, new FormattableMarkup($message, [
    +        '%token' => $token,
    +        '%output' => $output,
    +        '%expected' => $expected,
    +      ]));
    +    }
    +  }
    

    The comments about the test method above apply here too.

  9. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -103,37 +122,67 @@ public function testTaxonomyTokenReplacement() {
         // Generate and test sanitized tokens for term2.
         $tests = [];
         $tests['[term:tid]'] = $term2->id();
         $tests['[term:name]'] = $term2->getName();
    -    $tests['[term:description]'] = $term2->description->processed;
    +    $tests['[term:description]'] = $term2->getDescription();
         $tests['[term:url]'] = $term2->toUrl('canonical', ['absolute' => TRUE])->toString();
         $tests['[term:node-count]'] = 1;
    +    $tests['[term:vocabulary]'] = $this->vocabulary->label();
    +    $tests['[term:parent]'] = $term1->getName();
    +    $tests['[term:parent:tid]'] = $term1->id();
         $tests['[term:parent:name]'] = $term1->getName();
    +    $tests['[term:parent:description]'] = $term1->getDescription();
         $tests['[term:parent:url]'] = $term1->toUrl('canonical', ['absolute' => TRUE])->toString();
    +    $tests['[term:parent:node-count]'] = 0;
         $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]';
         $tests['[term:vocabulary:name]'] = $this->vocabulary->label();
    +    $tests['[term:parent:vocabulary]'] = $this->vocabulary->label();
    +    $tests['[term:parent:vocabulary:name]'] = $this->vocabulary->label();
     
         // Test to make sure that we generated something for each token.
         $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
     
    -    foreach ($tests as $input => $expected) {
    -      $output = $token_service->replace($input, ['term' => $term2], ['langcode' => $language_interface->getId()]);
    -      $this->assertEqual($output, $expected, new FormattableMarkup('Sanitized taxonomy term token %token replaced.', ['%token' => $input]));
    -    }
    +    $base_bubbleable_metadata = BubbleableMetadata::createFromObject($term2);
    +    $metadata_tests = [];
    +    $metadata_tests['[term:tid]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:name]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:description]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:url]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:node-count]'] = $base_bubbleable_metadata;
    +    $bubbleable_metadata = clone $base_bubbleable_metadata;
    +    $bubbleable_metadata = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags());
    +    $metadata_tests['[term:vocabulary]'] = $bubbleable_metadata;
    +    $metadata_tests['[term:vocabulary:name]'] = $bubbleable_metadata;
    +    $base_bubbleable_metadata = BubbleableMetadata::createFromObject($term1)->addCacheTags($term2->getCacheTags());
    +    $metadata_tests['[term:parent]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:tid]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:name]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:description]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:url]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:node-count]'] = $base_bubbleable_metadata;
    +    $metadata_tests['[term:parent:parent:name]'] = $base_bubbleable_metadata;
    +    $bubbleable_metadata = clone $base_bubbleable_metadata;
    +    $bubbleable_metadata = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags());
    +    $metadata_tests['[term:parent:vocabulary:name]'] = $bubbleable_metadata;
    +    $metadata_tests['[term:parent:vocabulary]'] = $bubbleable_metadata;
    +
    +    $data = ['term' => $term2];
    +    $msg = 'Taxonomy term 2 token %token replaced with %output which is equal to %expected';
    +    $this->assertTokenReplacementAndCheckMetadata($tests, $data, $options, $msg, $metadata_tests);
     
    

    Separating the test and metadata test set-up makes this harder to think about than it needs to be.

    Yes this is an existing problem but we're now making an API because we're adding the trait. I think we should consider ditching the trait here and file a follow-up to make a nicer trait. With a clearer API. It would be nice if each test passed to the trait looked something like

    [
      'token' => '[term:parent:name]',
      'expected_value' => 'Term Name'
      'expected_metadata => object
    ]
    
megadesk3000’s picture

Hey together

The patch in #114 isn't applying to 8.9.1 anymore. Looks like it needs a reroll?

megadesk3000’s picture

Rerolled the patch from #114 against 8.9.x.

ravi.shankar’s picture

Assigned: Unassigned » ravi.shankar

Working on this.

ravi.shankar’s picture

Here I have added re-roll of patch #118.

I have also fixed points 1, 2, 3 and 6 of comment #122.

It still needs work for the remaining points of comment #122.

ravi.shankar’s picture

Assigned: Unassigned » ravi.shankar

Working on this.

ravi.shankar’s picture

Fixed use statement issue of patch #126.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

andypost’s picture

ankithashetty’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
19.54 KB
8.06 KB

Rerolled the patch in #128, thanks!

Suresh Prabhu Parkala’s picture

Status: Needs review » Needs work

The last submitted patch, 132: 2529182-132.patch, failed testing. View results

cgoffin’s picture

FileSize
16.38 KB

I needed the patch against the 9.1.5 version. Here the rerolled patch.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

nikitagupta’s picture

Status: Needs work » Needs review
FileSize
19.48 KB

Rerolled the patch #132

nikitagupta’s picture

The last submitted patch, 136: 2529182-136.patch, failed testing. View results

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/node/node.tokens.inc
    @@ -183,15 +181,14 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
     
             case 'created':
    -          $date_format = DateFormat::load('medium');
    -          $bubbleable_metadata->addCacheableDependency($date_format);
    -          $replacements[$original] = \Drupal::service('date.formatter')->format($node->getCreatedTime(), 'medium', '', NULL, $langcode);
    -          break;
     
             case 'changed':
    +          /** @var \Drupal\Core\Datetime\Entity\DateFormat $date_format */
               $date_format = DateFormat::load('medium');
    +          $date_raw = ($name === 'created' ? $node->getCreatedTime() : $node->getChangedTime());
    +          $date_formatted = \Drupal::service('date.formatter')->format($date_raw, $date_format->id(), '', NULL, $langcode);
               $bubbleable_metadata->addCacheableDependency($date_format);
    -          $replacements[$original] = \Drupal::service('date.formatter')->format($node->getChangedTime(), 'medium', '', NULL, $langcode);
    +          $replacements[$original] = $date_formatted;
               break;
           }
    

    this refactoring seems unrelated and only saves a single line of code at the cost of making the patch bigger and the code harder to understand. I'd suggest to revert these changes.

  2. +++ b/core/modules/taxonomy/taxonomy.tokens.inc
    @@ -95,8 +95,12 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
    +
       if ($type == 'term' && !empty($data['term'])) {
    -    $term = $data['term'];
    +    /** @var \Drupal\taxonomy\TermInterface $term */
    +    $term = \Drupal::service('entity.repository')->getTranslationFromContext($data['term'], $langcode, ['operation' => 'term_tokens']);
     
         foreach ($tokens as $name => $original) {
    

    I know this is copied from node tokens, but the problem is that the operations argument is weird and content_translation only implements it for the default entity_view operation. So I'd suggest to leave out the argument, we might deprecate that thing.

    See #2978048: Unpublished translations should fallback to the original language

  3. +++ b/core/modules/taxonomy/taxonomy.tokens.inc
    @@ -109,9 +113,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
             case 'description':
    -          // "processed" returns a \Drupal\Component\Render\MarkupInterface via
    -          // check_markup().
    -          $replacements[$original] = $term->description->processed;
    +          $replacements[$original] = $term->getDescription();
    

    This too is unrelated refactoring and it's not the same. getDescription() returns the value, not the processed string.

  4. +++ b/core/modules/taxonomy/taxonomy.tokens.inc
    @@ -158,6 +161,11 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
       elseif ($type == 'vocabulary' && !empty($data['vocabulary'])) {
    +    /** @var \Drupal\taxonomy\VocabularyInterface $vocabulary */
    +    $language_manager = \Drupal::languageManager();
    +    $language = $language_manager->getLanguage($langcode);
    +    $original_language = $language_manager->getConfigOverrideLanguage();
    +    $language_manager->setConfigOverrideLanguage($language);
         $vocabulary = $data['vocabulary'];
    

    I'm pretty sure this does nothing.

    The API for config entities is very different and applies to when they are loaded. the vocabulary is already loaded here. This sadly needs to be done whenever token replace is called and the vocabulary is loaded. For example the term:vocabulary token.

  5. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -14,6 +14,8 @@
     class TokenReplaceTest extends TaxonomyTestBase {
     
    +  use AssertTokenReplacementTrait;
    +
       /**
    

    I think @alexpott proposed to not introduce this trait here, makes the test harder to understand.

  6. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -68,12 +80,11 @@ protected function setUp(): void {
     
    -    // Create two taxonomy terms.
    -    $term1 = $this->createTerm($this->vocabulary);
    -    $term2 = $this->createTerm($this->vocabulary);
    +    // Create two taxonomy terms with unsafe names.
    +    $term1 = $this->createTerm($this->vocabulary, ['name' => 'T1 <script>"&lt;name&gt;"</script>']);
    +    $term2 = $this->createTerm($this->vocabulary, ['name' => 'T2 <strong>"&lt;name&gt;"</strong>']);
    

    how is escaping or unsafe names related to translating them? Is it possible this is a rebase of a very old version of this patch that still had that. I think we can drop all these changes.

  7. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -93,13 +104,18 @@ public function testTaxonomyTokenReplacement() {
         $tests['[term:name]'] = $term1->getName();
    -    $tests['[term:description]'] = $term1->description->processed;
    +    $tests['[term:description]'] = $term1->getDescription();
         $tests['[term:url]'] = $term1->toUrl('canonical', ['absolute' => TRUE])->toString();
    

    this needs to be reverted too.

  8. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -93,13 +104,18 @@ public function testTaxonomyTokenReplacement() {
     
    +    // Test to make sure that we generated something for each token.
    +    $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
    +
    

    this is testing the test, I'm not sure what this is for. remove?

  9. +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php
    @@ -108,37 +124,68 @@ public function testTaxonomyTokenReplacement() {
         $tests['[term:name]'] = $term2->getName();
         $tests['[term:description]'] = $term2->description->processed;
    +    $tests['[term:description]'] = $term2->getDescription();
         $tests['[term:url]'] = $term2->toUrl('canonical', ['absolute' => TRUE])->toString();
         $tests['[term:node-count]'] = 1;
    +    $tests['[term:vocabulary]'] = $this->vocabulary->label();
    +    $tests['[term:parent]'] = $term1->getName();
    +    $tests['[term:parent:tid]'] = $term1->id();
         $tests['[term:parent:name]'] = $term1->getName();
    +    $tests['[term:parent:description]'] = $term1->getDescription();
         $tests['[term:parent:url]'] = $term1->toUrl('canonical', ['absolute' => TRUE])->toString();
    +    $tests['[term:parent:node-count]'] = 0;
         $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]';
         $tests['[term:vocabulary:name]'] = $this->vocabulary->label();
    +    $tests['[term:parent:vocabulary]'] = $this->vocabulary->label();
    +    $tests['[term:parent:vocabulary:name]'] = $this->vocabulary->label();
     
    

    Beside the refactoring and some more tokens, I don't see how the fixes are actually asserted here.

    No translations are created, no language options are passed. to the test.

    To be honest, I would consider to just start from scratch with the test. As a bugfix, this is actually a good candidate for writing failing tests first. add the language modules, add a second language, add translations to the term and then fetch the same tokens with different options to get the translated values.

apaderno’s picture

Jeroen Dost’s picture

Does anyone have a patch that works against 8.9.18?

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Eduardo Morales Alberti made their first commit to this issue’s fork.

Eduardo Morales Alberti’s picture

I created a merge request to understand better the changes and to be more clear with the review, we need this for our project.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

AardWolf’s picture

Update patch to 9.5 in work

AardWolf’s picture

matdemeue’s picture

Patch #148 did apply for me on 9.5.4.

quietone’s picture

Suresh Prabhu Parkala’s picture

Re-rolled the patch. Please review.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

hongqing’s picture

Thanks for the contribution. It works with Drupal 10.1.4.

corneboele’s picture

FileSize
18.56 KB

Rerolled for 10.2.x