4

Now that drupal_add_js(...., 'inline') is no longer possible, how can I inject dynamic Javascript from a custom module's Controller? (I'm trying to upgrade a D6 module with as little refactorings as possible)

2

You can approach it a number of ways. You can add it to the #attached property in hook_preprocess_page or hook_preprocess_X. You can add it as a library in the #attached property of the array being returned for that request by the controller.

You will need to define some library definitions, as well.

See: https://www.drupal.org/node/2169605 and https://www.drupal.org/developing/api/8/assets

  • 2
    I like that this suggests to use #attached instead of inline JavaScript as that is much preferred. It is still possible to inject it inline with _drupal_add_html_head. For a deep discussion/debate about the specific use case where the order of JavaScript matters, see drupal.org/node/2391025. – mradcliffe Apr 5 '16 at 16:03
  • 1
    I have also seen {{ attach ... }} called from a twig template.drupal.org/node/2456753 – Kevin Apr 5 '16 at 16:21
  • @mradcliffe I can't find any details (or code in core) about _drupal_add_html_head apart from a single reference in that discussion. – Nic Apr 11 '16 at 8:47
2

If you want inline javascript in order to pass some computed variables, then it seems that the only way to do it in D8 is to use a combination of drupalSettings and an attached library. The following snippets are copied from Attaching configurable JavaScript in the official docs.

In mymodule.libraries.yml, declare a library containing your javascript file, with a dependency on drupalSettings (and on jQuery):

cuddly-slider: version: 1.x js: js/cuddly-slider.js: {} dependencies: - core/jquery - core/drupalSettings

Then, when building (or altering) your render array, attach the library and save something to the settings:

$build['#attached']['library'][] = 'fluffiness/cuddly-slider'; $build['#attached']['drupalSettings']['fluffiness']['cuddlySlider']['foo'] = 'bar';

Presumably, you have something more interesting than 'bar'. Finally, access the setting in your javascript file as drupalSettings.fluffiness.cuddlySlider.foo.

1

In some cases you would really want to add a snippet somewhere inside your code, inside script tags. This is how you do it: Let's say you want the snippet inside a controller. Create a custom module and add a file named google_snippet.routing.yml with this content:

google_snippet.page:
  path: '/my-custom-path'
  defaults:
    _title: 'Here is my snippet'
    _controller: '\Drupal\google_snippet\Controller\snippetPage::render'
  requirements:
    _permission: 'access content'

Also add a file google_snippet.module file to make the controller aware of a template file:

function google_snippet_theme($existing, $type, $theme, $path) {
  return [
    'google_snippet' => [
      'variables' => [
        'snippet' => NULL
      ],
    ],
  ];
}

Create a file in src/Controller/ named snippetPage.php.

namespace Drupal\google_snippet\Controller;
use Drupal\Core\Controller\ControllerBase;

class snippetPage extends ControllerBase {
  public static function render() {
    return [
      '#theme' => 'google_snippet',
      '#snippet' => '
         <script>
          INSERT YOUR SNIPPET HERE
        </script>
      ',
    ];
  }
}

Then, inside a templates folder of your module a file named google-snippet.html.twig with the following content:

{{ snippet|raw }}

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.