I want to output a JSON string as part of a data attribute on an HTML tag for a template in Drupal 7. For the life of me, I cannot figure out why it does not work (works perfectly in 8+).

I need to list a set of image urls and media sizes which is parsed by Javascript later.

In template.php:

    $variables['background_images'] = [];

    $variables['background_images'][] = [
      'srcset' => 'https://placeimg.com/1600/600/tech, https://placeimg.com/3200/1200',
      'media' => '(min-width: 100rem)',

    $variables['background_images'][] = [
      'srcset' => 'https://placeimg.com/1600/600/tech, https://placeimg.com/3200/1200',
      'media' => '(min-width: 48rem)',

    $variables['background_images'] = json_encode($variables['background_images']);

In the tpl file:

<div data-background="<?php print $background_images; ?>"></div>

The output is a mixed bag of issues in the browser. The URLs are escaped, and there are far more double quotes than I entered:

data-background="[{" srcset":"https:\="" \="" placeimg.com\="" 1600\="" 600\="" tech,="" https:\="" 3200\="" 1200","media":"(min-width:="" 100rem)"},{"srcset":"https:\="" 48rem)"}]"

I can't figure out why there is an extra spacing on the keys or why it escapes early and breaks the rest of it. It looks right (to me) with xdebug, but when its printed to the browser its wrong.

A second way I also tried (generate example data):

    $items = [];

    for ($x = 0; $x < 3; $x++) {
      $items[$x] = [
        'srcset' => 'https://placeimg.com/1600/600/tech, https://placeimg.com/3200/1200',
        'media' => '(min-width: 100rem)',

    $variables['background_images'] = drupal_json_encode($items);

enter image description here

  • Try json_encode($variables['background_images'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) instead
    – Clive
    Nov 2 at 17:44
  • Actually just try drupal_json_encode($variables['background_images']), it does the same but less chars
    – Clive
    Nov 2 at 17:45
  • Tried that, its a similar result (super escaped and malformed).
    – Kevin
    Nov 2 at 17:48
  • it seems to be choking on this part: (min-width: 48rem)
    – Kevin
    Nov 2 at 17:58

It's the double quotes that are causing the problem, whether they've been encoded with JSON_HEX_QUOT or not. They must be confusing a parser or something somewhere in the render pipeline.

Fortunately it's an easy fix, just use single quotes for the HTML attribute:

<div data-background='<?php print $background_images; ?>'></div>

The same problem doesn't occur for single quotes, as long as you use drupal_json_encode rather than json_encode (or json_encode with the JSON_HEX_APOS flag). So if your strings ever include single quotes in future this will still work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.