packagefactory/atomicfusion-afx

该包已被弃用且不再维护。作者建议使用 neos/fusion-afx 包。

Neos.Fusion 的 JSX 启发式紧凑语法

安装数: 9,264

依赖者: 0

推荐者: 0

安全: 0

星标: 12

关注者: 3

分支: 1

开放问题: 1

类型:neos-package

v5.0.1 2018-04-27 09:28 UTC

README

该包已弃用,推荐使用 https://github.com/neos/fusion-afx。此包将继续可用于依赖它的现有设置,但不会添加错误修复或新功能。

Neos.Fusion 的 JSX 启发式紧凑语法

该包提供了一种融合预处理器,可以将紧凑的 xml 风格语法扩展为纯融合代码。这允许编写紧凑的组件,无需单独的模板文件,并使定义的原型具有计划外的可扩展性,因为生成的融合代码可以在需要时被覆盖和控制。

安装

PackageFactory.AtomicFusion.AFX 通过 Packagist 提供。只需将 "packagefactory/atomicfusion-afx" : "~3.0.0" 添加到 composer.json 的 require 部分,或运行 composer require packagefactory/atomicfusion-afx

我们使用语义版本控制,每次重大更改都会增加主版本号。

使用

使用此包,以下融合代码

prototype(PackageFactory.AtomicFusion.AFX:Example) < prototype(PackageFactory.AtomicFusion:Component) {

    title = 'title text'
    subtitle = 'subtitle line'
    imageUri = 'https://dummyimage.com/600x400/000/fff'
    
    #
    # The code afx`...` is converted to the fusion code below at parse time. 
    # Attention: Currently there is no way to escape closing-backticks inside the Expression. 
    #
    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>
    `
}

将被转换,解析并缓存,然后评估为等价于以下融合代码

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 = ${props.title}
                attributes.class = 'headline'
            }
            subheadline = Neos.Fusion:Tag {
                tagName = 'h2'
                content = ${props.subtitle}
                attributes.subheadline = 'subheadline'
                @if.hasSubtitle = ${props.subtitle ? true : false}
            }
            image = PackageFactory.AtomicFusion.AFX:Image {
                uri = ${props.imageUri}
            }
        }
    }
}

AFX 语言规则

忽略外部元素周围的全部空白。与换行符相连的空白被视为无关紧要并忽略。

HTML 标签(无命名空间标签)

HTML 标签被转换为 Neos.Fusion:Tag 对象。afx 标签的所有属性都作为标签属性渲染。

以下 HTML

<h1 class="headline" @if.hasHeadline={props.headline ? true : false}>{props.headline}</h1>

被转换成

Neos.Fusion:Tag {
    tagName = 'h1'
    attributes.class = 'headline'
    content = ${props.headline}
    @if.hasHeadline = ${props.headline ? true : false}
}

如果标签是自闭合且没有内容,它将被渲染为自闭合融合标签。

<br/>

被转换成

Neos.Fusion:Tag {
    tagName = 'br'
    selfClosingTag = true
}

融合对象标签(命名空间标签)

所有命名空间标签都被解释为原型名称,所有属性都作为顶级融合属性传递。

以下 HTML

<Vendor.Site:Prototype type="headline" @if.hasHeadline={props.headline ? true : false}>{props.headline}</Vendor.Site:Prototype>

被转换成

Vendor.Site:Prototype {
    type = 'headline'
    content = ${props.headline}
    @if.hasHeadline= ${props.headline ? true : false}
}

标签子元素

afx 节点下子节点的处理方式根据找到的 childNodes 的数量而不同。

单个标签子元素

如果 AFX 标签恰好包含一个子元素,则该子元素将直接渲染到 content 属性中。
子元素随后被解释为字符串、eel 表达式、html 或融合对象标签。

以下 AFX 代码

<h1>{props.title}</h1>

被转换成

Neos.Fusion:Tag {
    tagName = 'h1'
    content = {props.title}
}

多个标签子元素

如果 AFX 标签包含多个子元素,则内容将被渲染为 Neos.Fusion:Array 并放入 content 属性中。子元素被解释为字符串、eel 表达式、html 或融合对象标签。

以下 AFX 代码

<h1>{props.title}: {props.subtitle}</h1>

被转换成

Neos.Fusion:Tag {
    tagName = 'h1'
    content = Neos.Fusion:Array {
        item_1 = {props.title}
        item_2 = ': '
        item_3 = ${props.subtitle}
    }
}

标签子元素内的@key属性用于更改融合属性的名称,以便将数组子元素渲染进去。如果没有提供@key属性,则从x=1开始使用index_x

<Vendor.Site:Prototype @children="text">
    <h2 @key="title">{props.title}</h1> 
    <p @key="description">{props.description}</p>
</Vendor.Site:Prototype>

被转换成

Vendor.Site:Prototype {
    text = Neos.Fusion:Array { 
        title = Neos.Fusion:Tag {
            tagName = 'h2'
            content  = ${props.title}
        }
        description = Neos.Fusion:Tag {
            tagName = 'p'
            content  = ${props.description}
        }
    }
}

元属性

一般来说,所有元属性都是以@符号开头的。

@children属性定义了用于将当前标签的内容/子元素渲染进去的属性。子元素的默认属性名为content

@key属性可用于在渲染数组时定义其兄弟元素中某项的属性名。如果没有定义@key,则从`x=1`开始使用index_x

所有其他元属性都直接添加到生成的原型中,并可用于@if或@process语句。

空白符和换行符

Afx不是HTML,对代码进行了一些简化以优化生成的融合,并允许以结构化方式表示组件层次结构。

以下规则被应用

  1. 与换行符相连的新行和空白字符被视为无关紧要,并被忽略
<h1>
	{'eelExpression 1'}
	{'eelExpression 2'}
</h1>

被转换成

Neos.Fusion:Tag {
	tagName = 'h1'
	contents = Neos.Fusion:Array {
		item_1 = ${'eelExpression 1'}
		item_2 = ${'eelExpression 2'}   
	}
}
  1. 单行元素之间的空格被视为有意义的,并被保留
<h1>
	{'eelExpression 1'} {'eelExpression 2'}
</h1>

被转换成

Neos.Fusion:Tag {
	tagName = 'h1'
	contents = Neos.Fusion:Array {
		item_1 = ${'eelExpression 1'}
		item_2 = ' '
		item_3 = ${'eelExpression 2'}   
	}
}

示例

使用Neos.Fusion:Collection渲染集合

为了渲染列表或菜单,表示组件通常将预处理的数组数据作为prop接收。要在afx中迭代此类数组,可以使用Neos.Fusion:Collection

prototype(PackageFactory.AtomicFusion.AFX:IterationExample) < prototype(PackageFactory.AtomicFusion:Component) {
    
    # array {[href:'http://www.example_1.com', title:'Title 1'], [href:'http://example_2.com', title:'Title 2']}
    items = null
    
    renderer = afx`
        <ul @if.has={props.items ? true : false}>
        <Neos.Fusion:Collection collection={props.items} itemName="item" @children="itemRenderer">
            <li><a href={item.href}>{item.title}</a></li>
        </Neos.Fusion:Collection>
        </ul>
    `
}

使用PackageFactory.AtomicFusion:Augmenter增强子组件

可以使用PackageFactory.AtomicFusion:Augmenter来向渲染的内容添加额外的属性。这允许在不扩展组件API的情况下提供一些渲染灵活性。这是一个有用的模式,在只需要额外类的情况下,可以避免不必要的标签包装。

prototype(PackageFactory.AtomicFusion.AFX:SliderExample) < prototype(Packagefactory.AtomicFusion:Component) {
  images = ${[]}
  renderer = afx`
     <div class="slider">
        <Neos.Fusion:Collection collection={props.images} itemName="image" iterationName="iteration" @children="itemRenderer">
            <PackageFactory.AtomicFusion:Augmenter class="slider__slide" data-index={iteration.index}>
                <PackageFactory.AtomicFusion.AFX:ImageExample image={image} /> 
            </PackageFactory.AtomicFusion:Augmenter>
        </Neos.Fusion:Collection>  
     </div>
  `
}

该示例遍历一张图片列表,并使用PackageFactory.AtomicFusion.AFX:ImageExample渲染每一张图片,同时PackageFactory.AtomicFusion:Augmenter添加来自外部的类和数据属性。

许可

参见LICENSE文件