Thymeleaf定制方言与标准表达

问题描述 投票:0回答:2

我创建了一个自定义的Thymeleaf 3方言,如果我只使用静态属性值,它可以正常工作:

<formBuilder:inputRow title="Email:" name="email" value="[email protected]" />

但是,我想使用标准的Thymeleaf表达式来填充value属性,但如果我写这个:

<formBuilder:inputRow title="Email:" name="email" value="${user.email}" />

输出将是文本$ {user.email}而不是真实的电子邮件地址。

如果我使用th:这样的值:

<formBuilder:inputRow title="Email:" name="email" th:value="${user.email}" />

那么根本就没有生成任何值字段。

方言课如下。它只注册一个elementTag处理器:

public class FormBuilderDialect extends AbstractProcessorDialect {

    private static final String DIALECT_NAME = "Form Builder Dialect";

    public FormBuilderDialect() {
        super(DIALECT_NAME, "formBuilder", StandardDialect.PROCESSOR_PRECEDENCE);
    }

    @Override
    public Set<IProcessor> getProcessors(String dialectPrefix) {
        final Set<IProcessor> processors = new HashSet<IProcessor>();
        processors.add(new InputElementTagProcessor(dialectPrefix));
        return processors;
    }
}

元素处理器是:

public class InputElementTagProcessor extends AbstractElementTagProcessor {

    private static final String TAG_NAME = "inputRow";
    private static final int PRECEDENCE = 1000;

    public InputElementTagProcessor(final String dialectPrefix) {
        super(
                TemplateMode.HTML, // This processor will apply only to HTML mode
                dialectPrefix,     // Prefix to be applied to name for matching
                TAG_NAME,          // Tag name: match specifically this tag
                true,              // Apply dialect prefix to tag name
                null,              // No attribute name: will match by tag name
                false,             // No prefix to be applied to attribute name
                PRECEDENCE);       // Precedence (inside dialect's own precedence)
    }

    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {

        final String name = tag.getAttributeValue("name");
        final String value = tag.getAttributeValue("value");

        final IModelFactory modelFactory = context.getModelFactory();

        final IModel model = modelFactory.createModel();

        // Add input
        Map<String, String> inputAttributes = new HashMap<>();
        inputAttributes.put("name", name);
        inputAttributes.put("value", value);
        model.add(modelFactory.createStandaloneElementTag("input", inputAttributes, AttributeValueQuotes.DOUBLE, false, false));

        structureHandler.replaceWith(model, false);
    }
}

不知道怎么解决这个问题?

spring spring-mvc thymeleaf
2个回答
1
投票

有同样的问题,有一个更简单的方法。

<formBuilder:inputRow title="Email:" name="email" th:attr="value=${user.email}" />


0
投票

要解决这个问题,我必须创建一个属性标记处理器,如下所示:

public class FormBuilderAttributeTagProcessor extends AbstractAttributeTagProcessor {

    private static final String ATTR_NAME = "value";
    private static final int PRECEDENCE = 100;

    public FormBuilderAttributeTagProcessor(final String dialectPrefix) {
        super(
                TemplateMode.HTML,
                dialectPrefix,
                "inputRow",
                true,
                ATTR_NAME,
                false,
                PRECEDENCE,
                false);
    }

    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {
        final IEngineConfiguration configuration = context.getConfiguration();

        final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);

        final IStandardExpression expression = parser.parseExpression(context, attributeValue);

        final String result = (String) expression.execute(context);

        structureHandler.setAttribute("value", result);
    }
}

并将其注册为方言类中的处理器:

public class FormBuilderDialect extends AbstractProcessorDialect {

    private static final String DIALECT_NAME = "Form Builder Dialect";

    public FormBuilderDialect() {
        super(DIALECT_NAME, "formBuilder", StandardDialect.PROCESSOR_PRECEDENCE);
    }

    @Override
    public Set<IProcessor> getProcessors(String dialectPrefix) {
        final Set<IProcessor> processors = new HashSet<IProcessor>();
        processors.add(new InputElementTagProcessor(dialectPrefix));
        processors.add(new FormBuilderAttributeTagProcessor(dialectPrefix));
        return processors;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.