Wiki

Clone wiki

Okapi / PackageFormat

Extensible Localisation Kit (XTK)

At the core of this 'vision' of a localisation framework is a project model. This model defines how we exchange data between different parts of the system (e.g. web, rich client).

The danger and downside of e.g. XLIFF and other meta-formats is that they tend to loose information in the process. And if XLIFF doens't support the feature, please wait X years until the new version of XLIFF is out. This is very counterproductive, and very non-agile (hm.. what is the opposite of agile?).

While XLIFF has some extensibility mechanisms built in, they are very limited.

Structure

Firstly, we use a zipped archive format similar to e.g. ODF or OOXML or jar archives. (On a server environment we would likely use another storage format, but the data model concepts remain the same)

Pointers: * Office Open XML specification * ODF Specification * Jar specification

We need to store the following core items: * A manifest file that's quick to access to get the basic information about the package. * An Extension registry * A Resource model descriptor

Now, I haven't decided on a structure for any of these, but have written a few examples that can get our minds thinking:

package.xml:

<package xmlns="urn:myns:package" version="1.0">
  <header>
    <name>My Sample L10N Package</name>
    <desciption>A brief desc of package</description>
    <x:labels xmlns:x="urn:myns:labels">
      <x:label>documentation</x:label>
    </x:labels>
  </header>
  <extensions>
    <extension id="org.camouflage.xliff.workflow" version="1.0" mustUnderstand="true" namespace="urn:myns:workflow"/>
    <extension id="org.camouflage.project.labels" version="1.0" mustUnderstand="false" namespace="urn:myns:labels"/>
    <extension id="org.camouflage.resources.priority" version="1.0" mustUnderstand="true"/>
    <extension id="org.camouflage.resources.statistics" version="1.0" namespace="urn:myns:statistics" mustUnderstand="false"/>
    <extension id="org.camouflage.resources.views" version="1.0" mustUnderstand="false"/>
    <extension id="org.camouflage.resources.tm.remote" version="1.0" mustUnderstand="false">
      <remote-tm xmlns="urn:remote-tm">
      </remote-tm>
    </extension>
  </extensions>
</package>

The first bit (<header>) is basic. Next part is the <extensions> registry. This registry defines what features are available in this package. For example, i have added the "labels" extension, allowing me to specify which folksonomy labels are attached to this project. Now extension developers can use these extension points when creating files, and similarly create rich-client plug-ins that can run in our workbench. The mustUnderstand attribute specifies if the client must know how to process this extension to modify the package.

content.xml

<content>
  <meta-inf>
    ...
  </meta-inf>
  <resources>
    <container type="folder" label="Documentation">
      <resources>
        <!-- In some sense XLIFF is a container rather than a resource -->
        <resource type="xliff" ref="content/myfile.xlf" res:priority="1" xlf:original="myfile.txt">
          <s:statistics xmlns:s="urn:myns:statistics">
            <s:word total="434" translated="34" untranslated="45" in-process="355"/>
            <s:unit total="50" translated="3" untranslated="4" in-process="43"/>
          </s:statistics>
        </resource>
      </resources>
    </container>
  </resources>
</content>

The content model defines a hierarchy of resources, similar to a folder structure. Extensions can use this model to add features, e.g. statistics or links to online resources.

Discussion

Plugin system

YS> I'm especially interested in extension for things like rendering plug-ins, or validation plug-ins, etc. I imagine this would be in a folder shipped with the package, or on a server, and the extension would have some plug-in description pointing to the calls to use (for local plug-in) like:

<plugin id="com.translate.validators.xyz" class="com.translate.validators.xyz.Validator">
Validator for the format XYZ
</plugin>

AF> Yes, I was thinking exactly the same (i think). In the context of an Eclipse RCP platform, I was thinking the following:

Say we have an extension-point in our RCP application for providing editors (allowing translators to switch from a table based editor to e.g. a visual editors if it's an HTML-based XLIFF file). Now, initially there is just the table-based editor, and our application does not know that the content-type "html" has a plugin somewhere that provides a richer editor for translations. But: say our server instance providing the translation kit knows about this plugin.

<extensions>
  <extension id="org.camouflage.rcp.updateSite" version="1.0" mustUnderstand="false" namespace="urn:myns:rcp:us">
    <update-site xmlns="unr:myns:rcp:us" id="org.othertoolkit.updateSite">
       <name>other toolkit update site</name>
       <description>Update site for features developed for L10N RCP app from other toolkit</description>
       <url>http://othertoolkit.com/rcp/update-site/3.4/</url>
    </update-site>
  </extension>
  <extension id="org.camouflage.rcp.editor" version="1.0" mustUnderstand="false" namespace="urn:myns:rcp:editor">
    <editor xmlns="urn:myns:rcp:editor" content-type="html" feature-id="org.othertoolkit.editor.html" provider="org.othertoolkit.updateSite"/>
  </extension>
</extensions>

So for each Rich client "extension" there has to be 1) an extension point defined in the Eclipse RCP application, and b) an extension listed in the kit that describes how to install this extension. I am not sure how we can transfer this concept also to the server side, and de-couple it from e.g. OSGI and the Eclipse extension mechanism. I am not very keen on actually bundling plugins inside the zipped kit. Having the code and the extension declarations separate allows us to use 'trusted' update sites.

That is an example of how the translation kit extension system could work. It wouldn't be coupled with e.g. OSGI and Eclipse RCP, but could be if we wanted it to, especially for features that requires code to be downloaded and executed.

This concept also allows e.g. older versions of a product to e.g. prompt the user that he needs to update the applciation to translate this kit, as the kit uses newer features that are only available in a newer version.

Updated