Round-about mechanism wanted for common issue

View: New views
7 Messages — Rating Filter:   Alert me  

Round-about mechanism wanted for common issue

by Adam Hardy-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I'm using Tiles to split up my JSPs so that I have a layout.jsp which contains
the HTML headers, meta-tags, style sheet links etc. There are other tiles, one
for menus, one for footer.

The tiles.xml contains the definitions where I re-use these tiles and specify
the content tile which contains the HTML forms or search results etc etc.

I find now that my cascading stylesheet is getting large, and much of the style
which it includes are only used on one page each, so I would like to put those
CSS declarations into the pages that require them directly. Mostly it is just
height or width attributes and occasionally some margins, borders or paddings.

I could include an individual <style> tag directly in the content tile JSP

<style type="text/css">
<!--
#mainContext div.row span.data {
     width: 23%;
}
-->
</style>

But because it's not in the header, the HTML doesn't validate (at W3C):

 >>Line 100, Column 22: document type does not allow element "style" here.


The alternative would be to keep it in a seperate CSS file and include it in the
valid position for styles using the layout.jsp (as for the main CSS file).

However, it would be ideal if I could put the CSS in the content tile, but wrap
it in a Tiles tag of some kind (e.g. <tiles:includeInOtherFile var="specialCss">
) that would pipe the body out of that tile and into the layout tile:

<tiles:includeFromMemory var="specialCss">

Is that already possible? Or if not, does it sound feasible, or is my layout
tile already written to out before the content tile is processed?

Thanks in advance,
Adam


Re: Round-about mechanism wanted for common issue

by Antonio Petrelli-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/5/6 Adam Hardy <ahardy.struts@...>:
>  The alternative would be to keep it in a seperate CSS file and include it
> in the valid position for styles using the layout.jsp (as for the main CSS
> file).

With Tiles 2.0 it is the only way, probably...

>  However, it would be ideal if I could put the CSS in the content tile, but
> wrap it in a Tiles tag of some kind (e.g. <tiles:includeInOtherFile
> var="specialCss"> ) that would pipe the body out of that tile and into the
> layout tile:
>
>  <tiles:includeFromMemory var="specialCss">
>
>  Is that already possible? Or if not, does it sound feasible, or is my
> layout tile already written to out before the content tile is processed?

I think it is not possible this way, since, when the "body" is
processed" the "header" has already been processed and it can't come
back.

However, in Tiles 2.1 (that you can find in svn trunk) you could use
the "cascaded" attributes.
For example, if you have a different CSS segment per page, you can do:

<definition name="myDefinition" template="/layout.jsp">
  <put-attribute name="specialCss" value="${requestScope.specialCss}"
cascade="true" />
<!-- Here goes the rest of the definition -->
</definition>

Notice the use of EL in the attribute value, see the test webapp
(tiles-test) for an example. Currently there is no docs about this
(sorry, it's under development).

HTH
Antonio

Re: Round-about mechanism wanted for common issue

by Adam Hardy-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Antonio Petrelli on 06/05/08 14:44, wrote:

> 2008/5/6 Adam Hardy <ahardy.struts@...>:
>>  The alternative would be to keep it in a seperate CSS file and include it
>> in the valid position for styles using the layout.jsp (as for the main CSS
>> file).
>
> With Tiles 2.0 it is the only way, probably...
>
>>  However, it would be ideal if I could put the CSS in the content tile, but
>> wrap it in a Tiles tag of some kind (e.g. <tiles:includeInOtherFile
>> var="specialCss"> ) that would pipe the body out of that tile and into the
>> layout tile:
>>
>>  <tiles:includeFromMemory var="specialCss">
>>
>>  Is that already possible? Or if not, does it sound feasible, or is my
>> layout tile already written to out before the content tile is processed?
>
> I think it is not possible this way, since, when the "body" is
> processed" the "header" has already been processed and it can't come
> back.
>
> However, in Tiles 2.1 (that you can find in svn trunk) you could use
> the "cascaded" attributes.
> For example, if you have a different CSS segment per page, you can do:
>
> <definition name="myDefinition" template="/layout.jsp">
>   <put-attribute name="specialCss" value="${requestScope.specialCss}"
> cascade="true" />
> <!-- Here goes the rest of the definition -->
> </definition>

So if I made a taglib that stored the CSS in its body into the request
attribute, e.g. requestScope.specialCss, a bit like this:

<adam:style var="specialCss">
#ContextBody div.repo span { width: 25px; }
</adam:style>

then I could achieve this? Or do you mean that it's not possible?

I don't know what order the various tiles parts are executed.

My layout.jsp definition is inherited by every JSP like so:

   <definition name="layout.tile" template="/WEB-INF/jsp/layout.jsp">
     <put-attribute name="focalPointTile" type="template"
       value="/WEB-INF/jsp/focalpoint.jsp" />
     <put-attribute name="smallPrintTile" type="template"
       value="/WEB-INF/jsp/smallprint.jsp" />
     <put-attribute name="contextHeaderTile" type="template"
       value="/WEB-INF/jsp/contextheader.jsp" />
     <put-attribute name="menuTile" type="template"
       value="/WEB-INF/jsp/menu.jsp" />
     <put-attribute name="subMenuTile" type="template"
       value="/WEB-INF/jsp/submenu.jsp" />
     <put-attribute name="tilesBrowserTitle" type="string"
       value="general.browserTitle" />
   </definition>
   <definition name="categoryList.tile" extends="layout.tile">
     <put-attribute name="bodyContentTile"
       value="/WEB-INF/jsp/category/list.jsp" />
     <put-attribute name="tilesContextHeader" type="string"
       value="category.list.pageHeader" />
     <put-attribute name="subMenuTile"
       value="/WEB-INF/jsp/category/submenu.jsp" />
   </definition>


Re: Round-about mechanism wanted for common issue

by Antonio Petrelli-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/5/6 Adam Hardy <ahardy.struts@...>:
>  So if I made a taglib that stored the CSS in its body into the request
> attribute, e.g. requestScope.specialCss, a bit like this:
>
>  <adam:style var="specialCss">
>  #ContextBody div.repo span { width: 25px; }
>  </adam:style>
>
>  then I could achieve this? Or do you mean that it's not possible?

It's not possible to put it in the body and hope that it will be
processed in the header, simply because the header gets renderer
before the body, and when you render the body it's too late to process
the header.
I think that your option is to do some pre-rendering processing, for
example using a ViewPreparer, to store the extra CSS items, and then
use them when rendering the <head>.

Antonio

Re: Round-about mechanism wanted for common issue

by Adam Hardy-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Antonio Petrelli on 06/05/08 18:02, wrote:

> 2008/5/6 Adam Hardy <ahardy.struts@...>:
>>  So if I made a taglib that stored the CSS in its body into the request
>> attribute, e.g. requestScope.specialCss, a bit like this:
>>
>>  <adam:style var="specialCss">
>>  #ContextBody div.repo span { width: 25px; }
>>  </adam:style>
>>
>>  then I could achieve this? Or do you mean that it's not possible?
>
> It's not possible to put it in the body and hope that it will be
> processed in the header, simply because the header gets renderer
> before the body, and when you render the body it's too late to process
> the header.
> I think that your option is to do some pre-rendering processing, for
> example using a ViewPreparer, to store the extra CSS items, and then
> use them when rendering the <head>.

OK. Perhaps I could write a ViewPreparer that greps the JSP and extracts the CSS
declared there.

I could write a simple taglib for the JSP to surround the CSS which would
identify the portion to extract and also prevent it displaying when the JSP loads.

This depends on the ViewPreparer getting the name of the JSP file. Presumably
that's in the AttributeContext.


Regards
Adam

Re: Round-about mechanism wanted for common issue

by Chris Pratt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

What I do is in my layout I use code like:

    <tiles:importAttribute scope="request"/>
    <link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/css/default.css"
title="default" />
    <c:forEach items="${styles}" var="s">
      <link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/${s}" />
    </c:forEach>
    <script language="JavaScript" type="text/javascript"
src="${pageContext.request.contextPath}/script/util.js"></script>
    <c:forEach items="${scripts}" var="s">
      <script language="JavaScript" type="text/javascript"
src="${pageContext.request.contextPath}/${s}"></script>
    </c:forEach>

Then in my tiles.xml I have a template definition at the top like:

  <definition name="default-layout" template="/layout/default-layout.jsp">
    <put-attribute name="menu-bar" value="/tiles/menu-bar.jsp" type="template"/>
    <put-attribute name="left-nav" value="/tiles/left-nav.jsp" type="template"/>
  </definition>

Then I extend this and override the pieces that need to change for that page:

  <definition name="site-manager" extends="default-layout">
    <put-attribute name="title" value="Site Manager" type="string"/>
    <put-attribute name="body" value="/body/site-manager.jsp" type="template"/>
    <put-list-attribute name="styles">
      <add-attribute value="/css/tab.css" type="string"/>
    </put-list-attribute>
    <put-list-attribute name="scripts">
      <add-attribute value="script/cookies.js" type="string"/>
      <add-attribute value="script/tab.js" type="string"/>
    </put-list-attribute>
  </definition>

This seems to work well, is very flexible and keeps things that belong
in the header where they belong.
  (*Chris*)


On Tue, May 6, 2008 at 2:42 PM, Adam Hardy
<ahardy.struts@...> wrote:

>
> Antonio Petrelli on 06/05/08 18:02, wrote:
>
> > 2008/5/6 Adam Hardy <ahardy.struts@...>:
> >
> > >  So if I made a taglib that stored the CSS in its body into the request
> > > attribute, e.g. requestScope.specialCss, a bit like this:
> > >
> > >  <adam:style var="specialCss">
> > >  #ContextBody div.repo span { width: 25px; }
> > >  </adam:style>
> > >
> > >  then I could achieve this? Or do you mean that it's not possible?
> > >
> >
> > It's not possible to put it in the body and hope that it will be
> > processed in the header, simply because the header gets renderer
> > before the body, and when you render the body it's too late to process
> > the header.
> > I think that your option is to do some pre-rendering processing, for
> > example using a ViewPreparer, to store the extra CSS items, and then
> > use them when rendering the <head>.
> >
>
>  OK. Perhaps I could write a ViewPreparer that greps the JSP and extracts
> the CSS declared there.
>
>  I could write a simple taglib for the JSP to surround the CSS which would
> identify the portion to extract and also prevent it displaying when the JSP
> loads.
>
>  This depends on the ViewPreparer getting the name of the JSP file.
> Presumably that's in the AttributeContext.
>
>
>  Regards
>  Adam
>

Re: Round-about mechanism wanted for common issue

by Adam Hardy-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Chris,

good plan except for me the one problem is that you have to keep the CSS in
seperate files. I suppose I might end up doing that but I'd much rather keep the
special CSS in the same file as the JSP, if only it were possible.

At the moment I am putting this extra CSS directly on the HTML in style=""
attributes, which is OK for small pages but not optimal when it needs repeating
alot.

regards
Adam

Chris Pratt on 07/05/08 00:47, wrote:

> What I do is in my layout I use code like:
>
>     <tiles:importAttribute scope="request"/>
>     <link rel="stylesheet" type="text/css"
> href="${pageContext.request.contextPath}/css/default.css"
> title="default" />
>     <c:forEach items="${styles}" var="s">
>       <link rel="stylesheet" type="text/css"
> href="${pageContext.request.contextPath}/${s}" />
>     </c:forEach>
>     <script language="JavaScript" type="text/javascript"
> src="${pageContext.request.contextPath}/script/util.js"></script>
>     <c:forEach items="${scripts}" var="s">
>       <script language="JavaScript" type="text/javascript"
> src="${pageContext.request.contextPath}/${s}"></script>
>     </c:forEach>
>
> Then in my tiles.xml I have a template definition at the top like:
>
>   <definition name="default-layout" template="/layout/default-layout.jsp">
>     <put-attribute name="menu-bar" value="/tiles/menu-bar.jsp" type="template"/>
>     <put-attribute name="left-nav" value="/tiles/left-nav.jsp" type="template"/>
>   </definition>
>
> Then I extend this and override the pieces that need to change for that page:
>
>   <definition name="site-manager" extends="default-layout">
>     <put-attribute name="title" value="Site Manager" type="string"/>
>     <put-attribute name="body" value="/body/site-manager.jsp" type="template"/>
>     <put-list-attribute name="styles">
>       <add-attribute value="/css/tab.css" type="string"/>
>     </put-list-attribute>
>     <put-list-attribute name="scripts">
>       <add-attribute value="script/cookies.js" type="string"/>
>       <add-attribute value="script/tab.js" type="string"/>
>     </put-list-attribute>
>   </definition>
>
> This seems to work well, is very flexible and keeps things that belong
> in the header where they belong.
>   (*Chris*)
>
>
> On Tue, May 6, 2008 at 2:42 PM, Adam Hardy
> <ahardy.struts@...> wrote:
>> Antonio Petrelli on 06/05/08 18:02, wrote:
>>
>>> 2008/5/6 Adam Hardy <ahardy.struts@...>:
>>>
>>>>  So if I made a taglib that stored the CSS in its body into the request
>>>> attribute, e.g. requestScope.specialCss, a bit like this:
>>>>
>>>>  <adam:style var="specialCss">
>>>>  #ContextBody div.repo span { width: 25px; }
>>>>  </adam:style>
>>>>
>>>>  then I could achieve this? Or do you mean that it's not possible?
>>>>
>>> It's not possible to put it in the body and hope that it will be
>>> processed in the header, simply because the header gets renderer
>>> before the body, and when you render the body it's too late to process
>>> the header.
>>> I think that your option is to do some pre-rendering processing, for
>>> example using a ViewPreparer, to store the extra CSS items, and then
>>> use them when rendering the <head>.
>>>
>>  OK. Perhaps I could write a ViewPreparer that greps the JSP and extracts
>> the CSS declared there.
>>
>>  I could write a simple taglib for the JSP to surround the CSS which would
>> identify the portion to extract and also prevent it displaying when the JSP
>> loads.
>>
>>  This depends on the ViewPreparer getting the name of the JSP file.
>> Presumably that's in the AttributeContext.
>>
>>
>>  Regards
>>  Adam
>>
>

LightInTheBox - Buy quality products at wholesale price