@ 选项运算符如何在 AEM HTL 模板中工作

How does the @ option operator work in AEM HTL templates

我花了一点时间试图阅读 official documentation on the AEM @ operator and the official syntax 规范,但我不明白背后的逻辑。

让我们以文档中的这个例子为例:

${myVar @ optOne, optTwo=bar}

如何计算这个表达式?赋值optTwo=bar有什么作用?.

或者语法规范中的这个例子:

${myVar @ optOne, optTwo=myVar, optThree='string', optFour=[myVar, 'string']}

列表中的每项赋值 (optTwo=myVar, optThree='string', optFour=[myVar, 'string']) 将如何影响表达式计算的最终值?

在我的项目中,我们使用此 @ 运算符将值传递给 Java 后端逻辑。我创建了一个示例 use-case 来演示 @ 运算符的用法。

我创建了一个带有文本字段、数字字段和复选框的简单信息组件。对应的cq:dialog的.content.xml如下-

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Info"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/container">
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/layouts/tabs"
            type="nav"/>
        <items jcr:primaryType="nt:unstructured">
            <tab
                jcr:primaryType="nt:unstructured"
                jcr:title="Properties"
                sling:resourceType="granite/ui/components/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <columns
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/foundation/container">
                        <items jcr:primaryType="nt:unstructured">
                            <name
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                class="field-whitespace"
                                fieldDescription="Enter full name of the user"
                                fieldLabel="Full Name"
                                name="./fullName"/>
                            <age
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/numberfield"
                                class="field-whitespace"
                                fieldDescription="Enter the age of the user"
                                fieldLabel="Age"
                                name="./age"/>
                            <married
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/checkbox"
                                class="field-whitespace"
                                fieldDescription="Check if the user is married"
                                name="./married"
                                text="Married?"
                                value="true"/>
                        </items>
                    </columns>
                </items>
                <layout
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
            </tab>
        </items>
    </content>
</jcr:root>

对应的HTL文件如下-

<div data-sly-test="${wcmmode.edit || wcmmode.design}">
    Info Component
</div>

<sly
    data-sly-use.info="${'org.redquark.aem.learning.core.cq.text.InfoComponent' @
        fullName=properties.fullName,
        age=properties.age,
        married=properties.married
    }" />

<sly data-sly-test="${info}">
    <h1>${info.details}</h1>
</sly>

在这里,您可以看到在标记中,我们在变量 fullNameage已婚.

读取这些值的java代码如下-

package org.redquark.aem.learning.core.cq.text;

import com.adobe.cq.sightly.WCMUsePojo;

public class InfoComponent extends WCMUsePojo {

    private String details;

    @Override
    public void activate() throws Exception {

        String fullName = get("fullName", String.class);
        Integer age = Integer.parseInt(get("age", String.class));
        Boolean isMarried = Boolean.parseBoolean(get("married", String.class));

        details = fullName + " is " + age + " years old and is " + (isMarried ? "married" : " not married");
    }

    /**
     * @return the details
     */
    public String getDetails() {
        return details;
    }
}

或者,如果您使用的是 SlingModels 而不是 Java 使用 API,那么您可以以典型的 Sling 模型方式访问这些值。

package org.redquark.aem.learning.core.models.text;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;


@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class InfoModel {

    @Inject
    @Optional
    @Default(values = "Test")
    private String fullName;

    @Inject
    @Optional
    @Default(values = "0")
    private String age;

    @Inject
    @Optional
    @Named("married")
    @Default(values = "false")
    private String isMarried;

    // Variable that will be read in the HTL file
    private String details;

    @PostConstruct
    protected void init() {

        details = fullName + " is " + Integer.parseInt(age) + " years old and is "
                + (Boolean.parseBoolean(isMarried) ? "married" : " not married");
    }

    /**
     * @return the details
     */
    public String getDetails() {
        return this.details;
    }

}

当然,那你得在HTL代码中调用你的InfoModel class as

<sly data-sly-use.info="${'org.redquark.aem.learning.core.models.text.InfoModel' @
        fullName=properties.fullName,
        age=properties.age,
        married=properties.married
    }" />

你看,这里我们正在读取在 HTL 代码中传递的相同值。然后我们可以对它们执行任何业务逻辑。

希望对您有所帮助。干杯!