Hi Erich
We do it with a set of configuration, fusion objects and an eel helper. Maybe this can be an inspiration for you. Just pick out the parts that fits your needs or the whole thing. I shortened it a bit because we use some fusion object in between that i just left out. So the code is not tested like it is, but the concept works more that 50 Neos websites already:
Our nodetypes fusion objects are all based on Neos.Neos:ContentComponent:
prototype(Vendor.Package:Content.Foo) < prototype(Neos.Neos:ContentComponent) {
...
renderer = afx`...`
# or you prefer fluid templates to render you nodes: renderer = Neos.Fusion:Template
}
We “enhanced” that prototype like this to let it wrap a div with class “container” around each content element:
prototype(Neos.Neos:ContentComponent) {
renderer.@process.wrapContentElement = Neos.Fusion:Tag {
tagName = 'div'
attributes.class = 'container'
content = ${value}
@if.shallWrapContainer = ${Internezzo.Neos.ContentCollection.shallWrapContainer(node)}
}
}
With the eel-helper in the if-condition we control which elements are getting wrapped:
<?php
namespace Internezzo\Neos\Eel\Helper;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Eel\FlowQuery\FlowQuery;
use Neos\Eel\ProtectedContextAwareInterface;
use Neos\Flow\Annotations as Flow;
class ContentCollectionHelper implements ProtectedContextAwareInterface
{
/**
* Return true if the current node shall be wrapped with a container
*
* @param NodeInterface $node
* @return string
*/
public function shallWrapContainer(NodeInterface $node)
{
$contentCollection = (new FlowQuery(array($node)))->parent('[instanceof Neos.Neos:ContentCollection]')->get(0);
if (!$contentCollection instanceof NodeInterface) {
return false;
}
$collectionNodeName = $contentCollection->getName();
/** @var NodeInterface $contentCollectionParent */
$contentCollectionParent = (new FlowQuery(array($contentCollection)))->parent()->get(0);
$configuration = array_change_key_case($contentCollectionParent->getNodeType()->getFullConfiguration()['childNodes'], CASE_LOWER)[$collectionNodeName];
if (!array_key_exists('options', $configuration)) {
return false;
}
if (!array_key_exists('wrapContainer', $configuration['options'])) {
return false;
}
return $configuration['options']['wrapContainer'];
}
/**
* All methods are considered safe
*
* @param string $methodName
* @return boolean
*/
public function allowsCallOfMethod($methodName)
{
return true;
}
}
Final part is that we add an option “wrapContainer” to all ContentCollections where we want the wrapping:
'Vendor.Package:Document.Foo':
childNodes:
main:
type: 'Neos.Neos:ContentCollection'
options:
wrapContainer: true