Oh... I didn't even see that one. Thanks for the heads up, I'll look at it.
On 15-07-16 08:13 AM, Brett Ryan wrote: > >> On 16 Jul 2015, at 22:00, Nicolas Le Bas <[email protected]> wrote: >> >> I see. >> So basically you like to use tiles as some kind of Domain Specific >> Langage for your views. >> >> What if we add support for something like raw data for an attribute, >> that would be translated into a Map for rendering? >> >> Something like: >> <definition name="customers/info" extends="customers/base"> >> <put-list-attribute name="body" cascade="true" inherit="true"> >> <add-attribute value="/WEB-INF/views/customers/cust-info.jsp" /> >> </put-list-attribute> >> <put-xml-attribute name="breadcrumbs" cascade="true" inherit="true"> >> <breadcrumbs> >> <link href="/customers/${customer.id}">${customer.id}</link> >> <link href="/customers/${customer.id}/salesOrders">Orders</link> >> <link >> href="/customers/${customer.id}/salesOrders/${order.id}">${order.id}</link> >> </breadcrumbs> >> </put-xml-attribute> >> </definition> >> >> I think most of the pieces to support it are already there: >> - we already have support for evaluating the expressions at runtime. >> - we can find libraries out there that translate XML into a usable map >> structure (xstream?) >> >> The only thing that worries me is whether the good old digester would >> accept to release control of the parsing and let us access the whole >> body of put-xml-attribute, or if we would have to rewrite >> DigesterDefinitionsReader. I'm not sure there. >> >> How does that sound? What do you think? > > It's certainly a flexible approach that could prove useful, I am ok with the > add-list-attribute mck suggested which works as advertised, I made pull > request #5 (https://github.com/apache/tiles/pull/5) which adds expression > support to list attributes, mck made some requests before accepting but the > logic I think is sound. > > Btw, the example I submitted works in the current release of tiles withe the > exception of expression evaluation which #5 addresses. > > All in all we can probably close this pull request and concentrate instead on > #5. > >> Nick. >> >>> On 15-07-14 10:18 PM, Brett Ryan wrote: >>> >>>> On 15 Jul 2015, at 11:53, Nicolas Le Bas <[email protected]> wrote: >>>> >>>> Hi all, >>>> >>>> First of all, I take responsibility for cross posting to the dev list. >>>> Sorry if it surprised you, Brett, I just feel it is a better place to >>>> discuss code changes. People come here with a different mindset. >>> >>> My bad actually, I should have realised there was a dev@ list, I subscribed >>> to users@ years ago and didn't bother to check when submitting patches. >>> >>>> And sorry for the delay in my answer, too. We're all volunteers here :) >>>> As a consequence, it will be a long answer, and I feel like apologizing >>>> again. >>> >>> Hah, it's cool :) I've been unwell and unable to finalise a solution to >>> mck's requests, I was hoping to resume on the weekend but have been >>> bed-ridden and can't think properly. It happens, what ya gonna do? >>> >>>> Concerning a universal solution to Brett's problem: well, here's what >>>> I've been doing for the past years. I do not pretend it is better, just >>>> that I like it: >>>> >>>> >>>> I find, like Brett, that the "JavaBeans" tags from struts-tiles (item >>>> and bean) are limited in nature. In my experience I only encountered two >>>> situtations were they were useful, and in both situations I've found >>>> other solutions to be more effective and maintainable. >>>> >>>> >>>> 1. The static approach >>>> I like the pure HTML+CSS solution to this: <ul><li>My Account</li><li>My >>>> Orders</li></ul>. It looks and lives well within the template itself. >>>> >>>> 2. The dynamic list. >>>> In most cases, I find it more convenient to add a bean into the >>>> appropriate context through the application. For instance, with spring: >>>> >>>> <util:list id="breadcrumbsData"> >>>> <bean class="example.Link" p:value="#{customer.id}" >>>> p:link="/customers/#{customer.id}" /> >>>> <bean class="example.Link" p:value="Orders" >>>> p:link="/customers/#{customer.id}/salesOrders" /> >>>> <bean class="example.Link" p:value="#{order.id}" >>>> p:link="/customers/#{customer.id}/salesOrders/#{order.id}" /> >>>> </util:list> >>>> >>>> And then in tiles: >>>> <put-attribute name="breadcrumbs" expression="${breadcrumbsData}"/> >>>> >>>> I find this "breadcrumbsData" tends to evolve over the life of the >>>> application into something more and more dynamic, for instance session >>>> specific or requires a data model more complex than the <item>-type of >>>> thing. Sometimes it is also more convenient to create the list by hand >>>> and add it to the session/servlet context programatically. >>> >>> I'm trying to remove things like this as much as possible from the >>> application context and defer to tiles as it's a lot less work. Consider >>> this in my template: >>> >>> <tiles:importAttribute name="breadcrumbs" ignore="true"/> >>> <ol class="breadcrumb"> >>> <c:forEach var="item" items="${breadcrumbs}" varStatus="vs"> >>> <li class="${vs.last ? 'active' : ''}"> >>> <c:choose> >>> <c:when test="${vs.last}"> >>> <c:out value="${item[0]}"/> >>> </c:when> >>> <c:otherwise> >>> <a href="<c:url value="${item[1]}"/>"><c:out >>> value="${item[0]}"/></a> >>> </c:otherwise> >>> </c:choose> >>> </li> >>> </c:forEach> >>> </ol> >>> >>> Now with this I can opt-in to providing crumbs in many different views, >>> which can be completely dynamic and inheritable by tiles. Consider the >>> customers crumbs I've been using, note that this has been changed from >>> using the "<item/>" version to using nested <add-attribute/> values, though >>> I've raised a new pull-request that I need to alter which provides >>> expression support as it's not presently available. >>> >>> <definition name="customers/base" extends="customers/none"> >>> <put-attribute name="title" cascade="true" >>> expression="${customer.sortName} (${customer.id})" /> >>> <put-list-attribute name="body" cascade="true"> >>> <add-attribute value="/WEB-INF/views/customers/menu-tabs.jsp"/> >>> </put-list-attribute> >>> <put-list-attribute name="breadcrumbs" cascade="true" inherit="true"> >>> <add-list-attribute> >>> <add-attribute value="Customers"/> >>> <add-attribute value="/customers"/> >>> </add-list-attribute> >>> </put-list-attribute> >>> </definition> >>> >>> <definition name="customers/info" extends="customers/base"> >>> <put-list-attribute name="body" cascade="true" inherit="true"> >>> <add-attribute value="/WEB-INF/views/customers/cust-info.jsp" /> >>> </put-list-attribute> >>> <put-list-attribute name="breadcrumbs" cascade="true" inherit="true"> >>> <add-list-attribute> >>> <add-attribute expression="${customer.id}"/> >>> <add-attribute >>> expression="/customers/${customer.country}/${customer.id}/info"/> >>> </add-list-attribute> >>> </put-list-attribute> >>> </definition> >>> >>> <definition name="orders/view" extends="customers/base"> >>> <put-list-attribute name="body" cascade="true" inherit="true"> >>> <add-attribute value="/WEB-INF/views/customers/cust-salesOrder.jsp" /> >>> </put-list-attribute> >>> <put-list-attribute name="breadcrumbs" cascade="true" inherit="true"> >>> <add-list-attribute> >>> <add-attribute expression="${customer.id}"/> >>> <add-attribute expression="/customers/${customer.id}/info"/> >>> </add-list-attribute> >>> <add-list-attribute> >>> <add-attribute value="Orders"/> >>> <add-attribute >>> expression="/customers/${customer.country}/${customer.id}/salesOrders"/> >>> </add-list-attribute> >>> <add-list-attribute> >>> <add-attribute expression="${salesOrder.id}"/> >>> <add-attribute >>> expression="/customers/${customer.country}/${customer.id}/salesOrders/${salesOrder.id}"/> >>> </add-list-attribute> >>> </put-list-attribute> >>> </definition> >>> >>> Note here how now my spring controllers need to know nothing about the >>> breadcrumbs. In fact the only thing that knows about them is the view and >>> the view composition, which I believe is the whole point of a framework >>> like tiles, being able to decouple your composition from your controllers, >>> which is what I love about tiles. >>> >>> >>> >>>> I used the tiles-centric solution back at the time when CSS and DI were >>>> barely budding, and their long-term adoption was still questionable, but >>>> now I prefer other ways. That being said, I'm totally open to >>>> contributions that would be useful to others. >>>> >>>> >>>> >>>> >>>> Concerning the documentation: I totally agree it needs work, there's a >>>> ramp up to learning Tiles 3. Initialization is cumbersome, and as we >>>> discussed earlier, the duality between "value" and "expression" is >>>> confusing. All of this is documented on the website, but the docs are >>>> dry and learning is difficult. Perhaps we could rework the tutorials and >>>> update the examples. Another dark area is: how to test? >>> >>> Would love to help, I've been using tiles for some years and myself only >>> stumble onto 3 specific features when I find them, so I don't "know it >>> all", but I'd be more than happy to help contribute to docs. >>> >>>> That being said, my time being limited, I prefer to invest it in >>>> simplifying the usage of tiles before documenting the simple solution, >>>> as opposed to trying to explain the complex solution in a clear way. >>> >>> I would tend to agree, and considering it's been that way for a while, >>> maybe that's the right approach. Though, how long would the simplified >>> solution take to implement? >>> >>>> So personnally I'm looking at reviewing the docs when tiles can be >>>> configured from DI, and run in junit (tiles 3.1, perhaps. My github fork >>>> already has the junit part working, and I'm experimenting with DI). >>>> >>>> Cheers! >>>> >>>> Nick >>>> >>>> PS: On 15-07-08 09:21 AM, Brett Ryan wrote: >>>>> toString should always be a string representation of a value, not >>>> null, alternatives would be "null" or "(null)". >>>> >>>> +1, definitely >>>
