Tasty Atomic.Fusion recipes for your website - NeosConference 2018

Tasty Atomic.Fusion recipes for your website - NeosConference 2018

8682955fc87df72a1c9284b271e9f414?s=128

Sitegeist

April 14, 2018
Tweet

Transcript

  1. Real Values. Tasty Atomic.Fusion recipes for your website Martin Ficzel

  2. Real Values. Martin Ficzel • Backend Developer • ficzel@sitegeist.de •

    twitter/slack: @kopfaufholz • Neos Team-Member Atomic-Fusion, AFX • Sitegeist.Monocle • 2 Kids, Climber
  3. Real Values. !!! Tons of code ahead

  4. Real Values. Terms

  5. Real Values. AFX

  6. Real Values. AFX renderer = afx` <div> <h1 class="headline">{props.title}</h1> <h2

    class="subheadline" @if.has={props.subtitle}>{props.subtitle}</h2> <Vendor.Site:Image uri={props.imageUri} /> </div> `
  7. Real Values. Fusion renderer = Neos.Fusion:Tag { tagName = 'div'

    content = Neos.Fusion:Array { item_1 = Neos.Fusion:Tag { tagName = 'h1' content = ${props.title} attributes.class = 'headline' } item_2 = Neos.Fusion:Tag { tagName = 'h2' content = ${props.subtitle} attributes.subheadline = 'subheadline' @if.hasSubtitle = ${props.subtitle ? true : false} } Vendor.Site:Image {
  8. Real Values. AFX Fusion, optimized for presentation • Easy to

    read and declarative • Usable without Atomic.Fusion • Makes Fluid obsolete • Eliminates a lot of jumping back and forth between templates and fusion • No negative runtime effects
  9. Real Values. Neos.Fusion.AFX composer require neos/fusion-afx

  10. Real Values. Atomic.Fusion

  11. Real Values. Fusion • Neos.Fusion:Component • Neos.Fusion:Augmenter Neos • Neos.Neos:ContentComponent

    • Neos.Neos:Editable Prototypes
  12. Real Values. • Separation of Presentation and Integration • Isolation

    of all visual aspects in presentational components Principles for structuring projects
  13. Real Values. Atomic.Fusion is an advanced concept!

  14. Real Values. Patterns for Presentation

  15. Real Values. Presentational Component

  16. Real Values. Presentational Component prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Component) { title =

    '' description = '' renderer = afx` <div class="component"> <h1>{props.title}</h1> <p>{props.description}</p> </div> `
  17. Real Values. Definition • Presentational components encapsulate the visual aspects

    for the representation of a data structure. This includes the generation of markup, styling and interaction via scripts. • Presentational components are side effect free but may rely on other presentational components to perform their job.
  18. Real Values. Composition

  19. Real Values. Composition prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Component) { title = ''

    description = '' imageUri = null renderer = afx` <div class="component"> <Vendor.Site:Component.Image src={props.imageUri} alt={props.title} /> <h1>{props.title}</h1> <p>{props.description}</p>
  20. Real Values. Flag

  21. Real Values. Flags prototype(Vendor.Site:Component.Atom.Headline) < prototype(Neos.Fusion:Component) { title = null

    isSpecial = false renderer = afx` <h1 class={'headline' + (props.isSpecial && ' headline--bold')} >{props.title}</h1> ` }
  22. Real Values. Modifier

  23. Real Values. Modifier prototype(Vendor.Site:Component.Atom.Headline) < prototype(Neos.Fusion:Component) { title = null

    modifier = null renderer = afx` <h1 class={'headline' + (props.modifier && (' headline--' + modifier))} >{props.title} ` @propTypes { modifier = ${PropTypes.oneOf('bold', 'italic')} } }
  24. Real Values. Augment

  25. Real Values. Augmentation prototype(Vendor.Site:Component.Molecule.TeaserList) < prototype(Neos.Fusion:Componen renderer = afx` <div

    class="teaserlist" data-filter="true"> <Neos.Fusion:Augmenter data-filter-region={teaser.region} data-filter-category={teaser.category} class=”teaserlist__item” > <Vendor.Site:Component.Molecule.Teaser title={teaser.title} description={ /> </Neos.Fusion:Augmenter> ... iv>
  26. Real Values. Conditional Tagname

  27. Real Values. Conditional Tagname prototype(Vendor.Site:Component.Atom.Button) < prototype(Neos.Fusion:Component) { link =

    null title = null renderer = afx` <Neos.Fusion:Tag tagName={props.link ? 'a' : 'span'} href={props.link} attributes.class="button" > {props.title} </Neos.Fusion:Tag>
  28. Real Values. Optional Section

  29. Real Values. Optional Section prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Compone title = ''

    subtitle = '' renderer = afx` <div class="component"> <h1>{props.title}</h1> <h2 @if.hasSubtitle={props.subtitle} > {props.subtitle} </h2> </div> ` }
  30. Real Values. Collection

  31. Real Values. Collection prototype(Vendor.Site:Component.Molecule.Slider) < prototype(Neos.Fusion:Component) { // [ {title:

    'lorem', href: 'http://dummyimage.com' }, ... ] items = null renderer = afx` <div class="slider" > <Neos.Fusion:Collection collection={props.items} itemName="item" @children="itemRenderer" > <Vendor.Site:Component.Molecule.Slider.Slide> <Vendor.Site:Component.Image src={item.href} title={item.title}/> /Vendor.Site:Component.Molecule.Slider.Slide>
  32. Real Values. Container

  33. Real Values. Container prototype(Vendor.Site:Component.Molecule.Accordeon) < prototype(Neos.Fusion:Compone title = '' content

    = '' renderer = afx` <div class="accordeon"> <div class="accordeon__header">{props.title}</div> <div class="accordeon__content">{props.content}</div> </div> ` }
  34. Real Values. Container - content prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Component) { renderer

    = afx` <Vendor.Site:Component.Molecule.Accordeon title=”Headline” > Lorem ipsum </Vendor.Site:Component.Molecule.Accordeon> ` }
  35. Real Values.

  36. Real Values. Component APIs

  37. Real Values. Presentational Component APIs • Mainly simple values /

    Meaningful Names • “content” is a nice name for a html string • Complex Data ◦ Collections ◦ Hashmaps • !!! never pass domain objects ◦ Convert to simple values like uris instead
  38. Real Values. WWJD?

  39. Real Values. What Would JSON Do

  40. Real Values. Additional Tools for Presentation

  41. Real Values. Sitegeist.Monocle prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Component) { @styleguide { title

    = 'Example Component' props { title = 'Lorem ipsum' description = 'dolor sit amet ...' imageUri = '//dummyimage.com/600x400/000/fff' } } } composer require sitegeist/monocle
  42. Real Values. PropTypes prototype(Vendor.Site:Component.Example) < prototype(Neos.Fusion:Component) { @propTypes { title

    = ${PropTypes.string.isRequired} description = ${PropTypes.string} imageUri = ${PropTypes.string} } } composer require packagefactory/atomicfusion-proptypes
  43. Real Values. Structuring the namespace

  44. Real Values. Atomic Design • Bottom up - principle •

    Atoms, Molecules, Organism, Template • Seldomly used for design but often used to structure code • !!! Effective way to find inconsistencies in design via coding
  45. Real Values. Your Method! The recommended way • Reflects your

    design process and intention • Common knowledge of your team members • Ubiquitous Language between FE and BE • Start where you are!
  46. Real Values. Snowflake Method • Top down • Take whole

    layout • Split into parts • Repeat the last step • !!! Naming things is hard • !!! Finding the granularity is hard
  47. Real Values. Be pragmatic there is no final structure •

    Talk to designers • Use parts of Atomic.Design or other design systems that fit • Mind your future self • Iterate
  48. Real Values.

  49. Real Values. Patterns for Integration

  50. Real Values. Hidden secrets of Neos

  51. Real Values. Secret 1: NodeType >> Fusion Prototype type =

    ${q(node).property('_nodeType.name')}
  52. Real Values. Secret 2: PrototypeGenerator # # Disable automagic fusion

    prototypes # Vendor.Site:Content.Example: options: fusion: prototypeGenerator: ~
  53. Real Values. <!-- Collection/Content: ContentElementWrapping --> <div data-__neos-node-contextpath="/sites/sitegeistde/main/node-j3xwsoeihfthx@ data-__neos-fusion-path="page<Vendor.Site:Base>/body<Neos.Fusion:Array >

    <h1> <!-- Editable: ContentEditableWrapping --> <span data-__neos-property="title" data-__neos-editable-node-contextpath="/sites/sitegeistde/main/no > Lorem ipsum dolor sit amet </span> Neos Secret 3: Backend Metadata
  54. Real Values. Content Mapping

  55. Real Values. Using a presentational component prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Neos:ContentComponent) {

    renderer = Vendor.Site:Component.Molecule.Teaser { title = "Lorem ipsum" description = "dolor sit amet" imageUrl = "//dummyimage.com/600x400/000/fff" link = "http://www.sitegeist.de" } }
  56. Real Values. Neos.Neos:ContentComponent = Component + ContentElementWrapping

  57. Real Values. Property mapping prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Neos:ContentComponent) { renderer =

    Vendor.Site:Component.Molecule.Teaser { title = ${q(node).property('title')} description = ${q(node).property('description')} imageUrl = Neos.Neos:ImageUri { asset = ${q(node).property('image')} } link = ${q(node).property('link')} link.@process.convertUris = Neos.Neos:ConvertUris link.@if.isLive = ${node.context.live}
  58. Real Values. Editable mapping prototype(Vendor.Site:Content.Teaser) < prototype(Neos.Neos:ContentComponent) { renderer =

    Vendor.Site:Component.Molecule.Teaser { title = Neos.Neos:Editable { property = 'title' } description = Neos.Neos:Editable { property = 'description' } } }
  59. Real Values. Neos.Neos:Editable = BackendTag + ContentEditableWrapping

  60. Real Values. Container Mapping

  61. Real Values. Collection > Container - 1 prototype(Vendor.Site:Content.TwoColumn) < prototype(Neos.Neos:ContentComponent)

    renderer = Vendor.Site:Component.Molecule.TwoColumn { left = Neos.Neos:PrimaryContent { nodePath = 'left' } right = Neos.Neos:PrimaryContent { nodePath = 'right' } } }
  62. Real Values. Collection > Container 2 prototype(Vendor.Site:Content.Accordeon) < prototype(Neos.Neos:ContentComponent) {

    renderer = Vendor.Site:Component.Molecule.Accordeon { title = Neos.Neos:Editable { property = 'title' } content = Neos.Neos:ContentCollectionRenderer } }
  63. Real Values. Collection

  64. Real Values. Collection > List prototype(Vendor.Site:Content.Slider) < prototype(Neos.Neos:ContentComponent) { renderer

    = Vendor.Site:Component.Molecule.Slider { slides = Neos.Fusion:RawCollection { collection = ${q(node).children('[instanceof Vendor.Site:Content.Slider.Slide]').get itemName = 'slide' itemRenderer = Neos.Fusion:RawArray { title = ${q(slide).property('title')} imageUri = Neos.Neos:ImageUri { asset = ${q(slide).property('image')} } } }
  65. Real Values. !!! Editable List prototype(Vendor.Site:Content.Slider) < prototype(Neos.Neos:ContentComponent) { renderer

    = Vendor.Site:Component.Molecule.Slider { slides = Neos.Fusion:RawCollection { itemName = 'slide' itemRenderer = Neos.Fusion:RawArray { __slideNode = ${slide} } } prototype(Vendor.Site:Component.Molecule.Slide) { @process.contentElementWrapping = Neos.Neos:ContentElementWrapping { node = ${item.__slideNode} } }
  66. Real Values. !!! Editable List prototype(Vendor.Site:Content.Slider) < prototype(Neos.Neos:ContentComponent) { renderer

    = Vendor.Site:Component.Molecule.Slider { slides = Neos.Fusion:RawCollection { itemName = 'slide' itemRenderer = Neos.Fusion:RawArray { __slideNode = ${slide} title = Neos.Neos:Editable { property = 'title' node = ${slide} } } }
  67. Real Values.

  68. Real Values. Presentation != Integration

  69. Real Values. #project-atomic-fusion

  70. Real Values. Thank You!

  71. Real Values. Questions?