Run script on Site Tab Save

Hi!

What would be the best approach to run scripts on Site Tab (or similar) saving?

I have integrated Less/CSS PHP compiler, and at the moment it works like this:

  • Plugin for LESS compiling is added to site/plugins/
  • It is called from within a snippet in site/snippets/
  • Which has options that are added from one site.yml tab (panel tab)
  • Snippet is called from header.php
  • And on every page load it compiles new stylesheet

I added the option to turn off styling when done, and that switch also removes that snippet call from header.php.

It is working great like this, but it is not ideal of course.
The ideal would be that it runs compiling on site tab save only.
But of course, not any site save but only on that specific styling options.

Checked out some site update options from the docs, but not sure what direction would be the best.
Also, I am open to some other approaches, that are maybe better.

Thank you in advance.

What about a button to trigger stylesheet generation: https://getkirby.com/plugins/bnomei/janitor

There is no hook that listens only to a specific tab, although you could of course listen to changes in specific fields in that tab and only re-generate then. (https://getkirby.com/docs/reference/plugins/hooks/site-update-after)

1 Like

Hey, @pixelijn, thanks for the fast response.

Yes, a very nice idea with Janitor, I’ll check it right away, know about that plugin.
Also, that hook is worth looking at.

Thank you very much, will get back with solution.

Hi,

But is it even possible to run/execute/access a snippet from 'site.update:after'?
Can’t get it to work no matter I try…

Could you post your code, please?

Hi, Sonja, thank you for the reply.

What code do you mean?

header.php is calling less.php snippet

<?php if($site->stylingSwitcher() == "true"): ?>

    <?php snippet('less') ?>

<?php endif ?>

And less.php snippet is connecting site.yml options to lessphp plugin

...
// various options
... 

// Activate library.
require_once 'site/plugins/lessphp/lib/Less/Autoloader.php';
Less_Autoloader::register();

$parser = new Less_Parser($options);

// Compile content
$parser->parseFile($sourceFile);

// Variables modification
$parser->ModifyVars( 
    array(
        '@global-font-family'=>h($site->textFontFamily()),
        '@global-font-size'=>h($site->textFontSize()) . 'px',
        '@global-primary-font-family'=>h($site->headingFontFamily()),
        '@global-primary-font-weight'=>h($site->headingFontWeight()),
        '@global-secondary-font-family'=>h($site->secondaryFontFamily()),
        '@global-secondary-font-weight'=>h($site->secondaryFontWeight()),
        '@global-secondary-font-style'=>h($site->secondaryFontStyle()),
        '@global-color'=>esc($site->textColor()),
        '@global-emphasis-color'=>esc($site->textEmphasisColor()),
        '@global-muted-color'=>esc($site->textMutedColor()),
        '@global-link-color'=>esc($site->textLinkColor()),
        'global-inverse-color'=>esc($site->inverseColor()),
        '@global-background'=>esc($site->defaultColor()),
...
// And so on
...

And it compiles many .less files from assets/app/ folder, combining those variables values.

It does some caching, but I can not do caching of those variables from site.yml so for as long the switch in site.yml is turned on (true) it compiles on every page refresh. Only when switch is off, snippet isn’t called.

It actually works great, but I am a perfectionist, and I know some users will forget to turn it off.
So, best would be to run/activate that snippet on selected fields save. Or to have a button with Janitor field.

But I didn’t find anywhere in the docs or in the forum that anybody called snippet from hook, or anywhere else except the template file.

My code in its best got this far :joy:

'bnomei.janitor.jobs' => [

      'aweSomeItCouldBe' => function (Kirby\Cms\Page $page = null, string $data = null) {

        F::load($kirby->root('snippets') . 'less.php');

          return [
              'status' => 200,
              'label' => 'Success',
          ];

      },

  ]

The same and various similar things I tried also with site.update:after hook.

I don’t really see the purpose of the snippet. The code from the snippet should either go into the janitor callback or into the hook.

If you want to use a hook, you can still check if certain field were changed or not, as I already suggested above and only execute your code then.

Yes, Janitor would be best probably because hook would need to check many fileds.

But, can you give me some hint or code example how could code for Janitor custom job look.
That plugin, although really great, has very modest documentation.

Or example for the hook if it is easier for you.
Actually would rather use hook, don’t like to rely too much on plugins.

I haven’t tried to create custom jobs myself yet and yes, the documentation is probably only useful for the cognoscenti. But I think you do your job within the callback and then return a success status code on success and a fail on fail.

With the hook, it’s the same. I’d create an array of fields to check (guess those are the ones in your array above, and if once field is changed, you call your code.

Hi, Sonja.
Ok, I will play with that, and try to transfer the whole less.php snippet to custom job, or the hook.
We’ll see what happens.

If it turns out to be really good, I might even publish that Less/CSS compiler as a plugin with complete solution.

Thank you for your help!