Query for specific component in page and add a body class

Hi everybody,

I am looking for a way to add a specific class to the body tag when a certain node type is used within the current rendered page. I tried to solve this by using the example mentioned within the docs here. My fusion for the page node type looks like this:

prototype(Example.Site:Document.Page) < prototype(Example.Site:Document.AbstractPage) {
    bodyTag {
        attributes.class = ${q(documentNode).find('[instanceof Example.Site:Content.Hero]').count() > 0 ? 'has-hero' : ''}
    }
...

So this does not work properly. For example, when the child node contains the selected node type, the instruction also applies to the parent node. I don’t really understand how I should define this query to match the right conditions (Flow Queries are hard sometimes :neutral_face:). It would be great if there were a way to include this in the abstract page to make it available to all defined page types.

Has any of you ever implemented something similar and could provide me with a tip on how to achieve the desired behavior?

– Tom

find searches through all sub-nodes - including content and documents (in turn including their contents etc.).
For content elements in most cases you want to restrict the search to an element on the page first - typically within your main content-collection:
q(documentNode).children('main').find('[instanceof ExampleSite:Content.Hero]').count()
(Search the element by name: could be something like “sidebar” as well depending on your setup.)
Or if you have multiple content sections you might use .children('[instanceof Neos.Neos:ContentCollection]').

2 Likes

Fully agree with Matthias.
Try to be as precise with FlowQueries as you can be, as they can affect performance and cause unexpected results when being too broad.
In case of your hero element, you probably have a very precise idea where it could show up due to constraints, maybe it even has its own parent collection.

I’m lately thinking about how we can define a shorthand for “content on the current document”, as the query Matthias mentioned is necessary so often and often being asked about.

Thank you, that worked perfectly.

I keep the precision about the queries in mind. Maybe a tutorial for this kind of FusionQuery would be a starting point. Or another example within the tutorial I was mentioning in my initial post.