I’ve just discussed with @sjsone (author of the VSCode Editor Extension) how we can improve the documentation in the code. This suggestion covers how to provide documentation using fusion features and some ideas how this would improve the everyday life of a fusion developer. This must not affect rendering at all.
Proposal
We suggest to use @doc
:
@doc = "This prototype does xy"
.@propTypes.[field].@doc = "This field does xy"
This would look something like this:
prototype(Vendor.Website:Atom.Test) < prototype(Neos.Fusion:Component) {
@doc = "Description for Vendor.Website:Atom.Test"
@propTypes {
field = ${PropTypes.string}
field.@doc = "This is a field"
}
}
Thoughts to why we chose this route
Previously this was the suggested syntax for the docs:
prototype(Vendor.Website:Atom.Test) < prototype(Neos.Fusion:Component) { itemKey = 'itemKey' itemKey.@type = ${PropTypes.string} itemKey.@description = ${PropTypes.string} }
If we rely on the @propTypes
meta property / decorator “inside” the actual field, then the description would be lost if we process, overwrite or delete the prop. With our suggestion this won’t be a problem, as the description is not directly attached to the prop itself. Also this uses @propTypes
which is already established in the Neos community.
Impact
With this we could document Fusion more easily and closer to the code.
This will solve at least 2 problems:
- Documentation Reference stays in sync with the code and is always accessible in the project
- Machine readable reference
- For the IDE plugins this would also remove the need to keep the plugin in sync as the sources are available inside the project
- For docs.neos.io this provides versioned Fusion object definitions
Requirements
As this suggestion is partly based on propTypes, we would need propTypes to move into the core. (Currently the reference is far away from the actual code: Inside Neos.Neos instead of Neos.Fusion)
Example of Neos.Fusion:Loop
prototype(Neos.Fusion:Loop) {
@class = 'Neos\\Fusion\\FusionObjects\\LoopImplementation'
@doc.text = "Render each item in items using itemRenderer."
@doc.description = "
Example using an object itemRenderer:
```neosfusion
myLoop = Neos.Fusion:Loop {
items = ${[1, 2, 3]}
itemName = \"element\"
itemRenderer = Neos.Fusion:Template {
templatePath = 'resource://...'
element = ${element}
}
}
```
"
@propTypes {
items = ${PropTypes.arrayOf(PropTypes.any).isRequired}
items.@doc = "The array or iterable to iterate over (to calculate iterator.isLast items have to be countable)"
itemName = ${PropTypes.string}
itemName.@doc = "Context variable name for each item"
itemKey = ${PropTypes.string}
itemKey.@doc = "Context variable name for each item key, when working with array"
iterationName = ${PropTypes.string}
iterationName.@doc = "A context variable with iteration information will be available under the given name: `index` (zero-based), `cycle` (1-based), `isFirst`, `isLast`"
itemRenderer = ${PropTypes.any.isRequired}
itemRenderer.@doc = "The renderer definition (simple value, expression or object) will be called once for every collection element, and its results will be concatenated (if `itemRenderer` cannot be rendered the path `content` is used as fallback for convenience in afx)"
@meta.glue = ${PropTypes.string}
@meta.glue.@doc = "The glue used to join the items together"
}
items = null
itemName = 'item'
itemKey = 'itemKey'
iterationName = 'iterator'
@glue = ''
}
We think it would be also beneficial to be able to differentiate between a short description (just @doc=''
or @doc.text=''
) and more content (like examples, links, …) .
Next steps
- Discuss solution with the core team
- Move propTypes to the core
- Move Fusion reference to the
.fusion
files and update the ReadTheDocs generation (with small to no changes for the reference users) - Create package for docs.neos.io to be able to use the reference as content
- Implement IDE improvements to suggest props/docs based on defined
@propTypes
/@doc
Outlook
Eventually this could be implemented by the IDE plugin (like @sjsone’s VSCode plugin as well as the docs.neos.io)
Links, bugs & other ideas
-
Neos.Fusion:Join
reference has property[key].@ignoreProperties
and should probably be.@ignoreProperties
(without[key]
) -
Bug in PropTypes
PropType definitions can't be deleted with >
We think this should delete the proptype definition:
prototype(Vendor.Website:Atom.Test) < prototype(Neos.Fusion:Component) { @propTypes { @strict = true field = ${PropTypes.string} } field = 'test' } prototype(Vendor.Website:Atom.Test2) < prototype(Vendor.Website:Atom.Test) { @propTypes { field > } field > }
Currently this is not possible. We encounter the following error:
propType for prop field must implement the ValidatorInterface array found instead
-
@deprecated
Idea
Create a meta property@deprecated
. This could show a message on hover in the IDE, write a.
warning in the log, …