Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Atomic.Fusion & Sitegeist.Monocle - Neos Confer...

Atomic.Fusion & Sitegeist.Monocle - Neos Conference 2017

An presentation of sitegeists approach for component based fusion development that enabled the creation of living styleguide in Neos.

Sitegeist

March 31, 2017
Tweet

More Decks by Sitegeist

Other Decks in Technology

Transcript

  1. Evolution of an Image Partial <f:if condition="{link}"> <f:then> <f:if condition="{neos.rendering.inBackend()}">

    <f:then> <f:render section="image" attributes="{_all}" /> </f:then> <f:else> <a href="{link}"> <f:render section="image" attributes="{_all}" /> </a> </f:else> </f:if> </f:then> <f:else> <f:render section="image" attributes="{_all}" /> </f:else> </f:if> <f:section name="image"> <f:image image="{image}" alt="{altText}" title="{node.property.title}" /> Part 3 - Backend adds optional link
  2. The challenges for bigger projects 1. Partials don't scale well

    2. Proper context boundaries are missing 3. That way Frontend to backend collaboration is a one way trip
  3. Atomic.Fusion - Component prototype(Vendor.Site:Component.Atom.Link) < prototype(PackageFactory.AtomicFusion:Component) { # component api

    text = '' uri = '' # component renderer renderer = Neos.Fusion:Tag { tagName = 'a' content = Neos.Fusion:Array { text = ${props.text} } attributes.src = ${props.uri}
 } }
  4. Atomic.Fusion - Composition prototype(Vendor.Site:Component.Organism.Header) < prototype(PackageFactory.AtomicFusion:Component) { renderer = Neos.Fusion:Array

    { funcNav = Vendor.Site:Component.Molecule.FuncNav mainNav = Vendor.Site:Component.Molecule.MainNav home = Vendor.Site:Component.Atom.Link { src = '/' } } }
  5. Sitegeist.Monocle - Meta Data prototype(Vendor.Site:Component.Atom.Button) { @styleguide { # Meta

    Data path = 'atoms.basic' title = 'Button' description = 'generic Buttom Atom’ # Preview Data props { content = 'Lorem Ipsum'
 tagName = 'a' } } }
  6. Sitegeist.Monocle - Preview Data prototype(Vendor.Site:Component.Atom.Button) { @styleguide { # Meta

    Data path = 'atoms.basic' title = 'Button' description = 'generic Buttom Atom’ # Preview Data props { content = 'Lorem Ipsum'
 tagName = 'a' } } }
  7. Sitegeist.Monocle Github: https://github.com/sitegeist/Sitegeist.Monocle Packagist: composer require sitegeist/monocle It is used

    in Production Has no effect the on the neos-fusion runtime It does'nt need a database
  8. Atomic.Fusion - Mapping Content prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Fusion:Renderer) { renderer =

    Vendor.Site:Component.Molecule.Teaser { layout = ${q(node).property('layout')} title.content = ${q(node).property('title')}
 description { content = ${q(node).property(‚description')}
 @process.makeEditable = Neos.Neos:ContentEditableWrapping
 @process.makeEditable.propertyName = 'description'
 } } @process.contentElementWrapping = Neos.Neos:ContentElementWrapping }
  9. Atomic.Fusion - Mapping Content prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Fusion:Renderer) { renderer =

    Vendor.Site:Component.Molecule.Teaser { layout = ${q(node).property('layout')} title.content = ${q(node).property('title')}
 description { content = ${q(node).property(‚description')}
 @process.makeEditable = Neos.Neos:ContentEditableWrapping
 @process.makeEditable.propertyName = 'description'
 } } @process.contentElementWrapping = Neos.Neos:ContentElementWrapping }
  10. Atomic.Fusion - Mapping Content prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Fusion:Renderer) { renderer =

    Vendor.Site:Component.Molecule.Teaser { layout = ${q(node).property('layout')} title.content = ${q(node).property('title')}
 description { content = ${q(node).property(‚description')}
 @process.makeEditable = Neos.Neos:ContentEditableWrapping
 @process.makeEditable.propertyName = 'description'
 } } @process.contentElementWrapping = Neos.Neos:ContentElementWrapping }
  11. Atomic.Fusion - Mapping Documents prototype(Vendor.Site:Document.Page) < prototype(Neos.Neos:Page) { body =

    Vendor.Site:Component.Template.Page { navigationItems = Neos.Fusion:RawCollection { collection = ${q(site).children('[instanceof Neos.Neos:Document]').get()} itemName = 'item' itemRenderer = Neos.Fusion:RawArray { title = ${q(item).property('titleOverride') ? q(item).property('titleOverride') : q(item).property( uri = Neos.Neos:NodeUri { node = ${item} } } } content = Neos.Neos:PrimaryContent { nodePath = 'main' } } }
  12. Atomic.Fusion - Mapping Documents prototype(Vendor.Site:Document.Page) < prototype(Neos.Neos:Page) { body =

    Vendor.Site:Component.Template.Page { navigationItems = Neos.Fusion:RawCollection { collection = ${q(site).children('[instanceof Neos.Neos:Document]').get()} itemName = 'item' itemRenderer = Neos.Fusion:RawArray { title = ${q(item).property('titleOverride') ? q(item).property('titleOverride') : q(item).property( uri = Neos.Neos:NodeUri { node = ${item} } } } content = Neos.Neos:PrimaryContent { nodePath = 'main' } } }
  13. Atomic.Fusion - Mapping Documents prototype(Vendor.Site:Document.Page) < prototype(Neos.Neos:Page) { body =

    Vendor.Site:Component.Template.Page { navigationItems = Neos.Fusion:RawCollection { collection = ${q(site).children('[instanceof Neos.Neos:Document]').get()} itemName = 'item' itemRenderer = Neos.Fusion:RawArray { title = ${q(item).property('titleOverride') ? q(item).property('titleOverride') : q(item).property( uri = Neos.Neos:NodeUri { node = ${item} } } } content = Neos.Neos:PrimaryContent { nodePath = 'main' } } }
  14. The challenges for bigger projects 1. Partials don't scale well

    Presentational components do! 2. Proper context boundaries are missing Components have boundaries In Fusion you can cross boundaries if needed 3. Frontend to backend collaboration works only in one direction Seperate presentational components enable independent. The Component API defines the interface between crafts.
  15. Fusion Components - Today prototype(PackageFactory.AtomicFusion.AFX:Example) < prototype(PackageFactory.AtomicFusion:Component) { title =

    'title text' subtitle = 'subtitle line' imageUri = 'https://dummyimage.com/600x400/000/fff' renderer = Neos.Fusion:Tag { tagName = 'div' content = Neos.Fusion:Array { headline = Neos.Fusion:Tag { tagName = 'h1' content = Neos.Fusion:Array { 1 = ${props.title} } attributes.class = 'headline' } subheadline = Neos.Fusion:Tag { tagName = 'h2' content = Neos.Fusion:Array { 1 = ${props.subtitle} } attributes.subheadline = 'subheadline' @if.hasSubtitle = ${props.subtitle ? true : false} } image = PackageFactory.AtomicFusion.AFX:Image {
  16. Fusion Components - AFX Github: https://github.com/PackageFactory/atomic-fusion-afx EXPERIMENTAL CODE ... WILL

    LIKELY CHANGE ... BUT IT WORKS prototype(PackageFactory.AtomicFusion.AFX:Example) < prototype(PackageFactory.AtomicFusion:Component) { title = 'title text' subtitle = 'subtitle line' imageUri = 'https://dummyimage.com/600x400/000/fff' renderer = afx` <div> <h1 @key="headline" class="headline">{props.title}</h1> <h2 @key="subheadline" class="subheadline" @if.hasSubtitle={props.subtitle ? true : false}>{props.subtitle}</h2> <PackageFactory.AtomicFusion.AFX:Image @key="image" uri={props.imageUri} /> </div> ` }
  17. Fusion Components - AFX Github: https://github.com/PackageFactory/atomic-fusion-afx EXPERIMENTAL CODE ... WILL

    LIKELY CHANGE ... BUT IT WORKS prototype(PackageFactory.AtomicFusion.AFX:Example) < prototype(PackageFactory.AtomicFusion:Component) { title = 'title text' subtitle = 'subtitle line' imageUri = 'https://dummyimage.com/600x400/000/fff' renderer = afx` <div> <h1 @key="headline" class="headline">{props.title}</h1> <h2 @key="subheadline" class="subheadline" @if.hasSubtitle={props.subtitle ? true : false}>{props.subtitle}</h2> <PackageFactory.AtomicFusion.AFX:Image @key="image" uri={props.imageUri} /> </div> ` }
  18. Fusion Components - AFX Github: https://github.com/PackageFactory/atomic-fusion-afx EXPERIMENTAL CODE ... WILL

    LIKELY CHANGE ... BUT IT WORKS prototype(PackageFactory.AtomicFusion.AFX:Example) < prototype(PackageFactory.AtomicFusion:Component) { title = 'title text' subtitle = 'subtitle line' imageUri = 'https://dummyimage.com/600x400/000/fff' renderer = afx` <div> <h1 @key="headline" class="headline">{props.title}</h1> <h2 @key="subheadline" class="subheadline" @if.hasSubtitle={props.subtitle ? true : false}>{props.subtitle}</h2> <PackageFactory.AtomicFusion.AFX:Image @key="image" uri={props.imageUri} /> </div> ` }
  19. What to take home Don't use Partials Components in Fusion

    are a thing, use them today! Sitegeist.Monocle helps to develop reusable Components.