Skip to content

Possibility to copy (child) nodes from another node #60

Open
@jonnitto

Description

With NodeTemplates version 1.2 I've created the possibility to create template sites where you can add content elements to have a fast quick start (e.g. for blog posts).

For this, I've created following mixin

'Base.Templates:Mixin.CreationDialog':
  ui:
    creationDialog:
      elements:
        templateNodeIdentifier:
          type: reference
          ui:
            label: Template
            editorOptions:
              nodeTypes: ['Base.Templates:Mixin.Template']
  options:
    template:
      childNodes:
        mainContentCollection:
          when: '${data.templateNodeIdentifier}'
          name: main
          options:
            childNodesToCopy: "${q(node).find('#' + data.templateNodeIdentifier).children('main').children().get()}"

And following Package.php

<?php

namespace Base\Templates;

use Base\Templates\Service\ChildNodeCopyService;
use Flowpack\NodeTemplates\Template;
use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Package\Package as BasePackage;

/**
 * The Node Templates Magic Package
 */
class Package extends BasePackage
{
    /**
     * @param Bootstrap $bootstrap The current bootstrap
     * @return void
     */
    public function boot(Bootstrap $bootstrap)
    {
        $dispatcher = $bootstrap->getSignalSlotDispatcher();

        $dispatcher->connect(
            Template::class,
            "nodeTemplateApplied",
            ChildNodeCopyService::class,
            "copyChildNodesAfterTemplateApplication"
        );
    }
}

The ChildNodeCopyService.php looks like that

<?php

namespace Base\Templates\Service;

use Flowpack\NodeTemplates\Service\EelEvaluationService;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Eel\Package as EelPackage;
use Neos\Flow\Annotations as Flow;
use Neos\Neos\Service\NodeOperations;

/**
 */
class ChildNodeCopyService
{
    /**
     * @var EelEvaluationService
     * @Flow\Inject
     */
    protected $eelEvaluationService;

    /**
     * @var NodeOperations
     * @Flow\Inject
     */
    protected $nodeOperations;

    /**
     * @param NodeInterface $node
     * @param array $context
     * @param array $options
     * @return void
     */
    public function copyChildNodesAfterTemplateApplication(
        NodeInterface $node,
        array $context,
        array $options
    ): void {
        // Copy child nodes from template
        if (
            isset($options["childNodesToCopy"]) &&
            preg_match(
                EelPackage::EelExpressionRecognizer,
                $options["childNodesToCopy"]
            )
        ) {
            $childNodes = $this->eelEvaluationService->evaluateEelExpression(
                $options["childNodesToCopy"],
                $context
            );
            /** @var NodeInterface $childNode */
            foreach ($childNodes as $childNode) {
                $this->nodeOperations->copy($childNode, $node, "into");
            }
        }
    }
}

With the new version, it is not possible to create this helpful feature. Should we create an API for that, to make this possible?

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions