6

I'm having trouble understanding how to attach a library to views. I want my assets to be included in /foo but not in /bar. I've read through the documentation on this more than once and from my understanding this is achieved by using preprocess, such as:

function my_theme_preprocess_page(&$variables) {
  if($variables['is_front']){
    $variables['#attached']['library'][] = 'my_theme/my_library';
  }
}

I'm new to Drupal so forgive my inherit ignorance, but what does $variables contain? 'is_front' is easy enough, but how do I apply this to views or content types?

Thank you all in advance.

6
  • Usually I attach my assets on twig template. All assets will be included only once. I think this is the best option when you are theming. (for me make more sense put them together, twig template + css/js). Please clarify what you really need accomplish.
    – Vagner
    May 6, 2016 at 16:29
  • I believe you are asking two questions at the same time. Can you post the second question as a separate question? May 6, 2016 at 16:33
  • @Vagner I'm just trying to attach assets to a view. Can you show me how you accomplish this through twig? I'm not sure what I need to be naming the files. May 6, 2016 at 16:49
  • 1
    @Neograph734 Sorry about that, removed the question that was unrelated to the title. May 6, 2016 at 16:49
  • The Devel module is very helpful in these situations when you want to see the structure of an array or what value a variable has. It's currently only a dev module for Drupal 8 but could be worth checking out.
    – Fever
    May 6, 2016 at 17:08

5 Answers 5

8

but what does $variables contain?

A couple of render arrays and some values that be used by twig template. Your best option is check de documentation for each preprocess function to see what are included in $variables. Docs link template_preprocess(&$var) better explanation about preprocess functions and default list of template preprocess functions

but how do I apply this to views or content types?

For me the best option is your twig template file by including this line.

{{ attach_library('my_theme/my-library') }}

No matter how many times this will be 'attached' only one will be downloaded (or aggregate). And only will added if this particular template will be rendered.

More info about Twig debug is here

1
  • This is my new favorite method, it's nice and granular. May 6, 2016 at 17:34
8

One way to do it via your theme:

Set up your js as a library in your mytheme.libraries.yml file:

library-name:
  js:
    js-file-location/js-file-name.js: {}

Call your library in a preprocess hook in your mytheme.theme file:

/**
 * Implements hook_preprocess_views_view().
 */
function mytheme_preprocess_views_view(&$vars) {
  $vars['#cache']['contexts'][] = 'route';
  if ($vars['view_array']['#name'] == 'view_name') {
    $vars['#attached']['library'][] = 'mytheme/library-name';
  }
}

You'll need to replace these parts with your own actual code:

  • js-file-location - is it in a folder?
  • js-file-name - include the extension, I've used .js in this example
  • library-name - call it whatever you like
  • mytheme - the machine name of your theme

Note the cache context in this example is set to cache per route. It's important to know about it but outside the scope of this question.

Source: Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 theme

9
  • Perfect! Could you give me a little more info on the cache context? Tried reading the Docs, but it went way over my head... Aug 28, 2017 at 21:57
  • 1
    @ChrisHappy, it's basically how Drupal decides how to set the cache for whatever the context is attached to. Anything else will have to be a new question because comments is not the place for this =)
    – Darvanen
    Aug 29, 2017 at 1:36
  • Nice. I've been looking for a solution to adding libraries to paths for a while. This looks to be a good one.
    – Jaypan
    Mar 15, 2019 at 3:20
  • 1
    I don't like adding libraries within templates. Templates are for formatting data, adding libraries does not fit this paradigm. While Drupal allows it, I would never do it myself.
    – Jaypan
    Mar 20, 2019 at 6:51
  • 1
    I use this technique, but to identify the view I access the view id, which I find more readable: $view = $vars['view'] ; if ($view->id() == 'view_id') $vars['#attached']['library'][] = 'my_theme/library-name' ; Apr 21, 2020 at 7:28
1

I made a module for that for Drupal 8: Views Attach Library.

The Views Attach Library module is designed to attach multiple libraries (JS and CSS) to views by providing just a library name.

How to use?

Installation is as simple as copying the module into your modules/contrib directory, then enabling the module.

To add a library to a view follow below steps:

  1. Create or edit view
  2. Find Attach Library section
  3. Click on add library or edit library
  4. Add or edit library name in textfield.
0
0

As per the documentation of template_preprocess_page():

See the page.html.twig template for the list of variables.

To know if a page is a view, please refer to: hook_preprocess_page(): how to tell a views page?

The content type is available as a property of the $node variable: $variables['node']->type.

0
0

Using hook_views_pre_render() a library can be attached to a view with JS/CSS.

<?php
/**
 * Implements hook_views_pre_render().
 */
function hook_views_pre_render(ViewExecutable $view) {
  if (isset($view) && ($view->storage->id() == 'test_view')) {
    $view->element['#attached']['library'][] = 'custom/view.lib';
  }
}

Here 'custom/view.lib', custom is the module/theme name and view.lib is the library name.

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.