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
Comments
Comment #1
wim leershook_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_infois 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.Comment #2
aspilicious commentedI 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)
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.
Comment #3
aspilicious commentedComment #4
aspilicious commentedComment #5
aspilicious commentedComment #6
wim leers#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
LibraryDiscoveryParserhas 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:
layout_pluginmodule'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 thelayout_pluginmodule's responsibility to generate asset libraries; and it can generate asset libraries of the formlayout_plugin/layout-<code>$id— since thelayout_pluginmodule is generating the asset libraries, it also has to be the extension to own them.layout_pluginmodule 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 amymodule.libraries.ymlfile 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.
Comment #7
aspilicious commentedThanks 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.
Comment #8
wim leersOption 2 is the better option anyway, sorry if that wasn't clear.
Updated the patch to update the incorrect test.
Comment #9
aspilicious commentedOk thnx!
Comment #10
wim leersComment #11
alexpottTest and docs changes are not blocked by beta. Committed 8e0bcfe and pushed to 8.0.x. Thanks!