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>