Determine snippet origin (site folder or plugin)

I am using a one-pager modular page setup similar to the following code in one of my templates:

foreach($page->children()->published() as $section)
  echo snippet($section->intendedTemplate(), ['snippetdata' => $section]);

This is working fine, but now I would like to find a way to determine, where the snippet was loaded from, i.e. the site/snippets folder or from a plugin.

The reason is that I want to load some specific assets, in case the snippet was loaded from a plugin. How can I achieve this?

Thanks in advance!

Is this a question about Kirby 3? Please mark your topic accordingly.

If it is kirby 3… snippets in site/snippets take precedence. If you have two snippets of the exact same name with one copy in the snippets folder and the other also declared in a plugin, the one in site/snippets folder will be loaded and the one the plugin ignored. Therefore, to know it’s coming from the plugin, simply don’t also copy it over to site/snippets.

I cant remember if this also works with Kirby 2, it’s possible that it does.

Yes, it’s about Kirby 3. Unfortunately, I can only select a single pre-determined tag and I felt Plugins was more fitting. Anyway, I used Kirby 3 now and added plugin as a custom tag.

Regarding snippet priority in the site folder and in plugins, I know the precedence rules. However, that doesn’t help my use case. My main goal is to be able to install a plugin and then automatically load the respective assets always when the snippet is called. So I need to know, whether the snippet comes from a plugin and I also need to know the actual plugin to be able to use the assets from there. I also want to handle this exclusively from the plugin, so that no changes to other files outside the plugin are needed, except maybe for the function calling the snippet as referenced in the initial post.

Any solution for this?

Hm, the snippet helper only returns a string. Maybe if you create your custom snippet component, you can achieve what you want.

By assets i’m assuming this is javascript and CSS? You can put the js() and css() helpers inside your snippet. link elements are valid in the body with html5, and i’m assuming these are very small bits of code so performance wise it should not be a problem. They will of course load sooner if you put css in the head.

That’s an option, but it appears to be a bit oversized for my use case. Anyway, I will keep this option in mind. Thanks

That’s also an option, thanks!
I’m not too happy with links in the body, though. Another working solution might be to parse all plugins and check for the requested template to be able to add the links in the header. This is not an elegant solution, either, but I will consider and use one of these approaches.

Anyway, it seems there is not a ready-made convenience function in Kirby 3, which already does what I want. Not a problem, I just wanted to check whether I’m missing an existing easy and(!) elegant solution. :wink:

Oh, I thought you really wanted to listen if a snippet was actually included or not and then insert the the assets on the fly.

Well, you want things to happen automatically, requiring just the installation of the plugin. The only way i know of to do that is call the assets from the snippet. You could set something in the session and check its value but that will require to add something where you want the assets to come out.

Another way, but a bit off the wall, is to use a third party tool like HTML Simpledom which will let you prepend your assets programatically to the closing head tag. I would only take that approach as an absolute last resort though.

I thought about something like that as well, modify the Dom with a route:after hook or something like that, but that seems rather exaggerated.

Ideally, yes, but after all, the plugins I’m thinking about are only to be used by me and my idea for their usage is that the plugins provide snippets and associated assets. The snippets may be overridden on a case-to-case basis, but the assets from the ‘original’ snippet (from the plugin) should then still be loaded.

That’s surely too much for my use case, but thanks.

I think I will go with the option to check the snippets to be included before calling my header snippet and then provide the assets as parameters to the header snippet. This requires me to have some related code in the header snippet (i.e. outside of the plugins as @jimbobrjames correctly noted), but it feels like the best solution for me at the moment.

I do it this way…

<?= snippet('global/footer', ['scripts' => true]) ?>

Then inside the snippet…

<?php if($scripts == "true"): ?>
  <?= snippet('js') ?>
<?php endif ?>