-
Notifications
You must be signed in to change notification settings - Fork 493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What is the scope of fragment expression selector? #626
Comments
Of cause I see recommendationы to name fragments differently from HTML tags to avoid ambiguity and my discovery shows problems in identifying what DOM is captured. It is better to have named argument in fragment and functions/operations/syntax that allows getting part of DOM via CSS/XPath selector syntax. Is it possible? |
Not necessarily. Only if these arguments are added to the fragment's signature. But it is possible to add arguments to a fragment call specifying a name for them, even if they are not in the signature, and then let them be used. This allows therefore for optional fragment parameters: <head th:fragment="common_header(title)">
<th:block th:replace="${links} ?: ~{}" /> And then: <head th:replace="temp :: common_header(title='Nice page',links=~{::links})"> Note the Alternatively, you could leave your
I understand in this case you are enunciating a preference for a different type of layout architecture: a hierarchical one instead of a pull-based or fragment-inclusion-based one like Thymeleaf uses by default. Hierarchical layout is not the preferred default option in Thymeleaf for a number of reasons (mostly related to how it negatively affects HTML design), but it is anyway a possibility using extensions like the Layout Dialect (have look at the ecosystem page).
As far as I understand the situation here, the behaviour is the expected. If you have: <!-- thymeleaf/default/layout.html -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<nav></nav>
<div th:replace="this :: body"/>
</body>
</html>
<!-- thymeleaf/page.html -->
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="thymeleaf/layout/default :: html">
<body>
XXX
</body>
</html> ...and you render <html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<nav></nav>
<div th:replace="this :: body"/>
</body>
</html> And the
But that's not how fragment expressions work. When the template in them is specified as Or alternatively, you could use the name of the template being processed (meaning "the one for which the template engine was originally called") and use it in the fragment expression at your <!-- thymeleaf/default/layout.html -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<nav></nav>
<div th:replace="${#execInfo.processedTemplateName} :: body"/>
</body>
</html>
<!-- thymeleaf/page.html -->
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="thymeleaf/layout/default :: html">
<body>
XXX
</body>
</html> At runtime, when processing the Have a look at this
This ambiguity is advised against because the expression So in summary, I believe that your needs should be covered by the Layout Dialect and your questions answered above. If so, please go ahead and close this ticket. |
By marking template body with class attribute I can match any parts from original page if Xpath/CSS selector can't find match inside template. How that can be? I was afraid using provided template in production, because it is not clear why that happen. Though, you provided much safer way to refer to original page via: And there is an option to use Layout Dialect. |
This page https://stackoverflow.com/a/20449189/173149 also refer to:
from template via: so original page content become available via |
Because it works up in the stack of calls. If your specified fragment (with However, in your case –if I understood correctly– that would be a completely unintended effect, because you don't want to match some |
Wow! I miss that part (about lookup in template hierarchy stack). Now I see that my questionable code is legitimate but it is safer to stick to suggested Thanks for support. |
I am new to Thymeleaf, heard about it 4 years ago (so v2.x) that it has layout support. During learning of Thymeleaf 3 features I began to think that it is possible to implement layout design with Fragment expression.
What is desired is so called "Mashup" (forgot precise name) layout style when fragments are enriched with surrounding elements, not just inserted in place. One of such example provided in official docs:
http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#flexible-layouts-beyond-mere-fragment-insertion
where fragment expression
~{::link}
selects CSS style references from page and pass them to fragment:In addition to CSS/JS I want to add
<nav>
to each page.What is the problem with fragment expressions?
th:fragment
and all of them should be passed or rendering will fail.head
andbody
usually are processed separately in most examples on the Web. So you have a lot ofth:replace
instead of single.So I asked if it is possible to pass
html
via fragment expression and extract parts from that object:https://stackoverflow.com/questions/45183075/what-type-of-operation-and-syntax-for-them-are-possible-on-thymeleaf-3-fragment/
That is single
th:replace
with single fragment expression argument~{::html}
. But it seems that you can't do anything with that object in fragment because there is no Thymleaf language syntax and there is no support in API (I believeTemplateModel
is actual holder of page DOM and its API allow only to pass visitor or write to stream).I came across https://stackoverflow.com/questions/18896915/thymeleaf-templates-is-there-a-way-to-decorate-a-template-instead-of-including and tried that technique (here it is https://stackoverflow.com/a/45187766/173149 ):
template:
and page:
Page is rendered into infinite sequence of
<body><nav>
. That because ~{this::body} select template body with has recursive link to itself.But what is interested that expression fragment allows to match original page DOM! So I guarded selector with valid class attribute:
Now selector captures page
html
!That allows to have rich layout support without needs to place many
th:replace
and many arguments to fragment expressions and even maintain fragment expressions on pages!For example "smart template" with navigation and extensible CSS/JS can be defined as:
Note: I don't define name for fragment in template. It is not necessary for example to work.
What I am worry about is if it not a bug in current implementation. How can fragment selector in template capture itself and external page?
The text was updated successfully, but these errors were encountered: