Note this text is originally written by @rolandschuetz just putting it here for review and discussion. It will end up in our documentation finally. This has been discussed at the sprint with a big group of people so it’s pretty much decided on, but at last round of comments is probably a good idea
At the Neos-sprint in Salzburg the team discussed the best practices we discovered in over the last years. In a friendly and very detailed discussion a lot of patterns were introduced and we decided on which recommendations we want to give. The recommendation we are giving here do not mean that things are wrong if done differently, there are valid reasons to deviate from those guidelines. However with no specific reasons speaking against we strongly recommend to obey to the following rules.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Note: These rules will eventually end up in the Neos-documentation where they will be reevaluated and extended in regular intervals. We will use semantic versioning for these best practises.
- Each NodeType SHOULD be defined in a dedicated yaml-file and the file-name MUST represent the namespace of the contained NodeType/s. This helps finding the definition of a node type and get an understanding of the existing NodeTypes by looking at the configuration folder.
- The namespace of the NodeTypes SHOULD be structured and nested. It is RECOMMEND to start with one of the prefixes “Document”, “Content”, “Mixin”, “Collection” or “Constraint”.
- Sub-NodeTypes that are bound to a specific parent NodeType SHOULD have a name matching the parent, e.g. “Vendor:Content.Slider” and “Vendor:Content.Slider.Item”
- Properties SHOULD only be editable by a single editor – either inline or in the inspector. Editing the same property with different editors like inspector and inline easily causes problems when settings are only slightly off.
- Each NodeType property MUST be valid after creating a new node. This can be done by defining the defaultValue or by allowing the property being empty. Especially SelectBoxEditors caused trouble in the past if they neither allowed being empty nor had good defaults.
- The Neos.Neos.NodeTypes package SHOULD NOT be used directly. You RECOMMEND to create NodeTypes in the project namespace. You MAY use the Mixins from Neos.Neos.NodeTypes.Mixins instead.
- A NodeType SHOULD only inherit from a single non-abstract superType. All other superTypes SHOULD be Mixins, or Constraints. This helps keeping the inheritance chain understandable.
- NodeType-files that modify NodeTypes from other Packages MUST have “Override” in the filename.
- The Root.Fusion in a project MUST not contain anything but includes.
- Fusion files SHOULD only contain a single prototype. The folder and filenames MUST reflect the names of the contained prototypes.
- The Fusion prototype-namespace SHOULD be structured and nested. It is RECOMMENDED to start with one of the prefixes “Content”, “Document”, “Component”, “Helper” “Presentation” and “Integration”.
- Each non-abstract NodeType SHOULD have a matching Fusion prototype. This is the default way of Neos to find a matching Renderer and makes the code easy to understand. We RECOMMEND to abstract code into Fusion prototypes that are not bound to NodeTypes and reuse them across the project.
- Fusion prototypes with the prefixes “Content” and “Document” SHOULD implement the rendering of a Content or Document NodeType
- Fusion prototypes with the “Component” Prefix SHOULD implement rendering aspects only without fetching data from the ContentRepository.
- The rendering of content SHOULD be defined in Fusion-AFX. Fluid-Templates are still supported but no longer considered best-practice.
- Fusion-files that modify prototypes from other packages MUST have “Override” in the file- or folder name.
- For larger projects the presentainal prototypes SHOULD be separated from Integration. This can be done with seperate packages or folders “Presentation”, “Integration”. Those presentational Fusion prototypes MUST implement rendering aspects only without fetching data from the ContentRepository. You MAY use Sitegeist.Monocle.
- Visual differentiations between Documents SHOULD be implemented via separate Document-NodeTypes. Especially the layout property from Neos.Neos:NodeTypes.Page layout property SHOULD NOT be used.
- Neos projects SHOULD be managed as a single git repository that contains all packages that are specific to this project. This gives you a shared git history for all project-specific code.
- The “Packages” folder SHOULD only be controlled by composer. All your own project-specific packages MUST be be stored in special directory like “DistributionPackages” that is referenced as a repository of type path in the main composer file.
- We RECOMMEND to separate reusable Mixins from concrete NodeTypes definitions. This makes it easy for users of your package to only use specific parts of your package.
- You MAY provide presentational components without a direct cumpling to the NodeTypes. This makes your package even more flexible other developers.