-
-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overhaul 9.0 NodeTypeManager
#4228
Comments
Would you be fine by using the |
@mhsdesign your comment is quite old and in the meantime we already "solved" the ObjectManager issue. But for the record: IMO we should avoid service location in the core as much as possible. E.g. it would be totally fine in the Suggestions for an overhauled
|
one of the bigger changes, that might not be clear from the above comment alone: |
That's fine by me, might be nice to comment at the method but I don't see a problem there. |
thanks for this write-down ;) yes the 1.) 2.) Im wondering if we really need 3.) seb and me use a hacky 4.) 5.) its a good thing to get rid of all the 6.) The ... Also the unstructured type: string # core
defaultValue: abc # core
required: true # future core ... but now part of metadata
ui: # metadata
inspector: ... # metadata
arbitraryStuff: # metadata
validators: # metadata
7.) we should definitely have the NodeType either not attached to the Node (which is architectural preferred but more breaking) or have a legacy mechanism that As we have already a migration from 8.3 8.) In Neos.Neos we currently use the 9.) While reading nodetypes from yaml is of course mainly a Neos.Neos concern, standalone projects might also profit from this declarative syntax so maybe keep some part of the 10.) Idk why node label generation is THE most complex thing and it should rather be a Neos concern? |
@mhsdesign Thanks a lot for your feedback!
Yes, thanks, I added it as todo to #4999
Currently we only use in a single place in Neos.Neos within in NodesController::addExistingNodeVariantInformationToResponse() it seems – but we do rely on it. But it could be replaced with
This would become really fast now, because it's just
Yes, I agree – there is no sensible way to re-implement this with the suggested approach
Not 100% sure what you mean? That meta- and core data are mixed on one level? That would only be the case for the legacy configuration array – in the core we should replace this by calls to the DTOs where possible. Re required: true # future core ... but now part of metadata Good catch – that should be part of the core props IMO and the Neos NodeTypeProvider could already translate
I don't know how that could work lazily in a clean way, we'd still have to expose some ugly injection object to the
+1
I agree.. IMO a trait is almost never the best option ;)
Yes, I agree. As a first step, I would like to get the Neos NodeTypeProvider to work, but as a follow-up we could try to extract the lazy-loading and abstract/final handling from the Neos specific things (
I'm not sure what you mean. You wonder why it should be a Neos concern or you suggest to make it a Neos concern? $node->getLabel() would have to be replaced with s.th. like $nodeLabelRenderer->renderNodeLabel($node); which would do sth like $nodeTypeManager->getNodeType($node->nodeTypeName)->metadata['label.generatorClass'] ?? ... |
In parallel, we have been progressing nicely regarding the label topic #5020 and the node attached NodeType. I was interested what your ideas were and to prevent rotting it i kept #4999 up to date after the changes. A few things came to my eye when i further examined the draft: 1.) Current problems with NodeTypesIn addition to points 2 and 3 of my previous comment 1.1) Legacy namings and transformations like "childNodes" and reference properties are part of the core 1.2) The forgiving (sometimes forgotten) logic to create a valid 1.3) The type of a property can be changed in the inheritance chain completely, not only narrowed to a more specific say php class implementation #4722 1.4) Properties cannot be unset in the inheritance chain but childNodes can be unset #4618 1.5) The NodeType and NodeTypeManager operate the heaviest possible way constantly only on the yaml input array and its all sprinkled over several places :) 1.6) The API 1.7) Calling 2.) Concepts to move to NeosFollowing things are not needed by the cr core and should be part of Neos (and thus the Neos.ContentRepositoryRegistry so its also helpful for other flow installs)
3.) Standalone PHP only NodeType schema definitionI tried to imagine the stand-alone cr use case and wondered how one would use the API to define the following NodeType schema: 'Neos.ContentRepository.Testing:AbstractNode':
abstract: true
properties:
text:
defaultValue: 'abstract'
type: string
'Neos.ContentRepository.Testing:SubNode':
superTypes:
'Neos.ContentRepository.Testing:AbstractNode': true
properties:
other:
type: string
'Neos.ContentRepository.Testing:Node':
superTypes:
'Neos.ContentRepository.Testing:AbstractNode': true
childNodes:
child-node:
type: 'Neos.ContentRepository.Testing:SubNode'
properties:
text:
defaultValue: 'test'
'Neos.ContentRepository.Testing:Page':
superTypes:
'Neos.ContentRepository:Root': true First i thought, well this is simple, by just instantiating the NodeType instances that should be available. $nodeTypeManager = new NodeTypeManager(
DefaultNodeTypeProvider::createFromNodeTypes(
NodeType::create(name: NodeTypeName::fromString(NodeTypeName::ROOT_NODE_TYPE_NAME)), // 3.1)
NodeType::create(
name: NodeTypeName::fromString('Neos.ContentRepository.Testing:AbstractNode'), // 3.2)
propertyDefinitions: PropertyDefinitions::fromArray([
PropertyDefinition::create(
name: PropertyName::fromString('text'),
type: 'string',
defaultValue: 'abstract',
)
])
),
NodeType::create(
name: NodeTypeName::fromString('Neos.ContentRepository.Testing:SubNode'),
superTypeNames: NodeTypeNames::fromStringArray(['Neos.ContentRepository.Testing:AbstractNode']),
propertyDefinitions: PropertyDefinitions::fromArray([
PropertyDefinition::create(
name: PropertyName::fromString('other'),
type: 'string',
)
// 3.3)
])
),
NodeType::create(
name: NodeTypeName::fromString('Neos.ContentRepository.Testing:Node'),
superTypeNames: NodeTypeNames::fromStringArray(['Neos.ContentRepository.Testing:AbstractNode']),
tetheredNodeTypeDefinitions: TetheredNodeTypeDefinitions::fromArray([
new TetheredNodeTypeDefinition(
name: NodeName::fromString('child-node'),
nodeTypeName: NodeTypeName::fromString('Neos.ContentRepository.Testing:SubNode'),
nodeTypeConstraints: NodeTypeConstraints::createEmpty()
)
]),
propertyDefinitions: PropertyDefinitions::fromArray([
PropertyDefinition::create(
name: PropertyName::fromString('text'),
type: 'string', // 3.4)
defaultValue: 'test',
)
])
),
NodeType::create(
name: NodeTypeName::fromString('Neos.ContentRepository.Testing:Page'),
superTypeNames: NodeTypeNames::fromStringArray([NodeTypeName::ROOT_NODE_TYPE_NAME]),
),
)
); 3.1) does the root type have to be specified, or can be overridden and has own meta-data? 3.2) as the abstract state should not be part of the core there would be no constraints against instantiating such abstract like or mixing like node type 3.3) should property 'text' be actually inherited by logic in the node type manager? Otherwise, this would be an unset property which we discussed to not support on Neos level: #4618 3.4) has the type to be specified or should be taken from inherited? 4.) SuperType merging vs not mergingSo using pure value objects as api also has a downside regarding the supertypes behaviour. Merging only in the Neos adapter and keeping the core simple
The NodeTypeManger will keep merging capabilities
5.) ConclusionWow this topic is super complex. We might not get this done for Neos 9.0.
|
Turn the NodeTypeManager into an immutable and type safe API.
The constructor currently has two properties:
Especially the
$nodeTypeConfigLoader
closure should be replaced by some type safe, immutable construct.This will also affect the
NodeType
class that needs a thorough reworkEdit: Updated by @bwaidelich on April 20th 2024, the original points:
Challenge 1: Supertypes and the full configuration is currently resolved lazily and we might have to keep it that way for performance reasons.. But I would suggest to start with the type-safe "eager-loading" version and see how that works out firstChallenge 2: TheObjectManager
is currently passed through to theNodeType
in order to resolve the "nodeLabelGenerator". This dependency should be avoided (see #4227)Challenge 3: Prevent circular inheritance (superTypes)Challenge 4: Should the "node type" builder/specification object be the same that you get back fromNodeTypeManager::getNodeType()
?Challenge 5: (Neos integration) How to load only specified types (maybe specify Package Key(s) and load types specified there + all depend types. Or: allow/deny lists likeSome.Package:Document.*
The text was updated successfully, but these errors were encountered: