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 singleTextorTextObject. As a free-text string, it may naturally contain commas.addressLocality,addressRegion,addressCountry: Components of a postal address, which may contain commas just asstreetAddressdoes (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
- Install the schema_metatag module.
- In a metatag configuration for an Organization's postal address (PostalAddress), enter a value containing a comma in the
streetAddressfield (e.g.Suite 400, 1-2-3 Example Street). - View the page source and confirm that the
streetAddressvalue 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
- 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.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | 3593489-fix-neverexplode-branch-order-and-add-missing-fields.patch | 1.05 KB | ueshiy |
Comments
Comment #2
ueshiy commented