Hello im finding out how i can create a less file, with all the modules active on the website.
I like to generate a efficient main css file with no modules that are inactive/not used on the website.
So for i came up with the following code.
The hook will look for page updates, $site->moduleList() will list the active modules.
This will make or overwrite modules.less
f::write( kirby()->roots()->assets() . '/less/modules.less' , $content , false);
This code is a draft/doesn’t work.
kirby()->hook('panel.page.update', function($page) {
$kirby->plugin('modules');
$templates = $site->moduleList()->pluck('template', null, true);
$less = array_map(function($template) {
return '@import' . $template . '.less' . ';' . '\n';
}, $templates);
$content = $less;
f::write( kirby()->roots()->assets() . '/less/modules.less' , $content , false);
});
the result should be a modules.less file with the active modules,
@import "modules/accordion.less";
@import "modules/pricing-cards.less";
@import "modules/image-carousel.less";
@import "modules/tabs.less";
@import "modules/progress-tracker.less";
@import "modules/testimonials.less";
@import "modules/image-hero.less";
Im wondering where it goes wrong, can someone help me with this?
The $page->moduleList()
method only returns the modules of the given page. So if you call $site->moduleList()
, you don’t get the modules that are used on the site, but you get the modules on the top-level (which doesn’t make sense as the $site
doesn’t have a template and therefore also no modules on its own).
To get a list of “active” modules, you need to loop through the site’s index like this:
$activeModules = [];
foreach(site()->index()->filterBy('isModule', true) as $m) {
$moduleName = $m->module()->name();
if(!in_array($moduleName, $activeModules)) $activeModules[] = $moduleName;
}
Embedded into a hook this would look something like this (untested!):
kirby()->hook('panel.page.*', function() {
// get a list of modules that are currently active in the site
$activeModules = [];
foreach(site()->index()->filterBy('isModule', true) as $m) {
$moduleName = $m->module()->name();
if(!in_array($moduleName, $activeModules)) $activeModules[] = $moduleName;
}
// convert the list to a LESS string
$content = array_reduce($activeModules, function($carry, $template) {
return $carry . '@import' . $template . ".less;\n";
}, '');
// write the LESS file
f::write(kirby()->roots()->assets() . DS . 'less' . DS . 'modules.less', $content);
});
You could optimize this to only update the LESS file with the changes from the page that called the hook. That would be a lot faster to process (better performance), but more complex to implement.
Hello Lukas,
Many thanks!
I need to debug it further… until now i’ve tested the following.
This part of de hook works in config.php
kirby()->hook('panel.page.*', function() {
// convert the list to a LESS string
$content = 'test12';
// write the LESS file
f::write(kirby()->roots()->assets() . DS . 'less' . DS . 'modules.less', $content, false);
});
This Part works on a page, but not in the hook.
<?php
$activeModules = [];
foreach($site->index()->filterBy('isModule', true) as $m) {
$moduleName = $m->module()->name();
if(!in_array($moduleName, $activeModules)) $activeModules[] = $moduleName;
}
// convert the list to a LESS string
$content = array_reduce($activeModules, function($carry, $template) {
return $carry . '@import' . '"' . $template . '.less";' . "\n";
}, '');
// write the LESS file
f::write(kirby()->roots()->assets() . DS . 'less' . DS . '_md.less', $content, false);
?>
Do you get an error message? My first thought would be that the plugin doesn’t get loaded correctly in the Panel.
By the way: You don’t need to pass the third param to f::write()
. false
is the default anyway. 
I didn’t got a error message, in the hook i changed $site to site() .
Now it works, extremely happy!
Cheers, Maarten
kirby()->hook('panel.page.*', function() {
$activeModules = [];
foreach(site()->index()->filterBy('isModule', true) as $m) {
$moduleName = $m->module()->name();
if(!in_array($moduleName, $activeModules)) $activeModules[] = $moduleName;
}
// convert the list to a LESS string
$content = array_reduce($activeModules, function($carry, $template) {
return $carry . '@import' . ' "' . $template . '.less";' . "\n";
}, '');
// write the LESS file
f::write(kirby()->roots()->assets() . DS . 'less' . DS . '_modules.less', $content, false);
});
``
Oh, of course. 
Glad it works now.
1 Like
Hi there,
are there any additional plugin needed to get this gem running? Can’t get this to work, but its exactly what i need 
Thanks
Fabian
@gfx_dude Do you mean other plugins in addition to the modules plugin?
@texnixe right. i’m using the modules plugin already and i also want to load css/less only if the module is active. this here seems to be a pretty usefull solution