thymeleaf-layout-dialect icon indicating copy to clipboard operation
thymeleaf-layout-dialect copied to clipboard

Move the special $CONTENT_TITLE and $LAYOUT_TITLE values to context variables

Open ultraq opened this issue 7 years ago • 3 comments

These custom strings are only available within the scope of the layout:title-pattern processor, but there have been instances where devs have wanted access to these values elsewhere (usually the whole title).

Would it be possible to convert these into variables that I add to the current processing context instead so they can be used elsewhere? In the process, removing the custom placeholder names and turning them to something accessible via an expression instead (eg: ${CONTENT_TITLE}), taking advantage of the expression language to construct titles and any other strings using them.

ultraq avatar May 05 '18 00:05 ultraq

Will this ever be implemented?

justwiebe avatar May 12 '21 20:05 justwiebe

Gave this yet another try today, and I remembered why I left this one alone for so long...

In essence: a title can be anything. Developers aren't just putting text in between <title>...</title> tags:

  • they're using expressions with th:text/th:utext
  • or expression inlining
  • including it from other templates with th:include/th:insert
  • inserting their own HTML with <th:block> or other elements and using th:remove="tag"
  • running their own customer processors
  • and maybe more I haven't even thought of

The solution to handle all of the above was to put those "anything" parts in the correct places for the pattern given to layout:title-pattern, and then letting Thymeleaf process the result.

This does mean that the resulting title parts are no longer under the control of the layout dialect, and so being able to assign the results to template-wide context variables is not possible with the current suite of processors, and adding a new processor to be able to handle this feels very out-of-place with the layout dialect. As such, I'm going to close this issue.


For people coming to this in future and looking for ways to read the title, then some things that I thought of while attempting this:

  1. Use Thymeleaf's th:include processor with a fragment expression (th:include might be on its way out (https://github.com/thymeleaf/thymeleaf/issues/405), so this solution may have a limited lifespan):
<p th:include="~{::title}">The title will end up here</p>
  1. Create your own model processor that you can add to the the <title> element to read the result after the layout dialect has placed each title part and Thymeleaf has processed it:
class TitleModelProcessor extends AbstractAttributeModelProcessor {

  @Override
  protected void doProcess(ITemplateContext context, IModel model, AttributeName attributeName,
    String attributeValue, IElementModelStructureHandler structureHandler) {

    def titleText
    model.accept(new AbstractModelVisitor() {
      @Override
      void visit(IText text) {
        titleText = text
      }
    })

    // Do whatever you want with the title now that you have it 🎉
    println("Title is ${titleText}")
  }
}

As for being able to discern the content and layout title parts, that will depend on your own application as you'll know how those are put together.

ultraq avatar Jul 30 '22 08:07 ultraq

Reopening as I've had some inspiration on how to tackle this 💡 (Some 6 years later! 😅)

ultraq avatar Jan 21 '24 23:01 ultraq