Giter Site home page Giter Site logo

flowpack.nodetemplates's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flowpack.nodetemplates's Issues

uriPathSegment cannot be set via template

At the moment, the uriPathSegment property of a document is always generated by the TemplatingDocumentTitleNodeCreationHandler; thus, it's not possible to set it via a NodeTemplate. We should only generate it, if it is not set by the NodeTemplate.

FEATURE: Better exception handling when eel fails

Currently if you use a malformed expression, or the expression yields an error its hard to debug, in which property path the exception was caused.

ideally an exception would look like:

expression in template path: `childNodes.bar.properties.someProperty` threw Error: ...

it a bit tedious but a simple implementation could look like:

                try {
                    $propertyValue = $this->eelEvaluationService->evaluateEelExpression($propertyValue, $context);
                } catch (\Exception $exception) {
                    throw new \Exception(sprintf('Property "%s": "%s" could not be evaluated.', $propertyName, $propertyValue), 1684257493838, $exception);
                }

BUG: Setting the title via template on a document not working

The issue became present again: #20

there are now actually two handlers we have to fight:

  • Neos\Neos\Ui\NodeCreationHandler\DocumentTitleNodeCreationHandler (setProperty("title", is becomes actually redundant with the latter)
  • Neos\Neos\Ui\NodeCreationHandler\CreationDialogPropertiesCreationHandler

as suggested by @dimaip once we must implement positioning, as we cannot possibly augment any possible future processor, that changes the title. #21 (review)

sorting will be possible as bugfix via: neos/neos-ui#3511

Guard against invalid eel expressions. (Missing brace f.x.)

Currently since we use

if (preg_match(\Neos\Eel\Package::EelExpressionRecognizer, $name)) {
     $name = $this->eelEvaluationService->evaluateEelExpression($name, $context);
}

this will not qualify as an eel expression and never be evaluated and thus set as literal string property: (can you spot why? :P)

properties:
  foo: "${'hello + data.bar}"

this is just a simple case but in more complex scenarios its quite easy to forget to close the quotes of a string, write a malformed object or forget the ending eel brace.

we should fail in any case.

As its most likely not wanted to write the literal string which starts with ${ ... anywhere. And even if one wants to do it one can still use a string inside eel.

BUG: Asset id cant be set as property

In V1 you could have for example a node creation dialog to select an asset from the media module. This will be a string id in data.image.

Once you try to assign it to a property, it will fail, because the validator (correctly) says that the id is not of type ImageInterface

Property "image" in NodeType "Your.Vendor:Image" | PropertyIgnoredException(Because value `"4b5f90cb-6f42-4edd-91d9-6a0f4f0d6ddb"` is not assignable to property type "Neos\Media\Domain\Model\ImageInterface"., 1685958105644)

We should find a solution for this problem that will continue to work with 9.0

Setting the title of the generated node seems not possible

Given the following configuration:

  ui:
    label: Author
    icon: icon-user
    creationDialog:
      elements:
        title: ~
        firstName:
          type: string
          ui:
            label: 'Vorname'
            editor: 'Neos.Neos/Inspector/Editors/TextFieldEditor'
        lastName:
          type: string
          ui:
            label: 'Nachname'
            editor: 'Neos.Neos/Inspector/Editors/TextFieldEditor'
  options:
    template:
      properties:
        title: '${data.lastName + ", " + data.firstName}'

the title of the generated page is not set.

DISCUSSION: Should `property: null` be ignored?

When building a more complex template and a loop, you might encounter the situation, when you only want to set this property on iteration 1 or something and otherwise return null, thinking it will be ignored.

Currently the behaviour with null might not be 100% obvious.

template:
  properties:
    someSimplePropertyWithDefaultValue: null
    someReferencePropery: null
    someReferencesProperty: [null]

in the first case someSimplePropertyWithDefaultValue will be set to null (see $node->getProperties()) (also see somewhat related discussion about properties without default value or not previous value beeing skipped: neos/neos-development-collection#4292)

in the latter cases with the reference properties, the null value will be (rightfully) ignored, but because the setProperty will guard this:

https://github.com/neos/neos-development-collection/blob/1b744c8a6959a4aae735ffc6dd360f33847c98aa/Neos.ContentRepository/Classes/Domain/Model/AbstractNodeData.php#L167-L188C1

the question i asked myself, if it would be generally expected, that when null is returned, that the setProperty operation will be skipped for the property.

This would be helpful for cases, where you dont want to hardcode the default value. But this change might be breaking in unexpected ways...

FEATURE: `withContext`

It would be great, if one could define in withContext an additional global context, which is merged with the other values like triggeringNode

  options:
    template:
      withContext:
        fooReferenceNode: '${q(triggeringNode).find("#" + data.fooReference).get(0)}'

this way frequently computed values can be easily defined once at the top and dont need to be recomputed which might speed up performance marginally but mainly increases readability

Adjust conditions to Fusion - "if" instead of "when"

The property of conditions is currently named "when" which is a bit confusing as there was no "when" before in Neos. Is there reason for that?

@theilm: What do you think about renaming it to "if" which would be consistent with the naming in fusion.
Or even to "@if" to denote - like in Fusion - that this is a meta property.
An then - maybe adopt the complete fusion notation and allow multiple if statements with @if.<identifier>: <condition>

JS Error on media button click

Not sure, if this an error in this package or in the UI.

Description

The media button in creation dialog do not work, it throws a js error.

Steps to Reproduce

  1. use the 'Neos.Demo:Carousel' example
  2. start the creation dialog
  3. try to open the media modul from within the dialog modal

Expected behavior

The media modul is opening.

Actual behavior

Nothing visually, but in console I get an js error.

index.js:137 Uncaught TypeError: n.props.renderSecondaryInspector is not a function
    at AssetEditor.n.handleChooseFromMedia (index.js:137)
    at Object.Ja (react-dom.production.min.js:26)
    at Object.invokeGuardedCallback (react-dom.production.min.js:25)
    at Object.invokeGuardedCallbackAndCatchFirstError (react-dom.production.min.js:25)
    at Za (react-dom.production.min.js:30)
    at cb (react-dom.production.min.js:32)
    at gb (react-dom.production.min.js:32)
    at Array.forEach (<anonymous>)
    at ab (react-dom.production.min.js:31)
    at lb (react-dom.production.min.js:34)

Affected Versions

Neos: v3.3.13

UI: v1.1.2

Flowpack.NodeTemplates: <= 1.0

Node templates not autogenerated

(Might be outdated, as I had no time to reproduce this with the newest version. My Version was 1.1.1. Edit: I tested it with 1.3.1 and the issue still exists).

It seems to me that the node template config does not work (does not insert nodes automatically) if its parent is a configured childNode, meaning, the user did not insert it itself but it was generated as configured under the yaml key childNodes (of some higher parent in the hierarchy).

To put it another way: To me it looks like there is some hook that is not called when nodes are inserted by "the framework" instead of the user.

FEATURE: Create node template definition yaml dump from node subtree

(i have a prototype already locally and will create a pr soonish)

when creating a more complex node template, to create multiple pages and content elements, it can be helpful to take the current node subtree as reference. For this case a command controller would be great.

flow nodeTemplate:fromSubtree 136a646c-b2d5-4475-8e24-b25727aa7913 --workspaceName=live
Your.NodeType:
  options:
    template:
      childNodes:
        page0:
          name: page-0
          type: Foo.Bar:Page
          properties:
            title: 'my page'
            uriPathSegment: my-page
            # someReference -> Reference of NodeTypes (Neos.Neos:Document) with value Node(13f5e86b-7b0e-4a7f-9a8a-af6bdf1c1913)
          childNodes:
            page0:
              name: page-0
              type: Foo.Bar:Pag
              properties: ...
              childNodes:
                 mainContentCollection:
                   name: main
                   childNodes: ...

Document "document title templating" feature

I just realized that there is a new release of this package (1.0.0 => 1.1.0) and it states β€œWith this release, the templating of document titles and node paths is also possible.” but there is no documentation of this new feature whatsoever

BUG: Property convert not used when accessing values like `data.image` in eel

This patter doesnt work currently

  properties:
    image:
      type: ImageInterface
      ui:
         showInCreationDialog: true
  options:
    template:
      properties:
        imageCaption: '${data.image.copyrightNotice}'

as data.image is not converted. The dump looks like:

array(2)
  '__identity' => 4567890,
  '__type' => 'ImageVariant' 

related: #61

version: 2.x

how to add childNodes to NodeType of type ContentCollection

Hi, I have a content element which supertypes Neos.Neos:ContentCollection.
Therefore I don't have a named childNode of type ContentCollection.
I tried something like this, to add childNodes directly to my node, but it did not work.

'Vendor.XYGrid:Row':
  superTypes:
    'Neos.Neos:Content': true
    'Neos.Neos:ContentCollection': true
  ui:
   ...
    options:
      template:
         childNodes:
              column1:
                type: 'Vendor.XYGrid:Column'
              column2:
                type: 'Vendor.XYGrid:Column'

BUG: In case of an Exception dont create any nodes

If the template is malformed, all created nodes should be deleted, or better: A template should be first evaluated and expanded to a big array and then only rendered into the node tree not in the same run.

Separating the processes would make the code also easier testable, and the template less coupled the the old content repository implementation.

TASK: Improve exception messages -> dont start with `because`

Many exceptions are currently thrown like:

                    throw new PropertyIgnoredException(
                        sprintf(
                            'Because property is not declared in NodeType. Got value `%s`.',
                            json_encode($propertyValue)
                        ),
                        1685869035209
                    );

Property "nonDeclaredProperty" in NodeType "Flowpack.NodeTemplates:Content.SomeExceptions" | PropertyIgnoredException(Because property is not declared in NodeType. Got value "hi"., 1685869035209)

This provides not the best output for editors. A fully readable text would be better than starting with Because

Possibility to copy (child) nodes from another node

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?

Feature Request: Generate configuration from existing node

While I think that NodeTemplates is a great package, I find the according templates a little cumbersome to configure due to the fact that there can be deep nesting.

I think it would be a good idea to create a setting "development mode" for the package and then add an additional inspector tab to Document nodes, displaying the node structure in the way that you could copy it to the Node Type definition.

This way, you could create a node that suits your needs, copy the definition and adjust (e.g. pre-defined property values).

What do you think? We might be willing to (help) funding this, so an estimate would be great.

NodeCreation: childNodes constraints are not evaluated correctly if inserting items into Neos.Neos:ContentCollection

When upgrading from 2.0.0 to 2.0.1, one template configuration stops working. Extract:

  options:
    template:
      childNodes:
        content:
          name: 'content'
          childNodes:
            text:
              type: 'KaufmannDigital.Nova.NodeTypes.Text:Atom.Text'

Apparently the exception is thrown at Classes/Domain/NodeCreation/NodeCreationService.php L97+


                if (!$parentNode->getNodeType()->allowsChildNodeType($nodeType)) {
                    $caughtExceptions->add(
                        CaughtException::fromException(new \RuntimeException(sprintf('Node type "%s" is not allowed for child nodes of type %s', $template->getType()->getValue(), $parentNode->getNodeType()->getName()), 1686417627173))
                    );
                    continue;
                }

The exception that's coming up:

RuntimeException(Node type "KaufmannDigital.Nova.NodeTypes.Text:Atom.Text" is not allowed for child nodes of type Neos.Neos:ContentCollection, 1686417627173)

I am not 100% certain yet but I think the issue is coming up because in that template we are inserting nodes into generic content collections, however the constraint is checked via allowsChildNodeType in NodeType, which however is not considering special constraints defined for those collections. The constraints are defined exeplicitely:

  childNodes:
    content:
      type: 'Neos.Neos:ContentCollection'
      constraints:
        nodeTypes:
          'KaufmannDigital.Nova.NodeTypes.Text:Atom.Text': TRUE

Childnodes max deep

Hi, I miss the feature where you can adjust the maximum child nodes that could appear.

NodeCreation: `null` child nodes lead to an Exception

It is not possible to overwrite an existing Configuration and setting child nodes to null.

./flow nodeTypes:show Agency.Base:Content.Bla --path options.template returns:

childNodes:
    mainContentCollection:
        name: content
        childNodes:
            headline:
                type: 'Vendor.Website:Content.Bla'
            text: null
            buttonArea: null

$childNodeTemplatePart = $templatePart->withConfigurationByConfigurationPath(['childNodes', $childNodeConfigurationPath]);
(suggestion by @mhsdesign)

Allow array types to be set

Currently it seems that I cannot create a field with type array:

                salutation:
                  type: 'Sitegeist.PaperTiger:Field.RadioButtons'
                  properties:
                    name: 'salutation'
                    label: 'Anrede'
                    isRequired: true
                    options: [label: 'Frau', value: 'Frau'], [label: 'Herr', value: 'Herr']

How a RadioButtons element looks in the node properties:

{
    "isRequired": true,
    "customErrorMessageEnabled": false,
    "name": "salutation",
    "label": "Anrede",
    "options": {
        "0": {
            "label": "Frau",
            "value": "Frau"
        },
        "1": {
            "label": "Herr",
            "value": "Herr"
        }
    }
}

Error message:

Configuration "childNodes.fields.childNodes.fieldset.childNodes.salutation.properties.options" | RuntimeException(Template configuration properties can only hold int|float|string|bool|null. Property "options" has type "array", 1685725310730)

Is this concious limitation or not possible technically?

Cast required for DateTime fields in Creation Dialog

Description

The value of an DateTime field in creation dialog can't be given to the inspector field without cast to an DateTime object.

Error message during creation of a new node (without cast):
Exception in line 259 of /MyProject/Packages/Libraries/neos/utility-objecthandling/Classes/ObjectAccess.php: Argument 1 passed to Neos\ContentRepository\Domain\Model\Node_Original::setHiddenAfterDateTime() must be an instance of DateTime or null, string given, called in /MyProject/Packages/Libraries/neos/utility-objecthandling/Classes/ObjectAccess.php on line 259

Steps to Reproduce

  1. Define DateTime field in Creation Dialog
(...)
creationDialog:
  elements:
    _hiddenAfterDateTime:
        type: DateTime
          ui:
            label: i18n
            editor: 'Neos.Neos/Inspector/Editors/DateTimeEditor'
            editorOptions:
              format: 'd.m.Y'
  1. Define options in yaml
(...)
options:
    template:
      properties:
        _hiddenAfterDateTime: "${data._hiddenAfterDateTime}"

Expected behavior

The date set in creation dialog is also set in corresponding inspector field

Actual behavior

"Argument 1 passed to .... must be an instance of DateTime or null, string given."

Requires cast to DateTime object:

 options:
    template:
      properties:
        _hiddenAfterDateTime: "${Date.create(data._hiddenAfterDateTime)}"

Affected Versions

Neos: 4.0.6
NodeTemplates: 1.0.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.