Announcement Announcement Module
Collapse
No announcement yet.
PetClinic + HTML5 with Thymeleaf Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • PetClinic + HTML5 with Thymeleaf

    Hi all,

    At the Thymeleaf project [ http://www.thymeleaf.org ], we've just published a new article explaining how we modernized the view layer of the "PetClinic" Spring example application.

    All the JSPs have been replaced with Thymeleaf templates, taking advantage of its "Natural Templating" abilities (templates are valid static HTML prototypes), and the original XHTML has been replaced with HTML5.

    You can see it here: http://www.thymeleaf.org/petclinic.html

    Regards,
    Daniel.

  • #2
    Great showcase!

    Thymeleaf should become the view technology for Spring-MVC!

    regards
    Grzegorz Grzybek

    p.s. Thymeleaf-based web application in one of Polish ministries is working very well!

    Comment


    • #3
      Hi Daniel

      Thanks for the update. I started a new Spring MVC based project in March-2012 and looked at ThymeLeaf as one of the view technologies that could be used. I liked ThymeLeaf very much but ended up not using it because of 2 reasons.

      The first reason was that it was not clear how layouts can be created with ThymeLeaf (in a Spring MVC application). I have quickly browsed through the latest sample you have published. Can I request that you put up an article as well that walks developers through creating a web application having multiple layouts with ThymeLeaf? The basic use case I am interested in involves a simple app with 6 pages with 3 layouts (say, 1 column and 2 column page layouts and a popup layout) and how the pages declare which layout they want to use.

      The second reason was rendering performance. I tried with the latest ThymeLeaf version available in March-2012 and found its performance to be significantly slower than FreeMarker and Velocity. It will be good to see an honest benchmark with the latest version. I would like to see a benchmark with 2 simple pages - one with an HTML table with over 200 rows and the other with a collage of over 1000 images.

      I would be more than happy to port our current view code from FreeMarker to ThymeLeaf if these two things have been sorted out.

      In any case, I like ThymeLeaf and my congratulations for the latest sample.

      Comment


      • #4
        @Grzegorz -- Thanks a lot for your kind comments :-)


        @manish.in.java :

        Thanks for your interest. Layout techniques with Thymeleaf will be the topic of an article to be published soon, as it seems to be a hot topic among new developers coming to Thymeleaf, and nowadays it doesn't seem to be 100% well explained at the tutorials.

        There are two main alternatives for managing page layout in Thymeleaf, which I will call the "standard/pull" and the "traditional/hierarchical".

        Explaining the hierarchichal approach first will probably make it easier to understand: this approach allows you to first define "base pages" in which you define placeholders where your dynamic elements will be rendered. These base pages can usually be organized as a hierarchy and the real rendering markup of a page will therefore be splitted among several levels in a hierarchy --each of them being a non-complete and probably non-displayable HTML page--. Typical examples of this are SiteMesh, Apache Tiles or the Apache Wicket templating system.

        Thymeleaf can be used with SiteMesh thanks to the non-intrusive nature of SiteMesh [See http://forum.thymeleaf.org/Themes-in...td3216297.html -- A specific article regarding this integration will be published in the near future too]. Other layout engines like Tiles are much more intrusive (Tiles is 100% intrusive, in fact) and as of today cannot be used with Thymeleaf, although perhaps developing an integration module is already possible --I don't know.

        As for the second approach, which I called "standard" because it is the usual way of doing layouts in Thymeleaf: It works inversely to the hierarchical approach. Instead of creating base pages for layout and then defining their content in children pages, you directly create the "leaf node" pages, the ones that will really render when executed, and allow them to specify which UI fragments to include from layout-specific templates: headers, footers, menus... whatever. That's why I like to call it "pull-style": templates pull their required fragments and render them, instead of the rendering operation having to go down through a hierarchy of incomplete templates.

        What is the advantage of this approach? Mainly, the ability to create "natural templates", this is, to make your Thymeleaf HTML templates work as perfectly usable static prototypes in which you can easily write and/or test the design you want your pages to display.

        (also, from my point of view, this approach makes developing the UI much simpler, but I assume that's a matter of personal taste).

        This second approach can be enriched by javascript tools like Thymol[ http://sourceforge.net/u/jjbenson/wiki/thymol/ ] which allows you to test your layouts in a static manner by grabbing your included fragments via javascript. Thymol is still quite "work-in-progress" yet but keep an eye on it because once it evolves to include a couple of new features it will really rock.



        As for performance -- Comparing FreeMarker or Velocity to Thymeleaf only in terms of performance is in fact quite unfair, as they are completely different approaches to template engines. By construction, FreeMarker is a fast generic text template processor that can be used for the web as well as any other text-related usages. Its focus is speed, and it does that extremely well. On the other side, Thymeleaf is a mostly-web-oriented template engine that really understands the languages of the web (HTML5, XHTML, javascript, even Dart) and offers --or tries to offer-- a much more pleasant design, development and maintenance experience in the field of web user interfaces.

        We do not currently have formal well-designed speed benchmarks comparing FreeMarker and Thymeleaf. This could be an initial approach http://forum.thymeleaf.org/Performan...td3722763.html that might give you an idea, but the results will depend largely on the type of pages being displayed, so designing a 100% fair benchmark between these two technologies will be quite difficult and would require its designer to be a real expert in both technologies.

        Anyway it's clear to me that, if the differences in performance between FreeMarker and Thymeleaf are really that important to you and truly make such a difference in how your application behaves, you should not use Thymeleaf at all. Because of the different focuses of both technologies, it would be really strange that Thymeleaf gets the performance figures of FreeMarker anywhere in the future. In the same way that it would be really strange that FreeMarker offers the same kind of developing or design experience as Thymeleaf.

        Nevertheless, for most applications --probably not your case--, web UI rendering is not really a performance bottleneck, and their common performance issues are: 1. Database times. 2. Other kinds of I/O. 3. Latency due to Garbage Collection, all of which will probably consume execution time in higher orders of magnitude than UI rendering. What's more: in cases where UI rendering is such an issue it could even happen that Java is not the right platform to run on, in the first place.

        As a real-world example, I can tell you thymeleaf 2.0 is currently being used in production on a very popular public website serving an average of 385reqs/second in a cluster setup with no issues. But again, this depends on the specific needs of each scenario (here keeping GC-related latency low was far more important than UI rendering times, for example).

        Lastly -- if you tried the latest version in March 2012, that must be a 2.0.x, and Thymeleaf has not evolved since then in terms of performance --it was only one month ago! :-). The real performance improvements were made in Thymeleaf 2.0, published Feb 2012 [ http://www.thymeleaf.org/whatsnew20.html ]


        Well, it's been long -- sorry for that :-) -- but I hope to have answered your concerns.


        Regards,
        Daniel.

        Comment


        • #5
          Hi Daniel

          Thanks for your reply, although I have read your comments previously as well no there is nothing new in your position around the points I am concerned about.

          I do find your position a bit strange on two points. You mention that where UI rendering could be an issue, Java may not be the right platform any way. What alternatives did you have in mind? I am hoping you were not going to suggest CGI or C/C++ based solutions. I have worked with Java and non-Java technologies alike for a very long period of time and haven't found anything that is better than Java in terms of rendering time and productivity for a wide variety of use cases.

          The second point that struck me as being odd is your mentioning the relative performance of rendering operations v/s other operations. I do take your point about the bottleneck caused by out-of-process operations like database access, etc. I would like to draw your attention to the fact that data fetch times are becoming insignificant for an increasing number of applications. For instance, 60-70% of our use cases get data from a NoSQL or NewSQL data store. These operations are extremely fast, many owing to the fact that the requested data is in the same memory space as the web application. The data being cached on our app servers in-memory prevents I/O, etc. from being a concern. Anything that involves I/O in our applications is done asynchronously and is never on the critical path for rendering a response to the users. We are therefore constrained by rendering time taken to process large data sets. From the numbers I have seen, the factor of performance makes a lot of difference.

          I hope you will consider these things when looking at the next version of ThymeLeaf. Nevertheless, I like the framework and would be very happy to use it one of these days, the two concerns I mentioned not withstanding.
          Last edited by manish.in.java; May 18th, 2012, 12:16 AM.

          Comment


          • #6
            Hi Daniel

            Does Thymeleaf work with spring's ContentNegotiatingViewResolver? I want to use thymeleaf for my .html/.action views. If so, how would that look? Below is what I have for internalview.

            Thanks,
            Giang

            Code:
             <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:favorPathExtension="true" p:favorParameter="true" p:ignoreAcceptHeader="true"
            		p:defaultContentType="text/html">
            		<description>Depending on extension, return html with no decoration (.html), json (.json) or xml (.xml), remaining pages are decoracted</description>
            		<property name="mediaTypes">
            			<map>
            				<entry key="xml" value="application/xml" />
            				<entry key="json" value="application/json" />
            				<entry key="html" value="text/html" />
            				<entry key="action" value="text/html" />
            			</map>
            		</property>
            		<property name="defaultViews">
            			<list>
            				<bean class="org.springframework.web.servlet.view.xml.MarshallingView" p:marshaller-ref="xstreamMarshaller" />
            				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            			</list>
            		</property>
            		<property name="viewResolvers">
            			<list>
            				<bean id="nameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
            					<description>Maps a logical view name to a View instance configured as a Spring bean</description>
            				</bean>
            				<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
            			</list>
            		</property>
            	</bean>

            Comment


            • #7
              Hi gthiet,

              Actually, the PetClinic example application contains such example of ContentNegotiatingViewResolver. It allows it to return the list of vets either in XML or in HTML form depending on whether the ".xml" is being used or not. It just looks as any other view resolver, with a lower "order" value than Thymeleaf's (this is, higher priority).

              You can download the sample app from http://www.thymeleaf.org/documentation.html

              Regards,
              Daniel.

              Comment


              • #8
                Thanks Daniel.

                A follow up question, does thymeleaf work with recaptcha? I plan on using http://code.google.com/p/recaptcha4j/ with spring.

                Comment


                • #9
                  Hi,

                  From what I can see, recaptcha4j uses JSP code acting directly against the response output writer, like (from their website):

                  Code:
                          ...
                  <%
                          // create recaptcha without <noscript> tags
                          ReCaptcha captcha = ReCaptchaFactory.newReCaptcha("my-public-key", "my-private-key", false);
                          String captchaScript = captcha.createRecaptchaHtml(request.getParameter("error"), null);
                          
                          out.print(captchaScript);
                  %>
                          ...
                  So probably the easiest way to integrate this into a thymeleaf app would be a th:include going against an URL-resolved template. And that URL-resolved template --using Thymeleaf's URLTemplateResolver-- would go against a URL in your server that executes that JSP, and then Thymeleaf will simply include the resulting HTML fragment into your thymeleaf template (you can use a DOM selector to fine-tune that inclusion, in fact).

                  Another possibility would be to create a custom processor (an implementation of IProcessor) that simply executes this in Java and adds whatever it results from this into your DOM during template processing.

                  Regards,
                  Daniel.

                  Comment


                  • #10
                    New Thymeleaf + Tiles 2 integration package

                    Hi again,

                    I just wanted to mention Thymeleaf has now an Apache Tiles 2 integration package:

                    https://github.com/thymeleaf/thymeleaf-extras-tiles2

                    Regards,
                    Daniel

                    Comment


                    • #11
                      The method for delete a pet is not working.
                      How to make it work using RequestMethod.DELETE?

                      I have already tried to use
                      HTML Code:
                      <input type="hidden" value="delete" name="_method" />
                      but it didn't work.

                      Any ideas?

                      Thanks.

                      Comment


                      • #12
                        Originally posted by dblank View Post
                        The method for delete a pet is not working.
                        How to make it work using RequestMethod.DELETE?

                        I have already tried to use
                        HTML Code:
                        <input type="hidden" value="delete" name="_method" />
                        but it didn't work.

                        Any ideas?

                        Thanks.
                        There was a bug in the html form: a missing th:method attribute:
                        <form th:method="'delete'" th:if="${!pet.new}" th:action="@{#}" action="#">

                        I've just solved it:
                        https://github.com/thymeleaf/thymele...42ca4d66024814

                        Regards,
                        sorayasl

                        Comment


                        • #13
                          Thanks Daniel.

                          Comment


                          • #14
                            Originally posted by sorayasl View Post
                            There was a bug in the html form: a missing th:method attribute:
                            <form th:method="'delete'" th:if="${!pet.new}" th:action="@{#}" action="#">

                            I've just solved it:
                            https://github.com/thymeleaf/thymele...42ca4d66024814

                            Regards,
                            sorayasl
                            It worked!!!

                            Thanks =)

                            Comment

                            Working...
                            X