The new layout_plugin module provides a mechanism to define layouts for modules like display suite and panels. Done by using the plugin system.
I had the idea to define the library for those layouts in the layout_plugin module.

/**
 * Implements hook_library_info_build().
 */
function layout_plugin_library_info_build() {
  /** @var Drupal\layout_plugin\Plugin\Layout\LayoutPluginManager $layout_manager */
  $layout_manager = \Drupal::service('plugin.manager.layout_plugin');
  $layouts = $layout_manager->getDefinitions();

  $libraries = [];
  foreach ($layouts as $layout) {
    if (isset($layout['css'])) {
      $libraries[$layout['provider'] . '/' . $layout['id']] = [
        'css' => [
          $layout['css'] => [],
        ],
      ];
    }
  }
  return $libraries;
}

This has several issues:
1) The hook only gets loaded when I attach a 'layout_plugin' library, so I need an ugly hack

  $build['#attached']['library'][] = 'layout_plugin/llama';
  $build['#attached']['library'][] = $configuration['layout']['provider'] . '/' . $configuration['layout']['id'];

2) Why don't we need a css category in this hook?

3) Even with the hack it doesn't seem to work, the css file doesn't get loaded

CommentFileSizeAuthor
#8 interdiff.txt715 byteswim leers
#8 2411073-8.patch1.74 KBwim leers
#6 2389203-6.patch1.06 KBwim leers

Comments

wim leers’s picture

Category: Bug report » Support request
Status: Active » Fixed
  1. It's impossible that this hook "only gets loaded when you attach a certain library". All hook_library_info_build() hooks are invoked when libraries are discovered a first time. Therefore, it seems more likely that your true problem is that you're making the set of discovered libraries depend on the set of available plugins. That means that if a new plugin is discovered, hook_library_info_build() isn't re-invoked, and hence the library associated with your newly discovered plugin won't be available yet. It's clearly documented that this hook doesn't run on every request: https://www.drupal.org/node/2374649.
    You can fix this by invalidating the cache tag for discovered libraries (library_info is the associated cache tag) whenever your plugin discovery cache is cleared; hence tying the set of known "layout" plugins to the the set of known "layout" asset libraries. With such a 1:1 relationship, it will work fine.
  2. You do need a CSS category in this hook.
  3. It probably doesn't work because you didn't specify a CSS category.
aspilicious’s picture

Category: Support request » Bug report

I think you're missing the point on 1
And if 2 and 3 is true, the change records are incorrect...
AND if I remember correctly test cases are wrong to than. But I'll have to verify. (bug report for that)

I *know* it doesn't get called on every request. (I followed the entire flow)

$build['#attached']['library'][] = 'layout_plugin/llama';
  $build['#attached']['library'][] = 'my_module/plugin_id';

The point is if I can't define the 'my_module/plugin_id' library in the layout_plugin module.

Why?

Because of the fact that layout_plugin_library_info_build *only* gets invoked when I try to attach a 'layout_plugin' library.
As I want to attach ''my_module/plugin_id" it doesn't call layout_plugin_library_info_build ever...

it will try to call "my_module_library_info_build" which isn't what I want it to do.
You see the subtle difference...

So in the end, this architecture means that each module is responsible for it's own libraries.yml file or hook_library_info_build

This wasn't clear from all the docs I have read.

aspilicious’s picture

Category: Bug report » Support request
aspilicious’s picture

Category: Support request » Bug report
aspilicious’s picture

Status: Fixed » Active
wim leers’s picture

Title: Impossible to define a library with attachments located in another module » Impossible to define an asset library on behalf of another module
Status: Active » Needs review
Issue tags: +Documentation
StatusFileSize
new1.06 KB

#2 is not very clear, but together with what you wrote before I now understand your problem. The problem is that you want to define a library in one extension, on behalf of another extension.

First: the LibraryDiscoveryParser has always been architected this way; hook_library_info_build() is merely a new way in addition to YML files for an extension to define libraries: executed code instead of declared YAML. So it was only natural for it to have this limitation.

Second: I think the reasoning behind the pre-existing pattern was: only an extension can define the asset libraries that it provides — this feels like logical compartmentalization to me.


Of course, none of the above helps you. So let's help.

So here are the two options I see:

  1. The layout_plugin module's plugin manager gets the various layout plugin definitions (as we can see in the code in the IS) and in that layout definition, the associated CSS file is listed. Since Drupal deals only with asset libraries, it's the layout_plugin module's responsibility to generate asset libraries; and it can generate asset libraries of the form layout_plugin/layout-<code>$id — since the layout_plugin module is generating the asset libraries, it also has to be the extension to own them.
  2. The layout_plugin module was designed in a time where it was okay to deal with CSS assets directly; where asset libraries were not yet required (though it was known to be the goal for 8.0). So let's fix that design flaw and instead of having layout plugin definitions list a CSS asset, have them list an asset library instead, with the module containing the plugin (mymodule) also containing a mymodule.libraries.yml file containing that asset library.

RE: CSS categories: You're right, the example in the CR and docs is wrong; it doesn't specify a category for CSS assets, whereas it should. But that's a tiny oversight in the grand scheme of things, and #2389203: Validate the CSS categories in libraries.yml files. will help with that. Attached patch fixes the docs.

aspilicious’s picture

Thanks for all the info

1. Actually doesn't work because the library dynamically added only will look in the layout_plugin module. I can't point to css defined in another extension. Unless that extension defined a library which I can add as dependency. But that makes 2 a better solution.

There are also incorrect tests. That was the main reason for my confusion.

/**
 * Implements hook_library_info_build().
 */
function common_test_library_info_build() {
  $libraries = [];
  if (\Drupal::state()->get('common_test.library_info_build_test')) {
    $libraries['dynamic_library'] = [
      'version' => '1.0',
      'css' => [
        'common_test.css' => [],
      ],
    ];
  }
  return $libraries;
}
wim leers’s picture

StatusFileSize
new1.74 KB
new715 bytes

Option 2 is the better option anyway, sorry if that wasn't clear.


Updated the patch to update the incorrect test.

aspilicious’s picture

Title: Impossible to define an asset library on behalf of another module » Fix issues with missing categories for css assets
Status: Needs review » Reviewed & tested by the community

Ok thnx!

wim leers’s picture

Title: Fix issues with missing categories for css assets » Fix documentation of hook_library_build_info()
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Test and docs changes are not blocked by beta. Committed 8e0bcfe and pushed to 8.0.x. Thanks!

  • alexpott committed 8e0bcfe on 8.0.x
    Issue #2411073 by Wim Leers: Fix documentation of...

Status: Fixed » Closed (fixed)

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