Metatag appears to improperly escape characters such as quotation marks in text fields. I have a hook (see below) that lets users enter a "social media headline" to be used in title metatags, in place of the actual node title. But when that field contains quotation marks (eg, This is my "social" headline), the quotation mark is double-escaped, so the og:title tag looks like this:

<meta property="og:title" content="This is my &amp;quot;social&amp;quot; headline" />

This does not happen if quotation marks are used in the normal title field. In that case, the tag is produced properly:

<meta property="og:title" content="Testing &quot;Quotes&quot; in title" />

I've been having this problem on one of my sites and have been able to consistently reproduce it on a fresh install of Drupal 7.42 plus Metatag 7.x-1.13 and Entity 7.x-1.6:

  1. Add new "Social Media Headline" text field to the article content type. Set machine name to field_social_hed, and otherwise use default field settings.
  2. Add this hook to template.php (I used default Bartik theme):
    function bartik_metatag_pattern_alter(&$pattern, &$types, $tag_name) {
        if (strpos($pattern, 'title') !== FALSE) {
          $wrapper = entity_metadata_wrapper('node', $types['node']);
          try {
            if ($val = $wrapper->field_social_hed->value()) {
              $pattern = str_replace('title','field_social_hed', $pattern);
            }
          }
          catch (EntityMetadataWrapperException $exc) {
            watchdog('america', 'No social hed field'. __FUNCTION__ . '() <pre>' .  $exc->getTraceAsString() . '</pre>',NULL, WATCHDOG_ERROR);
          }
        }
      }
    
  3. Create test article and insert text with quotation marks into the social media headline field, save and view source. Observe bad escaping in og:title tag.
  4. Create another test article and insert text with quotation marks into the node title field. Save and view source. Observe correct escaping in og:title tag.

I'll post a patch if I find one, but so far I haven't been able to figure out where this is happening. Any hints on where to look or what to try would be very welcome.

Comments

kenficara created an issue. See original summary.

kenficara’s picture

Issue summary: View changes
kenficara’s picture

Sorry, I should have mentioned that as of the date of this posting, this also happens with 7.x-1.x-dev.

damienmckenna’s picture

Ok, we need to expand the tests in MetatagCoreStringHandlingTest to test field tokens, because right now it's only testing the title. We may also need to verify how it works with normal field tokens and also Entity API -based tokens, which are different.

damienmckenna’s picture

Version: 7.x-1.13 » 7.x-1.x-dev
joelstein’s picture

Status: Active » Needs review
StatusFileSize
new532 bytes

I'm not sure if this helps in the discussion, but here's an easy way to see this in action:

  1. Install clean Drupal, latest Metatag dev, and CKEditor module.
  2. Create a new page with body containing an ampersand.
  3. View the source code to see a double-encoded ampersand in the 'description' meta tag.

Here's a patch which uses htmlspecialchars_decode to decode things like ampersands, quotes, etc. It uses ENT_QUOTES since that's what check_plain() uses.

damienmckenna’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Thanks. I'm glad that the existing tests still pass. However, I think we need an extra test to confirm the encoding works as intended, maybe adding something to the tests/metatag.string_handling.test file?

damienmckenna’s picture

Status: Needs work » Needs review
StatusFileSize
new7.7 KB

This is an updated test for string encoding that shows the current codebase works correctly with values inserted into fields.

damienmckenna’s picture

Status: Needs review » Fixed

I've committed the patch in #8.

  • DamienMcKenna committed 202d99b on 7.x-1.x
    Issue #2667214 by DamienMcKenna: Improved tests for string encoding.
    
damienmckenna’s picture

@joelstein: Please examine the data stored in the database for the body field when created using the ckeditor module vs when it's inserted using Drupal core's text formats, I would wager that the ckeditor module is storing the data incorrectly.

joelstein’s picture

Status: Fixed » Needs work

@DamienMcKenna: I performed the steps in #6 again, and the issue still exists. With CKEditor installed, the data is not stored incorrectly in the database:

<p>This has an &amp; in it.</p>

joelstein’s picture

...and even without CKEditor installed, if I have an & in the body field, I see it double encoded in the 'description' metatag.

damienmckenna’s picture

Status: Needs work » Fixed
StatusFileSize
new48.7 KB

@joelstein: I just tested on a barebones install. If I add a bare ampersand to a node page it works correctly:

Ampersands.

Is it possible you have something else interfering with the tokens?

damienmckenna’s picture

StatusFileSize
new104.34 KB

I forgot to show what the meta tags were like:
Ampersands in meta tags

joelstein’s picture

Thanks for helping me troubleshoot this.

In your example, you entered What. & thing., which means it's not storing the HTML representation of an ampersand (&amp;), but just the ampersand itself. In my example, I'm storing the HTML: <p>This has an &amp; in it.</p>. In this case, whether or not I have Filtered HTML or Full HTML text format selected, I see the HTML-encoded ampersand double-encoded in the metatag.

Since Metatag is stripping HTML tags, we should also decode special HTML entities, so that they will be ready to be re-encoded when displayed as a meta tag. Is this making sense? :)

damienmckenna’s picture

Status: Fixed » Needs review
StatusFileSize
new3.37 KB

@joelstein: ok, you are correct. I looked up _filter_htmlcorrector(), etc and they all either rely upon PHP's automatic UTF8 encoding through e.g. DOMDocument->loadHTML() or use decode_entities().

Lets try this.

damienmckenna’s picture

Status: Needs review » Fixed

Committed. Thanks for the help, joelstein.

joelstein’s picture

Perfect, thank you!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.