jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] Re: [971-Multi-Templating] Terms and Scope

From: Leonardo Uribe <lu4242_at_gmail.com>
Date: Thu, 16 Aug 2012 21:36:47 -0500

Hi

2012/8/16 Edward Burns <edward.burns_at_oracle.com>:
>>>>>> On Sun, 5 Aug 2012 17:21:41 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:
>
> EB> Question: Does it make sense to continue to separate the concepts of
> EB> skinning and multi-templating, or should we just go ahead and declare
> EB> right now that multi-templating is a super-set of skinning and stop
> EB> talking about skinning altogether, just framing the discussion in terms
> EB> of multi-templating?
>
> LU> I agree with you about multi-templating is a super-set of skinning,
> LU> but I think this issue is all about how to map resources.
>
> Ok, I appreciate the luxury of waging the war on a single front.
>
> LU> To define any skin, what you provide is a set of resources (css,
> LU> images, ...) that can be used for an specific renderkit. To define
> LU> multi-templating, you also provide another set of resources (xhtml,
> LU> css, ...). In both, it is necessary to define some "extension points".
> LU> For example, a skin requires define some selectors on the renderkit
> LU> side. A multi-template requires to define an specific page layout
> LU> (header, footer, navigation menu, ....) and so on.
>
> KM> I think it's helpful to think about how this relates to skins/themes used
> KM> by component libraries. We're not worrying about the actual CSS selectors,
> KM> right? Just how to package up a set of resources and dynamically switch
> KM> between them, correct?
>
> Right, and taken together, all of these definitions comprise a contract.
> Multi-template vendors define a contract and produce implementations of
> that contract. App developers code their apps on the assumption that
> they'll have an implementation of that contract on hand when they need
> it.
>
> As with composite components, I want the contract for a multi-template
> to be infused with convention-over-configuration, and be easy for humans
> and tools to understand.
>
> I see some stories right away.
>
> * STORY_defineMultiTemplate Multi-template author defines multi-template
> and its usage contract.
>
> * STORY_declareMultiTemplateUsage App developer declares parts of their
> app to use one-or more multi-templates.
>
> * STORY_discoverDeclaredMultiTemplateUsage Runtime discovers which
> multi-templates are used by the page being rendered.
>
> * STORY_useDiscoveredMultiTemplates Runtime finds implementations of
> those templates and uses them in the rendering of the page.
>
> IO> +1 to "skip" skinning and make it part of "Multi-Templating" I am
> IO> not really happy with that term (Template already being ambiguous in
> IO> JSF), maybe we can find something better? Resource-Modules? Theming?
> IO> .
>
> FC> for me it is OK to use the term multi-templating, even if we go
> FC> beyond the current proposal, because:
>
> FC> - we actually need one term (I'm not the only one mixing skinning
> FC> and multi-templating)
>
> FC> - the world seems to be waiting for something under that term.
>
> RESOLVED: We will talk of the feature as multi-templating with the
> understanding that the feature is a super-set of skinning as
> conventionally understood today.
>
> LU> In few words, the big question is how to setup or map those resources.
>
> [...]
>
> LU> The change done is quite simple, just consider that after
> LU> ResourceHandler.createResource(resourceName, libraryName) is called,
>
> [... Leonardo cites a simple change to MyFaces...]
>
> LU> update the spec renderkit javadoc. Anyway, multi-templating/skinning
> LU> requires something else than this hack.
>
> LU> The url provided by a Resource instance to be included in a view or
> LU> page is affected by:
>
> LU> 1. The current locale of the view.
> LU> 2. The multi-templating/skinning configuration of the view.
>
> LU> In other words, a requeriment for any multi-templating/skinning
> LU> solution is that the generated Resource instances should contains all
> LU> necessary information to derive both the locale an the
> LU> multi-templating/skinning configuration, at least for derive the
> LU> Resource instance.
>
> Yes, this is a key requirement.
>
> REQUIREMENT_MultiTemplateLocale Multi-Templates are entirely Locale
> aware and the Locale must be discovered for each request using the
> existing JSF Locale system.
>
> LU> Multi-templating/skinning group resources together in a different way
> LU> than some resources are grouped into a library, because you can expect
> LU> a skin "extends" from other one, but that's not possible for a library
> LU> (not sure about it, it is a controversial topic).
>
> I don't know what you mean by "extend". I think multi-templates should
> be a flat system, but it's possible for any given view to declare that
> it wants to use several multi-template instances.
>

Let's take a look at a simplified example. Suppose for implement multi-templates
we'll group resources into a library, and to change between implementations of
a "multi-template contract", we just change the libraryName.

There is a library (or a theme) called A that define some default images
(for example a simple logo). The user wants to use that library, but change
only some images. In a flat system, the user needs create another library A'
and copy all resources of the previous library and then change the
required images.

An alternative to make a hard copy is allow to define a relationship
between different
libraries. Suppose we can describe somewhere (a property file called
/resources/my.custom.library/META-INF/library.properties inside the library
or in a faces-config.xml file or whatever), that our new library A' is an
"extension" of the previous library A. In that way, it is
possible to prevent the hard-copy, because if a resource is not found in A',
the relationship of extension indicates that the resource should be in A.

If we define a file inside a library to define that relationship, we
can do other
things like define declared versions of a library, specify versions
for multi-templates
and fix the problem with libraryVersion inside a jar file (scan a jar
file to derive the
latest libraryVersion is bad for performance).

Note the file is defined as optional, so by default this will work as
a flat system,
using the idea of "convention over configuration", at least in this part.

> REQUIREMENT_MultiTemplateFlat there is no provision for multi-templates
> to extend from one-another. If an app developer requires multiple
> templates for a view, they may declare that multiple multi-templates
> may be used.
>
> FC> I think you basically have the same question as me: Why limit this
> FC> functionality to templates only? You want to be able replace any
> FC> resource, right?
>
> LU> Yes. As I said before, this topic is all about how to map resources.
>
> FC> I think tying it to the library name is a good idea. Maybe we can
> FC> have something like
> FC> ResourceHandler.getDefaultLibraryName(FacesContext), which is simply
> FC> a prefix for all resources requested in the given FacesContext. E.g:
>
> FC> ResourceHandler.getDefaultLibraryName(FacesContext) returns "mobile"
> FC> ResourceHandler.createResource("main.css", "css") becomes
> FC> ResourceHandler.createResource("main.css", "mobile/css") If
> FC> ResourceHandler.createResource("main.css", "mobile/css") returns
> FC> null, use ResourceHandler.createResource("main.css", "css")
>
> LU> It is an option, but it has its advantages:
>
> LU> - It is only required to extend the concept of libraryName.
> LU> - No need to update request url spec.
>
> LU> and disadvantages.
>
> LU> - If skinning/templating is built on top of libraryName, no changes in
> LU> request url are required, but all limitations of libraryName applies,
> LU> like do not allow '/' in libraryName, so the example proposed
> LU> replacing libraryName with "mobile/css" is invalid according to
> LU> current spec. See: https://issues.apache.org/jira/browse/MYFACES-3454
> LU> for details.
>
> LU> I just wanted to notice that the option is on the table and that any
> LU> other strategy has its trade-offs too.
>
> LU> I think any solution should be built to allow:
>
> LU> - Extensibility (theme A extends theme B).
>
> As stated above, I don't like that idea. I prefer a mixin approach. I
> think Leonardo calls this out as composition.
>

In other words, allow to create a theme A from another one A', defining
a relationship between A' and A, allowing override or add resources.

> LU> - Packaging (a set of resources together into a single unit)
>
> REQUIREMENT_MultiTemplate_JarOrExplodedPackaging
>
> It must be possible to package a multi-template as a jar file, or as an
> exploded directory. In both cases, the system must be able to
> automatically discover all information necessary to use the
> multi-template lazily, once per application initialization, without any
> additional configuration being provided to the application. In other
> words, "drop in and go". This will make it possible to offer
> multi-templates as re-usable components in a software repository, such
> as a maven repository.
>
> LU> - Composition (allow multiple units to be dealt as a single
> LU> "logical" unit).
>
> What's the difference between this and Extensibility?
>

Suppose two different libraries A and B, one used for "skinning" and
the other one
for "layout". Composition allows to group A and B and create AB. If a
resource has
as libraryName AB, it means the resource could be in library A or in
library B, so
it is necessary to scan first in A and then in B.

For example if we call some js file we should do it like this:

<h:outputScript library="AB" name="myres.js"/>

The ResourceHandler is responsible to check how to resolve AB and then
look first in A and then in B.

I know both Extensibility and Composition are similar concepts, but note you can
think of a solution for Extensibility without consider Composition.

> FC> From my point of view there is no need for configuration. If the
> FC> developer want's it, she should simply create a
> FC> ResourceHandlerWrapper and implement getDefaultLibraryName according
> FC> to her needs.
>
> LU> I don't know. I think it is worth to deal with the configuration
> LU> problem from spec side. Otherwise, each vendor will reinvent the wheel
> LU> over and over in this part.
>
> LU> (the following part are just some ideas I have, sorry if the language
> LU> is poor or difficult to understand)
>
> LU> I have been thinking on something like faces navigation but for
> LU> resources. For an specific view it is defined an "outcome" or
> LU> "skin-name" or whatever and there is some kind of algorithm that
> LU> defines the order of libraryNames that should be scanned for the
> LU> specific resource, just like it is done for a localized resource
> LU> (first look for a resource with some specific locale and if it does
> LU> exists try to locate it without locale).
>
> LU> Now, suppose you have two different sets of libraries: one for
> LU> "skinning" resources one for "layout" resources. The configuration
> LU> should be able to say: "if the skin-name is "x" and the libraryName to
> LU> resolve is "skinning", the new skin-name is "p" ". If you have the
> LU> skins [a, b, c] and layout [x, y] the possible combinations for
> LU> skin-name should be [a-x, a-y, b-x, b-y, c-x, c-y]. If it is necessary
> LU> to define where is the file for the resource with libraryName "layout"
> LU> and resourceName "template1.xhtml" for the skin-name "b-x", both the
> LU> skin-name of the current view and the libraryName are passed to some
> LU> method, and it founds the rule that says for "b-x" if libraryName
> LU> "layout" is passed the new skin-name is "x". At the end, the
> LU> libraryName to use for "layout" is "x".
>
> LU> So, we are "splitting" the problem in two (divide and conquer):
>
> LU> - How to resolve a libraryName from a skin-name using some rules,
> LU> abstracting "application scope" concepts like skinning, layout and
> LU> others.
> LU> - How to resolve a libraryName from another libraryName and find an
> LU> specific resource, to solve Extensibility, Packaging and Composition.
>
> Leonardo, would you agree that the preciding paragraph is really a way
> to implement STORY_declareMultiTemplateUsage and
> STORY_discoverDeclaredMultiTemplateUsage?
>

I agree, it is another way to look at it.

> LU> Will it work? Maybe. It reuse existing concepts found in jsf and it is
> LU> simple to do.
>
> I like the idea of re-using existing concepts as much as possible,
> certainly, but it took me a little while to understand that you were
> just proposing a way to implement those two stories. I think we want to
> make it more simple then you propose.
>

Ok. I'm trying my best to provide different alternatives to the problem ;-).

> LU> Anyway, I don't know what are you guys thinking about this problem.
> LU> I'm just trying to provide all information available about the topic,
> LU> and specify some "criteria" to evaluate any proposed solution.
>
> FC> I think you basically have the same question as me: Why limit this
> FC> functionality to templates only? You want to be able replace any
> FC> resource, right?
>
> IO> +1 (I'd even love to see this for composite components - we probably
> IO> have to "work" on the caching then, but still)
>
> IO> I always like as basis an approach which can be coded, as is with
> IO> ResourceHandler.getDefaultLibraryName(FacesContext), but maybe we
> IO> should have: List<String>/String[]
> IO> ResourceHandler.getDefaultLibraryNames(FacesContext ctx or whatever
> IO> we need to map the libraries), which should then be checked one by
> IO> one, so in your example that could be:
>
> IO> ["mobile_dark","mobile"] so with resource css/main.css we get the following search order mobile_dark/css/main.css > mobile/css/main.css > css/main.css
> IO> This way we get "theme extension".
>
> IO> Concerning: (From Ed Burns logged work at 22/May
> IO> http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-971)
>
> EB> A multi-template is specified as a resource
> EB> library that includes the file template.xhtml in its top level. Every
> EB> Facelet VDL view in the application will be a template-client of this
> EB> template. PENDING: there must be some way for an application to express
> EB> which views should have the multi-template applied. Perhaps some kind of
> EB> pattern matching system?
>
> IO> Why automatically make template.xhtml the "template-host" of every
> IO> VDL-view, why not use what we already have: <ui:composition
> IO> templat"/{theme}/shoppingtemplate.xhtml">
>
> IO> Doing so (with the ResourceHandler.getDefaultLibraryNames from above)
>
> IO> a) We don't need pattern matching or other configuration options
>
> IO> b) One can pick different base templates of the
> IO> Theme/Multi-Templating for different "sections" of the site.
>
> IO> c) We are - as far as I can see - done, if we change the
> IO> ResourceHandling appropriately and use that for template discovery.
>
> I'm very interested in any solution that gets us efficiently to "done".
> Imre, can you think about it some more and we can talk on the telephone
> so you can explain it to me?
>
> IO> As the requested Facelet VDL needs to be written as a
> IO> template-client anyway, I don't see a drawback in having to use
> IO> <ui:composition> explicitly.
>
> No, certainly not.
>
> Ed
>

Leonardo

> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
> | homepage: | http://ridingthecrest.com/