Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
A Round Trip through your Presentation Layer wi...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Dominique Feyer
March 31, 2017
Programming
560
0
Share
A Round Trip through your Presentation Layer with Fusion
Get a better understanding of Fluid and Fusion for your Neos CMS project
Dominique Feyer
March 31, 2017
More Decks by Dominique Feyer
See All by Dominique Feyer
content modeling from theory to Neos CMS
dfeyer
1
210
Liiptalk Neos CMS
dfeyer
1
110
Inspiring conference 2016 - Automation & external service integration
dfeyer
0
52
Inspiring Conference 2016 - architectes.ch case study
dfeyer
0
73
Neos CMS Introduction, Webmardi, Lausanne, February 2015
dfeyer
0
63
Neos CMS: Node Kingdom
dfeyer
0
110
Other Decks in Programming
See All in Programming
Radical Imagining - LIFT 2025-2027 Policy Agenda
lift1998
0
230
Redox OS でのネームスペース管理と chroot の実現
isanethen
0
530
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
120
今こそ押さえておきたい アマゾンウェブサービス(AWS)の データベースの基礎 おもクラ #6版
satoshi256kbyte
1
230
煩雑なSkills管理をSoC(関心の分離)により解決する――関心を分離し、プロンプトを部品として育てるためのOSSを作った話 / Solving Complex Skills Management Through SoC (Separation of Concerns)
nrslib
3
480
Spec Driven Development: The End Of Vibe Coding | DevLand 2026
danielsogl
PRO
0
110
20260320登壇資料
pharct
0
160
Symfony + NelmioApiDocBundle を使った スキーマ駆動開発 / Schema Driven Development with NelmioApiDocBundle
okashoi
0
260
The free-lunch guide to idea circularity
hollycummins
0
410
AI駆動開発がもたらすパラダイムシフト
ryosuke0911
0
120
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
290
Vibe하게 만드는 Flutter GenUI App With ADK , 박제창, BWAI Incheon 2026
itsmedreamwalker
0
540
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
160
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
68
38k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
260
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.7k
Writing Fast Ruby
sferik
630
63k
Leo the Paperboy
mayatellez
6
1.6k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.8k
Utilizing Notion as your number one productivity tool
mfonobong
4
280
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
700
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Designing Powerful Visuals for Engaging Learning
tmiket
1
330
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Transcript
None
@dfeyer on twitter/slack Dominique Feyer
@dimaip on twitter/slack Dmitri Pisarev
a round trip through your presentation layer in Neos
Logicless Templates, Smart Fusion Objects
Conditions
<f:if condition="{neos:rendering.inBackend()}"> Secret stuff! </f:if>
secrectStuff = 'Secret stuff!'
[email protected]
= ${node.context.inBackend}
{secrectStuff}
Loops
<f:for each="{blogPosts}" as="blogPost"> <div class="BlogPost-teaser"> <h2>{blogPost.title}</h2> <div>{blogPost.teaser}</div> </div> </f:for>
prototype(Your.Site:BlogPostsList) < prototype(Neos.Fusion:Collection) { collection = ${blogPosts} itemName = 'node'
itemRenderer = Your.Site:BlogTeaser }
Partials
<f:render partial="Header"/> <div>Website content</div>
prototype(Your.Site:Page) { header = Your.Site:Header }
{header -> f:format.raw()} <div>Website content</div>
Layouts
<f:layout name="Layout"/> <f:section name="main"> <div class="Content">The content</div> </f:section>
prototype(Your.Site:MainPage) < prototype(Page) { @process.layout = Your.Site:Components.Layout }
prototype(Your.Site:Components.Layout) < prototype(Neos.Fusion:Template) { templatePath = .../Layout.html value = ${value}
}
structure is everything
collocate component's resources
Fusion/Components/Menu/ Menu.fusion Menu.html Menu.js Menu.css
project directory structure
Blog/ Blog.fusion Blog.html Blog.Document.fusion Blog.Comments.fusion Blog.css Components/Menu/ Menu.fusion Menu.html Menu.js
Menu.css Override.fusion Shame.fusion Root.fusion Resources/Private/Fusion
Override.fusion
prototype(Neos.Fusion:Collection) { itemName = ‘node’ }
Shame.fusion
prototype(Neos.Neos:Page) { googleAnalyticsTrackingCode = Neos.GoogleAnalytics:TrackingCode }
select rendering based on the node type
root { default { renderPath = ‘page’ } } root.blog
{ @position = ‘before default’ condition = ${q(node).is(‘[instanceof Your.Site:Blog]’)} type = ‘Your.Site:Blog.Document’ }
root { default { type = ${q(node).property(‘_nodeType') + ‘.Document’} renderPath
> } }
prototype(Your.Site:Blog.Document) < prototype(Page) { head.stylesheets.main = … body = Your.Site:Blog
} prototype(Your.Site:Blog) < prototype(Neos.Fusion:Template) { templatePath = ‘…’ main = Neos.Neos:ContentCollection { nodePath = 'main' } }
fusion prototype generator
'Neos.Neos:Node': options: fusion: prototypeGenerator: ~
'Neos.Neos:Node': options: fusion: prototypeGenerator: Your\Site\Generators\Generator
opinionated template object
prototype(Your.Site:Components.Footer) < prototype(Neos.Fusion:Template) { templatePath = ‘resource://Your.Site/Private/ Fusion/Components/Footer/Footer.html’ }
prototype(Your.Site:SimpleTemplate) { @class = ‘Your\\Site\\FusionObjects\\TemplateImplementation’ } https://gist.github.com/dfeyer/f13c5e35004493956c9fef0bbc5efb0f
prototype(Your.Site:Components.Footer) < prototype(Your.Site:SimpleTemplate) Will automatically look for template in resource://Your.Site/Private/Fusion/Components/Footer/Footer.html
more to come
fusion is just another language
Your.Site:Book is not Your.Site:Book
Your.Site:Book NodeTypes.Book.yaml
‘Your.Site:Book': superTypes: 'Neos.Neos:Document': true ‘Your.Site:SeoMixins': true ‘Your.Site:JsonLd.Document’: true
Your.Site:Book Book.fusion
prototype(Your.Site:Book) < prototype(Neos.Fusion:Template)
prototype(Your.Site:Book) { title = ${q(node).property(‘title’)} }
one node type multiple fusion prototypes
Your.Site:Book Your.Site:Book.Document Your.Site:Book.Title Your.Site:Book.QrCode Your.Site:Book.SearchResult
one fusion prototype multiple nodetypes
Your.Site:Defaut.SearchResult Your.Site:Defaut.Document Your.Site:Defaut.JsonLd.Document
composition or inheritance… again
prototype(Your.Site:Library) { ownerName = … ownerEmail = … contactName =
… contactEmail = … }
prototype(Your.Site:Library) { owner = Your.Site:Person contact = Your.Site:Person address =
Your.Site:Address }
‘Your.Site:Library': childNodes: 'owner': type: ‘Your.Site:Person' 'contact': type: 'Your.Site:Person' 'address': type:
'Your.Site:Address'
naming… again
schema.org
small objects are beautiful
Neos.Fusion:Value prototype(Your.Site:Anything) < prototype(Neos.Fusion:Value)
Query
prototype(Your.Site:AllBooks.Query) { value = ${q(site).find(...).get()} }
prototype(Your.Site:LatestBooks.Query) { value = Your.Site:AllBooks.Query { @process.latest = ${Array.slice(value,0,3} }
}
Decorator
prototype(Your.Site:Components.Article) { tagName = ‘article’ content = ${value} } prototype(Your.Site:Components.Article)
< prototype(Neos.Fusion:Tag)
prototype(Your.Site:Book.Teaser) { … @process.wrap = Your.Site:Components.Article }
Neos.Fusion:RawArray prototype(Your.Site:Anything) < prototype(Neos.Fusion:RawArray)
prototype(Your.Site:Book.Json) { title = ${q(bookNode).property(‘title’)} price = ${Price.get(bookNode)} @process.stringify =
${Json.stringify(value)} } prototype(Your.Site:Book.Json) < prototype(Neos.Fusion:RawArray)
Neos.Fusion:RawCollection Neos.Fusion:Tag
take care of your domain logic
${q(node).property('discount') > 0 ? q(node).property('price') - (q(node).property('price') * q(node).property('discount') /
100) : q(node).property(‘price’)}
‘Your.Site:Book’: class: Your\Site\Domain\Model\Book
${book.price}
start from scratch
fusion in flow application
workshop anyone ?
hijack us
demo site reboot
None
in the making https://github.com/Flowpack/fusion-bp