Skip to content

Latest commit

 

History

History
93 lines (70 loc) · 3.81 KB

02_PresentationObjectFactories.md

File metadata and controls

93 lines (70 loc) · 3.81 KB

2. Content integration with PresentationObject Factories

Hint: If you used the Kickstarter to create your component, an empty factory has already been created alongside the PresentationObject.

In this tutorial, we're going to write a PresentationObject factory for the image component we've created in "PresentationObjects and Components". Let's assume that we have a Vendor.Site:Content.Image node type with the properties image__src, image__alt and image__title that we want to integrate with our Image component.

Writing the factory

PresentationObject factories are co-located with their respective PresentationObjects. It's recommended to create factory methods with a speaking name prefixed with for* or from* to describe their use-case. When your code base grows, the factory will act like an index showing you all the different places in which the respective component is used.

EXAMPLE: PresentationObject Factory

<?php declare(strict_types=1);
namespace Vendor\Site\Presentation\Image;

use Neos\Flow\Annotations as Flow;

/**
 * @Flow\Scope("singleton")
 */
final class ImageFactory extends AbstractComponentPresentationObjectFactory
{
    /**
     * @param TraversableNodeInterface $node
     * @return ImageInterface
     */
    public function forImageNode(TraversableNodeInterface $node): ImageInterface
    {
        // Optional: Use assertions to ensure the incoming node type
        assert($node->getNodeType()->isOfType('Vendor.Site:Content.Image'));

        return new Image(
            $node->getProperty('image__src')
                ? $this->uriService->getAssetUri($node->getProperty('image__src'))
                : $this->uriService->getDummyImageUri()
            $node->getProperty('image__alt') ?? '',
            $node->getProperty('image__title')
        );
    }
}

Registering the factory

Each factory that extends AbstractComponentPresentationObjectFactory automatically implements the Neos\Eel\ProtectedContextAwareInterface and can be used as an Eel helper. To make our factory available in Fusion, we need to register it in the Settings:

EXAMPLE: Settings.PresentationHelpers.yaml

Neos:
  Fusion:
    defaultContext:
      Vendor.Site.Image: Vendor\Site\Presentation\Image\ImageFactory

Connecting the factory to content element rendering

Neos uses the Neos.Neos:ContentCase to map nodes to rendering prototypes. For our Vendor.Site:Content.Image node, the entry point is going to be a Fusion prototype of the same name.

From here, we just need to extend Neos.Neos:ContentComponent and provide our PresentationObject component Vendor.Site:Component.Image as the renderer. As the presentationObject we pass the result of the forImageNode-method of our newly registered ImageFactory.

EXAMPLE: Resources/Private/Fusion/Integration/Content/Image.fusion

prototype(Vendor.Site:Content.Image) < prototype(Neos.Neos:ContentComponent) {
    renderer = Vendor.Site:Component.Image {
        presentationObject = ${Vendor.Site.Image.forImageNode(node)}
    }
}

That's it! Our image component is now fully integrated and can be edited in the Neos Backend.