{"id":26234879,"url":"https://github.com/flowpack/flowpack.nodetemplates","last_synced_at":"2025-04-22T14:52:48.710Z","repository":{"id":42423383,"uuid":"103909111","full_name":"Flowpack/Flowpack.NodeTemplates","owner":"Flowpack","description":"Neos CMS package that auto creates nodes based on a declarative template","archived":false,"fork":false,"pushed_at":"2024-06-29T10:05:26.000Z","size":513,"stargazers_count":31,"open_issues_count":10,"forks_count":10,"subscribers_count":14,"default_branch":"2.0","last_synced_at":"2024-10-23T18:47:28.891Z","etag":null,"topics":["neoscms"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flowpack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-18T07:50:03.000Z","updated_at":"2024-06-21T20:50:41.000Z","dependencies_parsed_at":"2022-09-05T13:11:12.391Z","dependency_job_id":"7f517107-24f8-428d-9147-f6ec4e557254","html_url":"https://github.com/Flowpack/Flowpack.NodeTemplates","commit_stats":{"total_commits":36,"total_committers":8,"mean_commits":4.5,"dds":0.4444444444444444,"last_synced_commit":"913f28f5d84def0eb5b82ee60a102122c6015084"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowpack%2FFlowpack.NodeTemplates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowpack%2FFlowpack.NodeTemplates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowpack%2FFlowpack.NodeTemplates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flowpack%2FFlowpack.NodeTemplates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flowpack","download_url":"https://codeload.github.com/Flowpack/Flowpack.NodeTemplates/tar.gz/refs/heads/2.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250263639,"owners_count":21401923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["neoscms"],"created_at":"2025-03-13T02:29:46.325Z","updated_at":"2025-04-22T14:52:48.683Z","avatar_url":"https://github.com/Flowpack.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Neos Node Templates\n\nWhen using Neos CMS as an editor, you often work with nested node structures that\nhave to be created manually. This packages aims at easing the editing workflow by\nautomatically creating helpful child nodes and making useful modifications to node\nproperties when creating new nodes in the Neos UI.\n\nIn contrast to child nodes that are defined in the regular node type definition\n(which cannot be removed by the editor), all modifications that are made when a\ntemplate is applied can be changed or removed by the editor.\n\nThe desired node structure is defined in a declarative way in the NodeTypes.yaml\nunder the path `options.template`.\n\n## TL;DR\n\n1. `composer require flowpack/nodetemplates`\n2. Add templates to your nodetypes configuration in NodeTypes.yaml, as described in the examples below\n3. Or use the command to dump the template based on your workspace\n\n## Hello world\n\nThe following example will add a text child node with the content \"Hello World\"\nto the main content collection of all pages that are created via the UI:\n\n```yaml\n'Neos.NodeTypes:Page':\n  options:\n    template:\n      childNodes:\n        mainContentCollection:\n          name: 'main'\n          childNodes:\n            helloWorldTextNode:\n              type: 'Neos.NodeTypes:Text'\n              properties:\n                text: '\u003cp\u003eHello world!\u003c/p\u003e'\n```\n\n## Using the node creation dialog\n\nThe Neos UI comes with a configurable node creation dialog. You can access\nthe data entered in the node creation dialog in your node templates using EEL queries.\nYou could let the editor choose between different dummy texts like this:\n\n```yaml\n'Neos.NodeTypes:Page':\n  ui:\n    creationDialog:\n      elements:\n        dummyText:\n          type: string\n          ui:\n            label: 'Dummy text'\n            editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor'\n            editorOptions:\n              values:\n                'Hello world':\n                  label: 'Hello world'\n                'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.':\n                  label: 'Lorem ipsum'\n  options:\n    template:\n      childNodes:\n        mainContentCollection:\n          name: 'main'\n          childNodes:\n            helloWorldTextNode:\n              type: 'Neos.NodeTypes:Text'\n              properties:\n                text: '${\"\u003cp\u003e\" + data.dummyText + \"\u003c/p\u003e\"}'\n```\n\nYou can also access data from the node creation dialog if you use the\n`showInCreationDialog` feature:\n\n```yaml\n'Some.Package:SomeNodeType':\n  # ...\n  properties:\n    'firstName':\n      type: string\n      label: 'First Name'\n      ui:\n        showInCreationDialog: true\n    'lastName':\n      type: string\n      label: 'First Name'\n      ui:\n        showInCreationDialog: true\n    'cardTitle':\n      type: string\n      label: 'Card Title'\n  options:\n    template:\n      properties:\n        cardTitle: '${\"\u003ch2\u003e\" + data.firstName + \" \" + data.lastName + \"\u003c/h2\u003e\"}'\n```\n\n## Conditions and loops\n\n### Conditions\n\nIf you want to apply a template only under some conditions, you can use the ``when`` configuration\nkey. It can be used in the main node template or in any child node template.\n\nThe following example only creates a text node if the option was selected in the creation dialog:\n\n```yaml\n'Your.NodeType:ContentCollection':\n  ui:\n    creationDialog:\n      elements:\n        createText:\n          type: boolean\n  options:\n    template:\n      childNodes:\n        text:\n          type: 'Your.NodeType:Text'\n          properties:\n            text: \"bar\"\n          when: '${data.createText}'\n```\n\nAs a ``when`` condition that evaluates to ``false`` prevents the whole template (and all child\ntemplates) from being applied, its most common use case is conditional child node creation.\n\n### Loops\n\nLoops can be used to create multiple child nodes. You can use ``withItems`` to define the items\nof the loop. When using EEL, be sure to return an array. The current item is available in EEL\nexpressions as the ``item`` context variable.\n\nThe following example creates three different text child nodes in the main content collection:\n\n```yaml\n'Neos.NodeTypes:Page':\n  options:\n    template:\n      childNodes:\n        mainContentCollection:\n          name: 'main'\n          childNodes:\n            multipleTextNodes:\n              type: 'Neos.NodeTypes:Text'\n              properties:\n                text: '${\"\u003cp\u003e\" + item + \"\u003c/p\u003e\"}'\n              withItems:\n                - 'Hello world'\n                - 'Different text'\n                - 'Yet another text'\n```\n\nWe call conditions ``when`` and loops ``withItems`` (instead of ``if`` and ``forEach``),\nbecause it inspires a more declarative mood. The naming is inspired by Ansible.\n\n## EEL context variables\n\nThere are several variables available in the EEL context for example.\n\n| Variable name    | Type                   | Description                                                                   | Availability            |\n|------------------|------------------------|-------------------------------------------------------------------------------|-------------------------|\n| data             | `array\u003cstring, mixed\u003e` | Data from the node creation dialog                                            | Global                  |\n| site             | `Node`                 | The site node in which the new node be created in                             | Global                  |\n| parentNode       | `Node`                 | The node where the new utmost node will be created inside                     | Global                  |\n| ~triggeringNode~ | `Node`                 | _Deprecated:_ The new node itself which is triggering the template processing | Global                  |\n| item             | `mixed`                | The current item value inside a loop                                          | Inside `withItems` loop |\n| key              | `string`               | The current item key inside a loop                                            | Inside `withItems` loop |\n\n\u003e **Notice**\n\u003e `triggeringNode` will be removed with version 3.0\n\n\u003e **Warning**\n\u003e The behaviour of `parentNode` changed from version 1.x to version 2.2\n\u003e Previously it referenced the parent node of the current template part and its nesting.\n\u003e With version 2.0 it was removed and 2.2 reintroduced the variable identifying the parent node of the first/utmost node that will be created.\n\n### Additional context\n\nYou can add more context variables to a template via the ``withContext`` setting. ``withContext``\ntakes an arbitrary array of items whose values might also contain EEL expressions:\n\n```yaml\ntemplate:\n  withContext:\n    someText: '\u003cp\u003efoo\u003c/p\u003e'\n    processedData: \"${String.trim(data.bla)}\"\n    booleanType: true\n    arrayType: [\"value\"]\n  childNodes:\n    column0Tethered:\n      name: column0\n      childNodes:\n        content0:\n          type: 'Flowpack.NodeTemplates:Content.Text'\n          when: \"${booleanType}\"\n          withItems: \"${arrayType}\"\n          properties:\n            text: ${someText + processedData + item}\n```\n\nInside ``withContext`` the parent context may be accessed in EEL expressions, but sibling context\nvalues are not available. As ``withContext`` is evaluated before ``when`` and ``withItems``, you can\naccess context variables from ``withContext`` in ``withItems`` at the same level – but not the other\nway around.\n\nIf you want to use a custom EEL helper, make sure to register it in the package's Settings. EEL\nhelpers configured for Neos.Fusion are not automatically available:\n\n```yaml\nFlowpack:\n  NodeTemplates:\n    defaultEelContext:\n      My.Foo: 'My\\Site\\Eel\\Helper\\FooHelper'\n```\n\n## Fine-grained error handling, resuming with the next possible operation.\n\nIn the first step the configuration is processed, exceptions like those caused by an EEL Expression are caught, and any malformed parts of the template are ignored (with their errors being logged).\nThis might lead to a partially processed template with some properties or childNodes missing.\n\nYou can decide via the error handling configuration `Flowpack.NodeTemplates.errorHandling`, if you want to start the node creation of this partially processed template (`stopOnException: false`) or abort the process (`stopOnException: true`), which will only lead to creating the root node, ignoring the whole template.\n\n```yaml\nFlowpack:\n  NodeTemplates:\n    errorHandling:\n     templateConfigurationProcessing:\n        stopOnException: false\n```\n\nIn case exceptions are thrown in the node creation of the template, because a node constraint was not met or the `type` field was not set, the creation of the childNode is aborted, but we continue with the node creation of the other left over parts of the template.\nIt behaves similar with properties: In case a property value doesn't match its declared type the exception is logged, but we will try to continue with the next property.\n\n# Commands\n\n## Validate simple node templates\n\nIt might be tedious to validate that all your templates are working especially in a larger project. To validate the ones that are not dependent on data from the node creation dialog (less complex templates) you can utilize this command:\n\n```sh\nflow nodetemplate:validate\n```\n\nIn case everything is okay it will succeed with `X NodeType templates validated.`.\n\nBut in case you either have a syntax error in your template or the template does not match the node structure (illegal properties) you will be warned:\n\n```\n76 of 78 NodeType template validated. 2 could not be build standalone.\n\nMy.NodeType:Bing\n Property \"someLegacyProperty\" in NodeType \"My.NodeType:Bing\" | PropertyIgnoredException(Because property is not declared in NodeType. Got value `\"bg-gray-100\"`., 1685869035209)\n\nMy.NodeType:Bar (depends on \"data\" context)\n  Configuration \"\"${data.aListOfThings}\"\" in \"childNodes.pages.withItems\" | RuntimeException(Type NULL is not iterable., 1685802354186)\n```\n\nThe standalone validation should detect errors and prevents editors having to deal with these errors at runtime.\n\nFor more complex templates, which are dependent on the node creation data, it is recommended to write separate tests. Currently, errors in templates depending on the data context will only be treated as warning, as they are probably not an issue at runtime.\n\n## Create template from node subtree\n\nWhen creating a more complex node template (to create multiple pages and content elements) it can be helpful to take the current node subtree from your workspace as reference.\nFor this case you can use the command:\n\n```sh\nflow nodeTemplate:createFromNodeSubtree \u003cstarting node id\u003e\n```\n\n- `--starting-node-id`: specified root node of the node tree\n\n**options:**\n- `--workspace-name`: custom workspace to dump from. Defaults to 'live'.\n\nIt will give you the output similar to the yaml example above.\nReferences to Nodes and non-primitive property values are commented out in the YAML.\n\n## More examples\n\nFor more examples have a look at the node templates demo package:\n\nhttps://github.com/mindscreen/neos-nodetemplates-demo\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowpack%2Fflowpack.nodetemplates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowpack%2Fflowpack.nodetemplates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowpack%2Fflowpack.nodetemplates/lists"}