8000 Feature request: preserve_thymeleaf_template_syntax option · Issue #274 · wilsonzlin/minify-html · GitHub
[go: up one dir, main page]

Skip to content

Feature request: preserve_thymeleaf_template_syntax option #274

Open

Description

@HowieHz

Hi, thanks for this excellent project.

I'd like to request support for Thymeleaf template syntax preservation.

Background

minify-html already supports preserving several template syntaxes through:

  • preserve_brace_template_syntax
  • preserve_chevron_percent_template_syntax

However, Thymeleaf uses different markers that aren't currently recognized.

The Problem

Aggressive minification can silently break Thymeleaf templates. In practice, users end up having to skip minification entirely for any file containing Thymeleaf-sensitive syntax, which pretty much defeats the purpose of using minify-html in Thymeleaf-based projects.

Syntax That Needs to Be Preserved

One of Thymeleaf's core design goals is Natural Templates — templates that can be opened directly in a browser as static prototypes, while still being processed correctly by Thymeleaf on the server. This relies on several special syntax forms that must survive minification intact:

  1. JavaScript / CSS inline expressions (inside blocks with th:inline="javascript" or th:inline="css"):

    • /*[[ ... ]]*/ — escaped output
    • /*[( ... )]*/ — unescaped output
    • /*[# th:each="..."] ... /*[/]*/ — inline blocks, where /*[# ...]*/ is the opening marker and /*[/]*/ is the closing marker
  2. Advanced inlining features (also inside th:inline blocks):

    • /*[+ ... +]*/ — inlined code (only active when processed by Thymeleaf)
    • /*[- ... -]*/ — inlined code removal (only visible in static prototypes)
  3. Prototype-only comment blocks (in regular HTML):

    • <!--/*/ ... /*/--> — hidden as an HTML comment when opened statically, but treated as normal markup by Thymeleaf at runtime

Suggested Support

It would be great if minify-html could add a Thymeleaf-aware preservation mode, for example via:

  • a dedicated config option like preserve_thymeleaf_template_syntax
  • or a more generic API for registering custom delimiter pairs / preservation markers

A generic custom-delimiter mechanism would also work well if full Thymeleaf support is out of scope.

Why This Matters

Thymeleaf is widely used in the Java ecosystem, especially in Spring applications. Better preservation support would make minify-html significantly more practical for server-rendered Java templates.

Thanks!

Activity

  1. HowieHz commented on Mar 19, 2026

    @HowieHz
    Author

    As a simpler starting point, it might be enough to just skip minification for blocks containing th:inline, and preserve <!--/*/ ... /*/--> as-is. That would cover the most common breakage without needing full template syntax parsing.


    One more thing worth noting: Thymeleaf also supports expression inlining directly in HTML text nodes, enabled by default in HTML mode:

    <p>Hello, [[${session.user.name}]]!</p>
    <p>Hello, [(${session.user.name})]!</p>
    <p>Hello, [(${session.user.name == 'a' ? 'a' : 'b' })]!</p>
    <p>Hello, [(${session.user.name == 'a'
                ? 'a'
                        : 'b' })]!</p>

    It's unclear whether aggressive minification might affect these — since they live in plain text nodes, a conservative minifier would leave them alone, but a more aggressive one might not. If that turns out to be an issue, it would need separate handling. For now, skipping th:inline blocks and preserving should cover the most critical cases.


    Thanks again for considering this!

  2. HowieHz commented on Mar 19, 2026

    @HowieHz
    Author

    Also noticed another issue related to attribute minification. The minifier unquotes attribute values that don't contain whitespace or >. This works fine for standard HTML attributes, but breaks Thymeleaf th:* attributes whose values are expressions, not static strings.

    For example:

    <div th:data-x="${config.a}"></div>
    <div th:aria-label="${config.a}"></div>

    gets minified to:

    <div th:data-x=${config.a}></div>
    <div th:aria-label=${config.a}></div>

    This looks fine statically, but at runtime Thymeleaf evaluates ${config.a} and produces the final HTML. If the value contains spaces, e.g. "a b", the expected output would be:

    <div data-x="a b"></div>

    but instead you get:

    <div data-x=a b></div>

    which is a broken attribute. So it would also be helpful to skip attribute unquoting for th:* attributes.

  3. jogerj commented on May 18, 2026

    @jogerj

    This sounds like configuration error. Thymeleaf templates should be evaluated first, then you minify the output.

  4. HowieHz commented on May 18, 2026

    @HowieHz
    Author

    This sounds like configuration error. Thymeleaf templates should be evaluated first, then you minify the output.

    Just extending that idea a bit (off the existing options) so the processor can handle more templates cleanly.

    Distributing Thymeleaf templates is pretty much the standard way to ship themes in the Halo CMS community.

    Btw, that "evaluated first" thing you mentioned? Already a plugin in the Halo community: HowieHz/halo-plugin-extra-api – doesn't conflict with what this issue proposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0