AFX Syntax

Draft

This page is not yet fully completed - we are still working on the content here. Expect some rough edges 🙃

#Fusion decorators / meta properties

#@apply / {...spread}

In AFX you are allowed to so called spreads. But those are just syntactic sugar and will be transpiled to Fusion's @apply meta property.

AFX
<a {...props}>Is the same as @apply</a>
fusion
Neos.Fusion:Tag {
    tagName = 'a'
    attributes.@apply.spread_1 = ${props}
    content = 'Is the same as @apply'
}
fusion
attributes = Neos.Fusion:DataStructure {
	class = 'my-button'
	id = 'bestButton'
}

#@if / @process

These meta properties translate directly to Fusion. But in AFX one is allowed to omit the describing subkey as short notation:

AFX
<a @if={true}>Is a shorthand for @if.*</a>
fusion
Neos.Fusion:Tag {
    tagName = 'a'
    @if.if_1 = ${true}
    content = 'Is a shorthand for @if.*'
}

#AFX specific decorators / meta properties

#@key

@key overrides the default generated key for the object. 

AFX
<h2>Heading</h2>
<br @key="breakline" />
This is just flow content
fusion
Neos.Fusion:Array {
    item_1 = Neos.Fusion:Tag {
        tagName = 'h2'
        content = 'Heading'
    }
    breakline = Neos.Fusion:Tag {
        tagName = 'br'
        selfClosingTag = true
    }
    item_3 = 'This is just flow content'
}

Heading


This is just flow content

#@children

Content between the object tags gets written per default to the content prop of the object. To change this you can define @children  

AFX
<Docs:Button @children="text">
  I do nothing
</Docs:Button>
fusion
MySite:Button {
    text = 'I do nothing'
}
fusion
prototype(Docs:Button) < prototype(Neos.Fusion:Component) {
	renderer = afx`<button>{props.text}</button>`
}

#@path

Move an object to the prop of a parent with @path 

AFX
<Docs:Article>
  <h2 @path="heading">This should move to the heading</h2>
  <p>This is default content</p>
</Docs:Article>
fusion
Docs:Article {
    heading = Neos.Fusion:Tag {
        tagName = 'h2'
        content = 'This should move to the heading'
    }
    content = Neos.Fusion:Tag {
        tagName = 'p'
        content = 'This is default content'
    }
}
fusion
prototype(Docs:Article) < prototype(Neos.Fusion:Component) {
	renderer = Neos.Fusion:Tag {
		tagName = 'article'

		attributes.class = 'my_article'

		content = Neos.Fusion:Join {
			item_0 = Neos.Fusion:Tag {
				tagName = 'div'
				attributes.class = 'my_article_heading'
				content = ${props.heading}
			}
			item_1 = ${props.content}
		}
	}
}

This should move to heading

This should just flow.

#Syntax Examples

#Simple

AFX gets transpiled to Fusion. See the transpiled output inside "Generated Fusion".

AFX
<p class="paragraph">
  <strong>This is strong</strong><br>
  This is just flow content
</p>
fusion
Neos.Fusion:Tag {
    tagName = 'p'
    attributes.class = 'hello'
    content = Neos.Fusion:Join {
        item_1 = Neos.Fusion:Tag {
            tagName = 'strong'
            content = 'This is strong'
        }
        item_2 = Neos.Fusion:Tag {
            tagName = 'br'
        }
        item_3 = 'This is just flow content'
    }
}

This is strong
This is just flow content

#Complex

This example contains all common syntax patterns.

AFX
<article class="hello">
  <My.Site:IdGenerator @path="attributes.id" />
  <h2 @key="heading" @if={!props.heading}>AFX Preview</h2>
  <Neos.Fusion:Loop items="props.items" itemName="item">
	<p>{item}</p>
  </Neos.Fusion:Loop>
  <Neos.Fusion:Augmenter class={props.link == '#top' ? 'int' : 'ext'}>
	<Neos.Fusion:Tag
		@if={Type.isString(props.link)}
		attributes.href={props.link}
		{...props.linkProps}
		tagName='a'
		attributes.rel='bookmark'
	>
	  Read more
	</Neos.Fusion:Tag>
  </Neos.Fusion:Augmenter>
</article>
fusion
Neos.Fusion:Tag {
    tagName = 'article'
    attributes.class = 'hello'
    attributes.id = My.Site:IdGenerator {
    }
    content = Neos.Fusion:Join {
        heading = Neos.Fusion:Tag {
            tagName = 'h2'
            @if.if_1 = ${!props.heading}
            content = 'AFX Preview'
        }
        item_2 = Neos.Fusion:Loop {
            items = 'props.items'
            itemName = 'item'
            content = Neos.Fusion:Tag {
                tagName = 'p'
                content = ${item}
            }
        }
        item_3 = Neos.Fusion:Augmenter {
            class = ${props.link == '#title' ? 'int' : 'ext'}
		    content = Neos.Fusion:Tag {
			  	attributes.href = ${props.link}
			 	@apply.spread_1 = ${props.linkProps}
			  	tagName = 'a'
			  	attributes.rel = 'bookmark'
			  	content = 'Read more'
		    }
        }
    }
}
rendering context
heading = null
linkProps = Neos.Fusion:DataStructure {
	attributes.title = 'Click me'
	attributes.href = '#top'
	attributes.class = 'default-link'
	attributes.rel = 'help'
}
items = Neos.Fusion:DataStructure {
	first = 'First paragraph'
	second = 'Second paragraph'
}
link = "https://www.neos.io/"

AFX Preview

First paragraph

Second paragraph

Read more