You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@forrest.apache.org by Eric BURGHARD <eb...@free.fr> on 2003/10/03 23:12:04 UTC

[CONTRIB] auto generation of menus

Hi,

I've made some modifications to directory2book.xsl (which generate side menu 
based on directory content):
-little cleanup (expected-extension argument no more needed)
-kind of control on which items are present or not
-allow parametrable sorting of menu-items
-easily extensible.

Example: auto generate menu from several directories (named dir1,dir2, dir3) 
full of document-v20 files. Each document file could have two meta tags
1- <meta name="short-title">short title</meta> 
for the menu if title is too long
2- <meta name="date">20031002</meta>
used for sorting items by date

I use the xpathdirectory generator to extract the meta and title tags. I use 
regexp matcher to factorize the matches.

-- sitemap.xmap snippet

<map:match pattern="(.*)(dir1|dir2|dir3)/book-(.*)" type="regexp">
   <map:generate label="debug" src="content/xdocs/{1}{2}" 
type="xpathdirectory">
      <map:parameter name="depth" value="2"/>
      <map:parameter name="xpath" value="/document/header/meta | 
/document/header/title"/>
   </map:generate>
   <map:transform src="resources/stylesheets/documentdirectory2book.xsl">
      <map:parameter name="sort-order" value="descending"/>
      <map:parameter name="sort-select" value="dir:xpath/meta[@name='date']"/>
   </map:transform>
   <map:serialize type="xml"/>
</map:match>

---

i override the named template "get-label" in documentdirectory2book.xsl which 
inherit from directory2book.xsl

--- documentdirectory2book.xsl snippet

<!-- label is  short-title, title and in last resort filename -->
<xsl:template name="get-label">
   <xsl:param name="corename"/>
   <xsl:choose>
      <xsl:when test="dir:xpath/meta[@name='short-title']">
         <xsl:value-of select="dir:xpath/meta[@name='short-title']"/>
      </xsl:when>
      <xsl:when test="dir:xpath/title">
          <xsl:value-of select="dir:xpath/title"/>
      </xsl:when>
      <xsl:otherwise>
          <xsl:value-of select="$corename"/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

implementation:
1- substring-before-last is defined in a separate xsl file. With this named 
template, expected-extension is no more needed
2- to able to change the select attribute of <xsl:sort/>, i use the dynamic 
extension of exslt <dyn:evaluate> 
(http://www.exslt.org/dyn/functions/evaluate/dyn.evaluate.html)

Hope it could help someone

Re: [CONTRIB] auto generation of menus

Posted by Eric BURGHARD <eb...@free.fr>.
here is the forgotten substring-last.xsl

Re: [CONTRIB] auto generation of menus

Posted by Eric BURGHARD <eb...@free.fr>.
Le Mercredi 08 Octobre 2003 13:12, Jeff Turner a écrit :

> True.
>
> Is there any reason we shouldn't just insist on the use of
> XPathDirectoryGenerator?  Why bother maintaining a subset of
> functionality for DirectoryGenerator?  Having labels equal to the
> filename (minus extension) sounds very unappealing to me.
>

Yeah ;-) you're the integrator, you choose. But it was for backward 
compatibility too (labels equal to the filename). Also you're right: 
XPathDirectoryGenerator is compatible with DirectoryGenerator and XPath is 
only applied on $xmlFiles regexp (match *.xml by default). Who do the most do 
the less. But it sounds weird to me to call XPathDirectoryGenerator on my 
jpegs directories. Just a question of taste.

>
> .. merged with that in CVS.
>

Thanks jeff !

> >
> > Yeah ! much more flexibility like this ! Thus you can already achieve
> > quite the same behavior with the actual sorting mechanism and without the
> > hassle of programming a constraints resolution engine. Use directory
> > hierachie a relaxed numbering scheme (like sysV init filenames):
> >
> > directory: GettingStarted
> > file1
> > <meta name="menu-order">S5</meta>
> >
> > index.xml
> > <meta name="menu-order">S0</meta>
> >
> > primer.xml
> > <meta name="menu-order">S20</meta>
> >
> > and do your sorting with
> >
> > <map:transform src="resources/stylesheets/documentdirectory2book.xsl">
> >    <map:parameter name="sort-select"
> > value="dir:xpath/meta[@name='menu-order']"/>
> > </map:transform>
>
> That almost works currently, except the sort is lexical not numeric so
> S10 < S2.
>

Yeah of course ! sorry for the typos: S00 and S05 (the real initV scheme ;-). 
We can tell xslt to sort numeric by an xsort attribute, but it's numeric only 
(not num and alpha mixed).

> > PS: What did the pathutils.xsl do in resources/skins/common/xslt/html
> > directory ? Shouldn't it be placed in resources/stylesheets ?
>
> It originated from the common need in skin XSLTs.  Since its generic it
> makes a bit more sense in resources/stylesheets, but moving it would
> likely break custom skins which expect it in its existing location.
>
>

Ok.

> --Jeff

A+


Re: [CONTRIB] auto generation of menus

Posted by Jeff Turner <je...@apache.org>.
On Tue, Oct 07, 2003 at 02:59:54AM +0200, Eric BURGHARD wrote:
> Le Lundi 06 Octobre 2003 08:47, Jeff Turner a écrit :
> > On Fri, Oct 03, 2003 at 11:12:04PM +0200, Eric BURGHARD wrote:
> > > Hi,
> > >
> > > I've made some modifications to directory2book.xsl (which generate side
> > > menu based on directory content):
> > > -little cleanup (expected-extension argument no more needed)
> > > -kind of control on which items are present or not
> > > -allow parametrable sorting of menu-items
> > > -easily extensible.
> >
> > Nice.  I've committed it with some modifications:
> >
> >  - Used the existing pathutils.xsl instead of substring-last.xsl
> >  - I didn't understand the purpose of documentdirectory.xsl, so I put its
> >    enhanced get-label template in directory2book.xml.  Any reason to
> >    separate it out, other than to demonstrate its 'overridability'?
> >
> ;-)
> 
> Yeah, in fact, directory2book.xsl is not specificly designed to be used with 
> XPathDirectoryGenerator. Right ? After a simple DirectoryGenerator you've got 
> no dir:xpath nodeset in the result. So is there any good reason to compute 
> the menu-items labels from inexistants tags and rely on the default behavior 
> which take them from the filenames ?

True.

Is there any reason we shouldn't just insist on the use of
XPathDirectoryGenerator?  Why bother maintaining a subset of
functionality for DirectoryGenerator?  Having labels equal to the
filename (minus extension) sounds very unappealing to me.

> On the other side, when you apply documentdirectory2book.xsl you say 
> indirectly your intention to scan directory full of document-v20 compliant 
> xml. This stylesheet rely on XPathDirectoryGenerator because the get-label 
> template make use of dir:xpath contents.
> 
> If you've got docbook directories, perhaps you want to get the labels from 
> something else than <meta name="short-title"/> (the meta tag could possibly 
> not exists in docbook or exists in another branch than document/header, i 
> don't know). So just edit a new docbookdirectory2book.xsl which only need to 
> override the get-label with something like:
> 
> <xsl:template name="get-label">
>  <xsl:value-of select="dir:xpath/whatever-tab"/>
> </xsl:template>
> 
> and modify your sitemap.xmap accordingly
> 
> <map:generate label="debug" src="content/xdocs/{1}{2}" type="xpathdirectory">
>   <map:parameter name="xpath" value="//whatever-tab">
>   </map:generate>
>   <map:transform src="resources/stylesheets/docbookdirectory2book.xsl"/>
>   <map:serialize type="xml">
> </map:generate>
> 
> In the last version of my directory2book.xsl (attached)

.. merged with that in CVS.

> I also define a 
> get-href named template. That way you can easily compute the urls served by 
> menu-items. Example: for my simple gallery i use a jpegdirectory2book.xsl 
> which is quite simple and clear:
> 
>     <xsl:import href="directory2book.xsl"/>
>     <xsl:output doctype-public="-//APACHE//DTD Cocoon Documentation Book 
> V1.0//EN" doctype-system="book-cocoon-v10.dtd"/>
> 
>     <!-- link to screen oriented jpegs -->
>     <xsl:template name="get-href">
>         <xsl:param name="corename"/>
>         <xsl:value-of select="concat($corename, '-1024.jpg')"/>
>     </xsl:template>
> 
> </xsl:stylesheet>
> 
> for each of my jpegs i've got a menu-item item which link to something like 
> img-1024.jpg which refer to img.jpg with a 1024 pixels height.
> 
> Somewhere in my sitemap.xmap i've got this to generate jpeg at a given height.
> 
> <map:match pattern="(.*)-([0-9]*).jpg" type="regexp">
>   <map:read src="content/xdocs/{1}.jpg" type="image">
>      <map:parameter name="height" value="{2}"/>
>   </map:read>
> </map:match>

Cool!

...
> > Then pages could have some metadata used by the sorting algorithm:
> >
> > <meta name="group">GettingStarted</meta>
> >
> > <meta name="comes-after">index.html</meta>
> >
> > <meta name="comes-before">primer.html</meta>
> >
> 
> Yeah ! much more flexibility like this ! Thus you can already achieve quite 
> the same behavior with the actual sorting mechanism and without the hassle of 
> programming a constraints resolution engine. Use directory hierachie a 
> relaxed numbering scheme (like sysV init filenames):
> 
> directory: GettingStarted
> file1
> <meta name="menu-order">S5</meta>
> 
> index.xml
> <meta name="menu-order">S0</meta>
> 
> primer.xml
> <meta name="menu-order">S20</meta>
> 
> and do your sorting with
> 
> <map:transform src="resources/stylesheets/documentdirectory2book.xsl">
>    <map:parameter name="sort-select" 
> value="dir:xpath/meta[@name='menu-order']"/>
> </map:transform>

That almost works currently, except the sort is lexical not numeric so
S10 < S2.

> PS: What did the pathutils.xsl do in resources/skins/common/xslt/html 
> directory ? Shouldn't it be placed in resources/stylesheets ?

It originated from the common need in skin XSLTs.  Since its generic it
makes a bit more sense in resources/stylesheets, but moving it would
likely break custom skins which expect it in its existing location.


--Jeff


Re: [CONTRIB] auto generation of menus

Posted by Eric BURGHARD <eb...@free.fr>.
Le Lundi 06 Octobre 2003 08:47, Jeff Turner a écrit :
> On Fri, Oct 03, 2003 at 11:12:04PM +0200, Eric BURGHARD wrote:
> > Hi,
> >
> > I've made some modifications to directory2book.xsl (which generate side
> > menu based on directory content):
> > -little cleanup (expected-extension argument no more needed)
> > -kind of control on which items are present or not
> > -allow parametrable sorting of menu-items
> > -easily extensible.
>
> Nice.  I've committed it with some modifications:
>
>  - Used the existing pathutils.xsl instead of substring-last.xsl
>  - I didn't understand the purpose of documentdirectory.xsl, so I put its
>    enhanced get-label template in directory2book.xml.  Any reason to
>    separate it out, other than to demonstrate its 'overridability'?
>
;-)

Yeah, in fact, directory2book.xsl is not specificly designed to be used with 
XPathDirectoryGenerator. Right ? After a simple DirectoryGenerator you've got 
no dir:xpath nodeset in the result. So is there any good reason to compute 
the menu-items labels from inexistants tags and rely on the default behavior 
which take them from the filenames ?

On the other side, when you apply documentdirectory2book.xsl you say 
indirectly your intention to scan directory full of document-v20 compliant 
xml. This stylesheet rely on XPathDirectoryGenerator because the get-label 
template make use of dir:xpath contents.

If you've got docbook directories, perhaps you want to get the labels from 
something else than <meta name="short-title"/> (the meta tag could possibly 
not exists in docbook or exists in another branch than document/header, i 
don't know). So just edit a new docbookdirectory2book.xsl which only need to 
override the get-label with something like:

<xsl:template name="get-label">
 <xsl:value-of select="dir:xpath/whatever-tab"/>
</xsl:template>

and modify your sitemap.xmap accordingly

<map:generate label="debug" src="content/xdocs/{1}{2}" type="xpathdirectory">
  <map:parameter name="xpath" value="//whatever-tab">
  </map:generate>
  <map:transform src="resources/stylesheets/docbookdirectory2book.xsl"/>
  <map:serialize type="xml">
</map:generate>

In the last version of my directory2book.xsl (attached) I also define a 
get-href named template. That way you can easily compute the urls served by 
menu-items. Example: for my simple gallery i use a jpegdirectory2book.xsl 
which is quite simple and clear:

    <xsl:import href="directory2book.xsl"/>
    <xsl:output doctype-public="-//APACHE//DTD Cocoon Documentation Book 
V1.0//EN" doctype-system="book-cocoon-v10.dtd"/>

    <!-- link to screen oriented jpegs -->
    <xsl:template name="get-href">
        <xsl:param name="corename"/>
        <xsl:value-of select="concat($corename, '-1024.jpg')"/>
    </xsl:template>

</xsl:stylesheet>

for each of my jpegs i've got a menu-item item which link to something like 
img-1024.jpg which refer to img.jpg with a 1024 pixels height.

Somewhere in my sitemap.xmap i've got this to generate jpeg at a given height.

<map:match pattern="(.*)-([0-9]*).jpg" type="regexp">
  <map:read src="content/xdocs/{1}.jpg" type="image">
     <map:parameter name="height" value="{2}"/>
  </map:read>
</map:match>

and by default (in directory2book.xsl) get-href is

<xsl:template name="get-href">
   <xsl:param name="corename"/>
   <xsl:value-of select="concat($corename, '.', $served-extension)"/>
</xsl:template>

which link items with something like filename.html

> Sorting by XPath is a good idea, but ordering still doesn't seem flexible
> enough for ordinary sites.  Perhaps we need another transformer that sets
> a <meta name="order"> field based on some clever algorithm:
>
> <map:generate src="content/xdocs/{1}" type="xpathdirectory"/>
> <map:transform type="sorter"/>
> <map:transform src="resources/stylesheets/directory2book.xsl"/>
>

That would be nice. I didn't like the fact to use a non standard xslt 
extension to achieve this sorting flexibility in my stylesheet, but it was a 
good preliminary that fullfill my needs.

> Then pages could have some metadata used by the sorting algorithm:
>
> <meta name="group">GettingStarted</meta>
>
> <meta name="comes-after">index.html</meta>
>
> <meta name="comes-before">primer.html</meta>
>

Yeah ! much more flexibility like this ! Thus you can already achieve quite 
the same behavior with the actual sorting mechanism and without the hassle of 
programming a constraints resolution engine. Use directory hierachie a 
relaxed numbering scheme (like sysV init filenames):

directory: GettingStarted
file1
<meta name="menu-order">S5</meta>

index.xml
<meta name="menu-order">S0</meta>

primer.xml
<meta name="menu-order">S20</meta>

and do your sorting with

<map:transform src="resources/stylesheets/documentdirectory2book.xsl">
   <map:parameter name="sort-select" 
value="dir:xpath/meta[@name='menu-order']"/>
</map:transform>

PS: What did the pathutils.xsl do in resources/skins/common/xslt/html 
directory ? Shouldn't it be placed in resources/stylesheets ?

>
> --Jeff

Re: [CONTRIB] auto generation of menus

Posted by Jeff Turner <je...@apache.org>.
On Fri, Oct 03, 2003 at 11:12:04PM +0200, Eric BURGHARD wrote:
> Hi,
> 
> I've made some modifications to directory2book.xsl (which generate side menu 
> based on directory content):
> -little cleanup (expected-extension argument no more needed)
> -kind of control on which items are present or not
> -allow parametrable sorting of menu-items
> -easily extensible.

Nice.  I've committed it with some modifications:

 - Used the existing pathutils.xsl instead of substring-last.xsl
 - I didn't understand the purpose of documentdirectory.xsl, so I put its
   enhanced get-label template in directory2book.xml.  Any reason to
   separate it out, other than to demonstrate its 'overridability'?

Sorting by XPath is a good idea, but ordering still doesn't seem flexible
enough for ordinary sites.  Perhaps we need another transformer that sets
a <meta name="order"> field based on some clever algorithm:

<map:generate src="content/xdocs/{1}" type="xpathdirectory"/>
<map:transform type="sorter"/>
<map:transform src="resources/stylesheets/directory2book.xsl"/>

Then pages could have some metadata used by the sorting algorithm:

<meta name="group">GettingStarted</meta>

<meta name="comes-after">index.html</meta>

<meta name="comes-before">primer.html</meta>


--Jeff