Styles and scripts depending on attached content

Hi guys!

I’m looking for solution to add css/js files to document node when special element is added as element of a page.
Maybe anybody know good solution for it instead of flowquery by nodetype on documentnode
Is there any plugin/extension that helps with it?

FlowQuery the for the existence of a specific nodeType or mixin is not that bad. It is the price to pay for beeing able to render each part of the fusion tree. Everything else would require communication between distant branches of fusion.

Also make sure that you add an @cache to the fragment as otherwise the header is cached with the document and will not be updated once you add the contents of your page.

I beg to differ :slight_smile:
It might not be a (big) performance issue but IMO we should built a mental barrier between node types and the components that are rendered on your site.
I assume included CSS/JS is about the latter and might not always be about the former so I think it should be possible to register the required assets from the rendering part (i.e. the component) in order to load them dynamically.

Maybe something like this could work:

1. Render a placeholder into the page source code:

prototype(Your.Site:Page) {
    head {
        dynamicAssetsPlaceholder = '###DYNAMIC_ASSETS###'
        dynamicAssetsPlaceholder.@position = 'after javascripts'
   }
}

2. Require assets from your component (and store them in some kind of singleton):

prototype(Your.Site:Component.SomeComponent) {
    @process.requireAssets = Your.Site:RequireAssets {
        css = 'resource://Your.Site/Some.css'
    }
}

3. Process the page and replace the placeholder

 prototype(Your.Site:Page) {
    @process.includeDynamicAssets = Your.Site:IncludeDynamicAssets
 }

This is obviously just a rough idea and I might miss something.

And apart from that all, the whole idea of loading dynamic assets might be a dangerous path that leads to worse performance in the end (e.g. the overhead of requesting multiple assets vs one minified blob…)

While i generally agree that this is not what nodeTypes are for, i think using mixins as markers for such cases is okish aswell and quite easy to understand and debug.

prototype(Your.Site:Page) {
    head {
        javascripts.evilJQueryPlugin = ...
        javascripts.evilJQueryPlugin.@if.isNeeded = ${q(documentNode).children('main').find('[instanceof Your.Site:Mixin.RequiresEvilJQueryPlugin]').is()}
   }
}

For a cleaner approach how about adding those js- or css-requirements as special data-attributes and later use an http-component to render them to the header. That could even be extracted into a dedicated package. Using a special prototype to get this informations always comes with the danger of beeing cached wrong.

1 Like

Had to try this https://github.com/sitegeist/Sitegeist.Slipstream not yet on packagist and no release yet but it works. Would recommend to use this with Flowpack.FullpageCache

1 Like

@pskwira are you still there?

Could you mark Martins response as “Solution” if it works for you?

@bwaidelich @martoro Thank You very much for discussion and solution.
I was “out of Neos” a bit and couldn’t view/test what You’ve provided. I’ll try i next few days.

1 Like

Give feedback if it works for you, i can release 1.0.0 then. I usually wait until i know about at least one successfull real world use.

@martoro Last weekend I’ve tested it localy on ddev and it works like a charm. Thank You very much. For real life will probably have to wait. Maybe even not so long. I think I’ll try to use it next time when our frontend colleagues will demand external css or js.

1 Like