Problem/Motivation

SchemaNameBase::neverExplode() lists fields (such as streetAddress and reviewBody) that are intended to never be split by the separator character. However, these fields are still being split by commas in practice.

The root cause is the order of conditional branches in processItem(). For fields where $this->multiple() returns TRUE when $key === 0, $explode is set to TRUE at that point and the code never reaches the neverExplode() check. Similarly, when $key !== 0, hasSeparator() is evaluated before neverExplode(), so if a separator is configured, neverExplode() is ignored entirely.

// Current code (broken implementation)
protected function processItem(&$value, $key = 0) {
  if ($key === 0) {
    $explode = $this->multiple();         // ← If TRUE, neverExplode() is never reached
  }
  elseif ($this->schemaMetatagManager->hasSeparator()) {
    $explode = TRUE;                      // ← Evaluated before neverExplode()
  }
  else {
    $explode = !in_array($key, $this->neverExplode());  // ← Not always reached
  }

In addition, neverExplode() is missing several fields that can legitimately contain commas:

  • @id: Used as a Schema.org identifier, typically in URL format. Commas may appear as query parameter separators (RFC 3986 permits commas as reserved characters within URLs).
  • url: Same reason as @id.
  • description: Per the Schema.org specification, the expected value is a single Text or TextObject. As a free-text string, it may naturally contain commas.
  • addressLocality, addressRegion, addressCountry: Components of a postal address, which may contain commas just as streetAddress does (e.g. Suite 400, Building B).

Note that the sameAs field is intentionally excluded from neverExplode(), as its field description explicitly states Comma separated list of URLs, meaning comma-delimited input is by design.

Steps to reproduce

  1. Install the schema_metatag module.
  2. In a metatag configuration for an Organization's postal address (PostalAddress), enter a value containing a comma in the streetAddress field (e.g. Suite 400, 1-2-3 Example Street).
  3. View the page source and confirm that the streetAddress value has been split at the comma, resulting in malformed JSON-LD output.

Proposed resolution

Fix the conditional branch order in processItem() so that neverExplode() is checked before hasSeparator(). Also add the missing fields to neverExplode().

diff --git a/src/Plugin/metatag/Tag/SchemaNameBase.php b/src/Plugin/metatag/Tag/SchemaNameBase.php
index 81afd98fb3..bbcd76fce3 100644
--- a/src/Plugin/metatag/Tag/SchemaNameBase.php
+++ b/src/Plugin/metatag/Tag/SchemaNameBase.php
@@ -266,8 +266,14 @@ public function pivotItem(array $array) {
    */
   protected function neverExplode() {
     return [
+      '@id',
       'name',
+      'url',
+      'description',
       'streetAddress',
+      'addressLocality',
+      'addressRegion',
+      'addressCountry',
       'reviewBody',
       'recipeInstructions',
     ];
@@ -280,11 +286,11 @@ protected function processItem(&$value, $key = 0) {
     if ($key === 0) {
       $explode = $this->multiple();
     }
-    elseif ($this->schemaMetatagManager->hasSeparator()) {
-      $explode = TRUE;
+    elseif (in_array($key, $this->neverExplode())) {
+      $explode = FALSE;
     }
     else {
-      $explode = !in_array($key, $this->neverExplode());
+      $explode = $this->schemaMetatagManager->hasSeparator();
     }

Workaround

It is possible to partially work around this issue by changing the separator character in the global metatag settings to something other than a comma.

However, this workaround has the following drawbacks:

  • Existing data that was entered with the assumption of comma-separated values (including fields such as sameAs, where comma-delimited input is intentional) may no longer work correctly after the change.
  • Even if the separator is changed to a different character, the underlying problem remains: if a user's input string happens to contain that character, fields that should never be split will still be split unintentionally.

For these reasons, changing the separator character is not recommended as a solution.

Remaining tasks

  1. Review the patch.

User interface changes

None.

API changes

Additional fields have been added to the return value of SchemaNameBase::neverExplode(). Any custom implementations that override this method should be reviewed and updated as necessary.

Data model changes

None.

Comments

ueshiy created an issue. See original summary.

ueshiy’s picture

StatusFileSize
new1.05 KB