Page Fusion Objects
#Neos.Neos:Page
Neos.Neos:Page
is the main prototype for rendering full HTML pages, responsible for all markup of a page. This is also the place where CSS and HTML is added to the head of the page.
It is necessary to use Neos.Neos:Page to have the Neos editing work correctly.
Naming Magic
By default, for a Document node with a given name, the Fusion prototype with the same name is used for rendering - and it is expected that this one inherits from Neos.Neos:Page.
A simple (but not yet useful) example looks like this:
# if you have a Document Node type of the name "MyVendor.AwesomeNeosProject:Document.MyPage",
# then automatically, the Fusion prototype of the same name
# is used for rendering the page by default.
prototype(MyVendor.AwesomeNeosProject:Document.MyPage) < prototype(Neos.Neos:Page) {
body = Neos.Fusion:Component {
renderer = afx`
<h1> Hello World</h1>
`
}
}
#Adding CSS and JS
CSS can be registered via head.stylesheets
, and JavaScript via head.javascripts
. Both are an array (Neos.Fusion:Join
). A common practice is using AFX and the StaticResource
Eel Helper as follows:
prototype(MyVendor.AwesomeNeosProject:Document.MyPage) < prototype(Neos.Neos:Page) {
head {
stylesheets.site = afx`
<link rel="stylesheet" href={StaticResource.uri('MyVendor.AwesomeNeosProject', 'Public/Styles/Main.css')} media="all" />
`
javascripts.site = afx`
<script src={StaticResource.uri('MyVendor.AwesomeNeosProject', 'Public/Styles/Main.js')}></script>
`
}
// ...
}
Using Neos.Fusion:Component for header content
Instead of using afx`...`
above, you can also use a separate Neos.Fusion:Component
for the header assets, to improve reusability.
#The Page Body Template
We suggest using a separate Neos.Fusion:Component as the page body template- which we often call layout (naming-wise).
A full example can then work like this:
prototype(MyVendor.AwesomeNeosProject:Document.AbstractPage) < prototype(Neos.Neos:Page) {
head {
javascripts.site = MyVendor.AwesomeNeosProject:Resources.HeaderAssets
}
body = MyVendor.AwesomeNeosProject:Layout.Default {
content = Neos.Neos:ContentCollection {
nodePath = 'main'
}
}
}
prototype(MyVendor.AwesomeNeosProject:Resources.HeaderAssets) < prototype(Neos.Fusion:Component) {
renderer = afx`
<link rel="stylesheet" href={StaticResource.uri('MyVendor.AwesomeNeosProject', 'Public/Styles/Main.css')} media="all" />
`
}
prototype(MyVendor.AwesomeNeosProject:Layout.Default) < prototype(Neos.Fusion:Component) {
// API
content = ''
menu = ''
// Implementation
renderer = afx`
<section>
Some very long markup here for the page template
<nav>{props.menu}</nav>
<article>{props.content}</article>
</section>
`
}
#Internal Behavior
Neos.Neos:Page
is basically a big array for the different parts of a page, inheriting from Neos.Fusion:Join
. It consists of the following sections:
doctype: <!DOCTYPE html>
htmlTag: <html>
headTag: <head>
head: Neos.Fusion:Join
-
stylesheets: Neos.Fusion:Join
- This is what you write yourself.
-
javascripts: Neos.Fusion:Join
- This is what you write yourself.
-
You can add extra sections to the
<head>
here yourself.
-
closingHeadTag: </head>
bodyTag: <body>
body:
- This is what you write yourself.
closingBodyTag: </body>
closingHtmlTag: </html>
Pitfall
Make sure to not directly write to Page
instead of Page.body
, as otherwise your output might appear f.e. before the <body>
tag.
#Different Page Templates
Remember that by default, for a Document node with a given name, the Fusion prototype with the same name is used for rendering. This can be used to easily implement different page templates.
It is common practice to define a project-specific AbstractPage
, and use this as the base for every individual page.