java - 如何在 Thymeleaf 3.0.x 中的自定义方言的处理器中获取标签正文

标签 java thymeleaf

我最近为 thymeleaf 3.0.7 编写了一个自定义方言,其中包含一个标签处理器,用于将片段与自定义标签的主体合并。

例如我有一个像这样的片段

<!-- file fragments/myfrag.html -->
<div th:fragment="content(header)">
    <h1 th:text="${header}">Header 1</h1>
    <my:content/>
    <span>Some span</span>
</div>

还有一个自定义标签,例如

<my:merger my:mergefragment="fragments/myfrag :: content('Hello world')">
    <h2>Header 2</h2>
    <button>Test</button>
</my:merger>

结果应该是这样的

<div>
    <h1>Hello world</h1>
    <h2>Header 2</h2>   <!-- Content of my:merger -->
    <button>Test</button> <!-- Content of my:merger -->
    <span>Some span</span>
</div>

我的问题是如何获取自定义标签的正文 <my:merger> ?目前我有以下处理器。

public class MergerElementTagProcessor extends AbstractElementTagProcessor {

    private static final String TAG_NAME = "merger";

    public MergerElementTagProcessor(final String dialectPrefix) {
        super(TemplateMode.HTML, dialectPrefix, TAG_NAME, true, null, false, 1000);
    }

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

        final IEngineConfiguration configuration = context.getConfiguration();

        final Fragment fragment = (Fragment) computeFragment(context, tag.getAttributeValue("mergefragment"));
        final Writer stringWriter = new FastStringWriter(200);
        configuration.getTemplateManager().process(fragment.getTemplateModel(), context, stringWriter);

        String elementBody = getBody(tag); // how do I get the body of my <my:merger></<my:merger> tag at his point?

        structureHandler.replaceWith(merge(stringWriter.toString(), elementBody), false);
    }

    private String merge(String fragment, String elementBody) {
        return fragment.replace("<my:content/>", elementBody);
    }
}

感谢您提供任何帮助或提示。

最佳答案

作为 Metroids 提示的答案,我使用以下代码完成了它:

public class MergerElementTagProcessor extends AbstractElementModelProcessor {

    private static final String TAG_NAME = "merger";

    public MergerElementTagProcessor(final String dialectPrefix) {
        super(TemplateMode.HTML, dialectPrefix, TAG_NAME, true, null, false, 1000);
    }

    @Override
    protected void doProcess(ITemplateContext context, IModel model,
            IElementModelStructureHandler structureHandler) {

        IProcessableElementTag tag = processElementTag(context, model);  // convert IModel to IProcessableElementTag
        Map<String, String> attrMap = processAttribute(context, tag); // get attributes of tag

        IModel baseModelClone = model.cloneModel(); // clone base model
        IModel fragmentModel = (IModel) computeFragment(context, tag.getAttributeValue("mergefragment")); // get fragment as IModel

        model.reset(); // clear the model reference
        model.addModel(mergeModel(fragmentModel, baseModelClone, "<my:content/>")); // merge the two IModels
    }

    protected IModel mergeModel(IModel fragment, IModel body, final String replaceTag) {
        IModel mergedModel = insert(fragment, body, replaceTag);
        mergedModel = remove(mergedModel, replaceTag);
        mergedModel = remove(mergedModel, replaceTag);
        return mergedModel;
    }

    private IModel insert(IModel fragment, IModel body, final String replaceTag) {
        IModel mergedModel = fragment.cloneModel();
        int size = mergedModel.size();
        ITemplateEvent event = null;
        for (int i = 0; i < size; i++) {
            event = mergedModel.get(i);
            if (event instanceof IOpenElementTag) {
                if (event.toString().contains(replaceTag)) {
                    mergedModel.insertModel(i, body);
                    break;
                }
            }
        }
        return mergedModel;
    }

    private IModel remove(IModel fragment, final String replaceTag) {
        IModel mergedModel = fragment.cloneModel();
        int size = mergedModel.size();
        ITemplateEvent event = null;
        for (int i = 0; i < size; i++) {
            event = mergedModel.get(i);
            if (event instanceof IOpenElementTag || event instanceof ICloseElementTag) {
                if (event.toString().contains(replaceTag)) {
                    mergedModel.remove(i);
                    break;
                }
            }
        }
        return mergedModel;
    }

}

关于java - 如何在 Thymeleaf 3.0.x 中的自定义方言的处理器中获取标签正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46074574/

相关文章:

java - 为什么接口(interface)只能在顶级类中声明?

java - 如何将java对象转换为clojure中的映射?

java - 用于具有多个项目的单一存储库的 Azure Pipelines 仅构建更新的一个

java - Spring MVC + Thymeleaf - 正确的上下文路径处理

java - 如何在 Thymeleaf 中使用对象中包含的 HashMap 填充下拉列表?

java - antlr 返回值作为键值

java - 为什么 gradle 依赖项的 xml 配置带有 "Gradle__"前缀? Intellij IDEA 13

java - 将 Thymeleaf TemplateEngine 与 Vert.x 3.9 结合使用

java - Spring Boot 用户注册 - 将验证错误发送到 UI

jquery - 自定义滚动事件