Inherit Node and add rendering of children

Hey everyone. Recently started with Neos and have been loving the process so far.

I came across one use case I can’t seem to solve.

We have the following NodeType which should provide a Tag to all Nodes that inherit it. These children should then use the , add to it and fill it with their own content i.e. columns:

prototype(Site.Site:Component.SectionComponent) < prototype(Neos.Neos:ContentComponent) {
    someProp = ''
    someOtherProp = ''

    renderer = afx`
        <section data-first={props.someProp} data-second={props.someOtherProp}>
            {value}
        </section>
    `
}

A child node should look like this:

prototype(Site.Site:Component.ColOne) < prototype(Site.Site:Component.SectionComponent) {
    someHeadline = Neos.Neos.Editable {
        property = 'headline'
    }

    renderer = afx`
        <Site.Site:Component.SectionComponent attribute.id='someId'>
            <div class="container">
                <div class="row">
                <div class="col-12 >
                    <div class="row">
                        <div class="col-12">
                            {props.someHeadline}
                        </div>
                    </div>
                </div>
            </div>
        </Site.Site:Component.SectionComponent>
    `
}

Im not sure how to load what ColOne is rendering inside SectionComponent, especially ColOne’s properties.

My goal is:
SectionComponent will have every property I need across multiple Components. So that changing or adding a property does not require me to change every child component but only the parent instead. But more than a few components need either specific section IDs or other attributes to work in addition to what the parent provides. And each component, of course, has it’s own HTML.

Any tips on what I’m doing wrong or how to approach this would be greatly appreciated.

Hi Sören, welcome to Neos

i think the problem is that you try to use composition and inheritence at the same time.

While both can work the preferred way usually us composition. So a component uses other components to do its job like you do here:

But that you are trying to extend the section at the same time causes trouble.

Instead of

Try to define a new component instead.

prototype(Site.Site:Component.ColOne) < prototype(Neos.Fusion:Component) {
... 

Regards Martin

Based of on Martins answer…

When you want to use the more JavaScript JSX like way of wrapping things you need to use {props.content} (this will hold the children) instead of {value}:

(i also made yout attributes.id thingy work ;))

prototype(Site.Site:Component.ColOne) < prototype(Neos.Fusion:Component) {
    someHeadline = "hello"
    renderer = afx`
        <Site.Site:Component.SectionComponent attributes.id='someId'>
            <!-- AFX will put the children into the 'content' path by default -->
            <div class="stuff">content: {props.someHeadline}</div>
        </Site.Site:Component.SectionComponent>
    `
}
prototype(Site.Site:Component.SectionComponent) < prototype(Neos.Neos:ContentComponent) {
    attributes = Neos.Fusion:DataStructure
    attributes {
        data-first = ''
        data-second = ''
    }
    content = ''

    renderer = afx`
        wrapper start
        <Neos.Fusion:Tag tagName="section" attributes={props.attributes}>
            {props.content}
        </Neos.Fusion:Tag>
        wrapper end
    `
}

wrapping html can also done via a Fusion @process with the {value} context:

prototype(Site.Site:Component.ColOne) < prototype(Neos.Fusion:Component) {
    someHeadline = "hello"
    renderer = afx`
        <div class="stuff">content: {props.someHeadline}</div>
    `
    renderer.@process.wrap = Site.Site:Component.SectionComponent {
        attributes.id = "someId"
    }
}

prototype(Site.Site:Component.SectionComponent) < prototype(Neos.Neos:ContentComponent) {
    attributes = Neos.Fusion:DataStructure
    attributes {
        data-first = ''
        data-second = ''
    }
    content = ''

    renderer = afx`
        wrapper start
        <Neos.Fusion:Tag tagName="section" attributes={props.attributes}>
            <!-- the value context will be filled by Fusion runtime if used as a processor -->
            {value}
        </Neos.Fusion:Tag>
        wrapper end
    `
}

btw to try these things out copy and paste them to FusionPen: Build, Test and Discover Fusion Code for Neos CMS (punkt.de)

Hi @AmeNoKenshi

Hope that you could solve your issue with Martins and Marcs input.
I would like to mark the topic as solved when it is ok for you :slight_smile:

Hey Markus and everyone who answered.
Thank you all very much! These ideas are great and I will be able to get a clean solution with those :slight_smile:

Topic can be closed