Hello again,
Den 14. sep. 2006 kl. 15.26 skrev Sjur Moshagen:
1- get the request
2- get a list of all documents that matches the request,
disregarding i18n infixes in the
filenames (that is, a request for X.html should match all of:
X.YY.xml
X.ZZ.xml
X.xml
where YY, ZZ and <nothing> corresponds to available locales or
the fallback file
3- examine the X.xml (fallback file) for an @xml:lang or @lang to
determine the
language of the document; if not found, use the site default (if
available)
4- based on 2 and 3, create a list of all languages available
5- examine the document actually being returned by the request for
@xml:lang or @lang,
to be able to detect the currently viewed language (it could be
different from
the fallback document, since other i18n components can have
picked a better
choice based on browser settings)
6- return a list of available language variants, tagging the
presently displayed
language, and with each of the other languages as a link to that
document (using,
e.g. ?locale=YY or some other means to override browser settings)
I have now managed to do 1-5 (not in the exact way described above,
but still...).
I also found an existing component that seems to be doing the same,
but it doesn't work with dispatcher (calling http://localhost:8888/
i18n-index.html returns an error) - see i18n.xmap for details.
Compared with the old version, my implementation improves on a couple
of points:
- it handles fallback documents (ie document.xml as well as
document.XY.xml, where XY is the locale)
- it looks into the fallback document for language markup, and will
use that to determine the language of the fallback document if found
- if no language information for the fallback document is found, it
will use an external default; presently it is hardcoded, but it
should be easy for somebody to replace that with a forrest property
Two issues remain:
1) How do I get the *full* request URL into my contract, ie #
{$getRequest} + extension in one string? I need this to be able to
return a working URL extended with the override locale setting:
URL?locale=XY
2) There is a bug in the processing of the contract that leads to a
double set of language list. I have confirmed that the bug is not in
my XSL (at least according to xsltproc), thus I can only blame
Forrest/dispatcher;-)
Here are the present details (the created URLs are not properly made
yet, disregard that issue, it is simple to fix - just wanted to post
the two main issues):
==== Contract markup in local pelt.fv ====
<forrest:hook class="languages">
<forrest:contract name="language-variants"
dataURI="cocoon://#{$getRequest}.languages.xml">
<!--forrest:property name="URL">cocoon://#{$getRequest}</
forrest:property-->
</forrest:contract>
</forrest:hook>
==== document returned by dataURI above: ====
<?xml version="1.0" encoding="UTF-8"?>
<document localecount="4">
<locale>en</locale>
<locale>nb</locale>
<locale selected="true">se</locale> <!-- this is currently being
displayed -->
<locale fallback="true">en</locale> <!-- this is the 'document.xml'
type file, ie without locale -->
</document>
(The two 'en' locales is caused by us having one document.en.xml and
another document.xml with @xml:lang="en" - two documents for the same
language. That is a miss on our part, and the double locale listing
can be used for debugging.)
==== contract language-variants.ft: ====
<forrest:contract
xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
xmlns:forrest="http://apache.org/forrest/templates/1.0"
name="language-variants">
<description>
<p>
<strong>language-variants</strong> will output a list of
available language for a given
input document. The presently displayed language will be marked.
Styling
is done using CSS.
</p>
</description>
<usage><![CDATA[<forrest:contract name="language-variants"
dataURI="cocoon://#{$getRequest}.languages.xml"/>]]></usage>
<forrest:template xmlns:forrest="http://apache.org/forrest/
templates/1.0"
name="language-variants" inputFormat="xsl"
xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--xsl:param name="URL" -->
<!--<xsl:param name="defaultVariables" select="'test.html'"/>-->
<!--<xsl:variable name="skin-img-dir"
select="$defaultVariables/*/[EMAIL PROTECTED]'skin-img-dir']/@value"/>-->
<xsl:template match="document">
<forrest:content>
debug string -
<forrest:part>
<xsl:comment>+ |start language list +</xsl:comment>
<xsl:choose>
<xsl:when test="@localecount = 1">
<xsl:comment>+ |no alternative languages +</
xsl:comment>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="locale" />
</xsl:otherwise>
</xsl:choose>
<xsl:comment>+ |end language list +</xsl:comment>
</forrest:part>
</forrest:content>
</xsl:template>
<xsl:template match="locale">
<forrest:content>
<forrest:part>
<xsl:choose>
<xsl:when test="@selected = 'true'">
<span class="selected">
<i18n:text><xsl:apply-templates/></i18n:text>
</span>
</xsl:when>
<xsl:otherwise>
<span>
<a>
<xsl:attribute name="href">
<xsl:value-of select="./text()"/>
</xsl:attribute>
<i18n:text><xsl:apply-templates/></i18n:text></a>
</span>
</xsl:otherwise>
</xsl:choose>
</forrest:part>
</forrest:content>
</xsl:template>
</xsl:stylesheet>
</forrest:template>
</forrest:contract>
==== output in rendered html: ====
<div class="languages">
<!--+ |start language list +-->
<content>
<part>
<span>
<a href="en">en</a>
</span>
</part>
</content>
<content>
<part>
<span>
<a href="nb">nb</a>
</span>
</part>
</content>
<content>
<part>
<span class="selected">se</span>
</part>
</content>
<content>
<part>
<span>
<a href="en">en</a>
</span>
</part>
</content>
<!--+ |end language list +-->
<span>
<a href="en">en</a>
</span>
<span>
<a href="nb">nb</a>
</span>
<span class="selected">se</span>
<span>
<a href="en">en</a>
</span>
</div>
==== expected output as rendered by xsltproc (my wrapping/indenting):
====
<?xml version="1.0"?>
<forrest:content xmlns:forrest="http://apache.org/forrest/templates/
1.0" xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
debug string -
<forrest:part>
<!--+ |start language list +-->
<forrest:content>
<forrest:part>
<span><a href="nb">
<i18n:text>nb</i18n:text></a>
</span>
</forrest:part>
</forrest:content>
<forrest:content>
<forrest:part>
<span class="selected">
<i18n:text>se</i18n:text>
</span>
</forrest:part>
</forrest:content>
<forrest:content>
<forrest:part>
<span>
<a href="en"><i18n:text>en</i18n:text></a>
</span>
</forrest:part>
</forrest:content>
<!--+ |end language list +-->
</forrest:part>
</forrest:content>