我目前正在用百里香3.0.11.RELEASE为Bootstrap组件编写自定义方言。
用于模式的自定义标签处理器非常棘手。
标记结构应如下所示:
<thb:modal id="MyModal" size="default|small|large" title="Model Title" closeButton="true|false">
<!--
size-> (optional, if not present, take default)
closeButton-> (optional, if not present, take true)
role-> (optional, if not present, take diaglog)
tabindex -> (optional, in not present, take '-1'
-->
<thb:modal-body>
<p>Modal body text goes here.</p>
</thb:modal-body>
<thb:modal-footer>
<thb:button class="btn btn-primary">Save changes</thb:button>
<thb:button class="btn btn-secondary" data-dismiss="modal">Close</thb:button>
</thb:modal-footer>
</thb:modal>
如您所见,我具有自定义的嵌套标签:<thb:modal-body>
和<thb:modal-footer>
。
如何处理它们,使其看起来像这样:
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
直到现在我只有一个用于标记的处理器类
public class BootstrapModalTagProcessor extends AbstractElementTagProcessor {
private static String ELEMENT_NAME = "modal";
public BootstrapModalTagProcessor(final String dialectPrefix, final int precedence) {
super(TemplateMode.HTML, // This processor will apply only to HTML mode
dialectPrefix, // Prefix to be applied to name for matching
ELEMENT_NAME, // No tag name: match any tag name
true, // No prefix to be applied to tag name
null, // Name of the attribute that will be matched
false, // Apply dialect prefix to attribute name
precedence); // Remove the matched attribute afterwards
}
@Override
protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {
String id = HtmlEscape.escapeHtml5(tag.getAttribute("id").getValue());
String title = HtmlEscape.escapeHtml5(tag.getAttribute("title").getValue());
String size = HtmlEscape.escapeHtml5(Optional.ofNullable(tag.getAttribute("size")).map(IAttribute::getValue).orElse("default"));
String role = HtmlEscape.escapeHtml5(Optional.ofNullable(tag.getAttribute("role")).map(IAttribute::getValue).orElse("dialog"));
boolean closeButton = Boolean.parseBoolean(
HtmlEscape.escapeHtml5(
Optional.ofNullable(tag.getAttribute("closeButton"))
.map(IAttribute::getValue)
.orElse("true")
)
);
int tabindex = Integer.parseInt(
HtmlEscape.escapeHtml5(
Optional.ofNullable(tag.getAttribute("tabindex"))
.map(IAttribute::getValue)
.orElse("-1")
)
);
IModelFactory modelFactory = context.getModelFactory();
/*
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
*/
Map<String, String> attributes = Map.of(
"id", id,
"title", title,
"size", size,
"role", role);
IModel model = closeButton ? modalWithCloseButton(modelFactory, attributes) : modalWithoutCloseButton(modelFactory, attributes);
structureHandler.replaceWith(model, true); // true ==> processable by other thymeleaf dialect processors
}
}
我可以使用 org.thymeleaf.processor 包中的其他接口吗?
感谢您的帮助, 干杯。