Search

We'd still need an interface to manage translation strings right?

@davidhund

@ahwayakchih suggested the following idea but can't find the thread atm.

You can add a Textbox field to a section called Translations and fill it as an XML structure.

<data>
    <search ro="cauta" en="search" dk="sog" />
    <item handle="handle_for_very_long_text">
        <ro>prajitura</ro>
        <en>This is an excruciating long text that will be translated like a piece of cake.</en>
    </item>
</data>

etc...

Structure the XML whatever you like it.

Or add a Textbox for each language, though I don't recommend it.

A DS can easily fetch this info.

You can add a Textbox field to a section called Translations and fill it as an XML structure.

That feels a bit like a hack...

That feels a bit like a hack...

*Smart

I stumbled across this issue (translating static strings) some time ago. I created an extension that stores translations for every page on harddisk and automatically loads it on current page. Strings are stored in XML and edited in ... Notepad or whatever. I can make it public if you wanna have a look.

But I agree with the idea suggest above for small sites.

I actually made simple text formatter (using Templated Text Formatters) that turns text into XML by splitting each line of text into "source" and "destination". So our "dictionary" for language looks like:

Welcome!: Witaj!
Next: Nast?pny
This one is a very long label: To jest bardzo d?uga etykietka

Empty lines can be used to separate chunks of translations, and i'm also thinking about adding support for comments and possibly different "modes" of the same strings. This is very easy and intuitive for site administrators and/or translators to use.

I don't see how this is a hack compared to module that requires editing an XML file. The only difference is that file is on disk, and "dictionary" is in database. But that can be worked around, if one needs it as a file. Not to mention, that basing it on Symphony, we get all the features of using entries, e.g., adding other fields to each "dictionary" entry to get additional "dictionary settings" (maybe "language modes"? date format? separators, numeric formats, etc...).

The reason why it feels like a hack to me is because the look and feel of Sections simply make it unintuitive to use it for string label translation. Adding a single entry with a large text field using a custom text formatter only further proves to me that Sections is not the right way to go.

Looking at other implementations to the same problem, we have the GNU gettext, JAVA i18n property files, .Net String Resources files and even the Symphony backend / extensions language translation files. They are all more or less the same: file-based dictionaries containing key/value pairs where the language code is in the file name.

There is just one thing that is troublesome with the file-based implementation: ownership lies with developers and it requires a release to bring changes to production.

However, come to think of it, this is exactly how it is in many other commercial projects I've done and it is also common with the current company I work for (we use .Net string resource files).

I'm not sure how I feel about this, but I do see that the file-based approach is more standards compliant / common practice.

I feel the same way about this. I don't think it's a problem to couple i18n to 'releases' and have a more file-based, developer focussed, approach. It would, however, be very nice to package this up in a userfriendly interface as much as possible. I don't think it's a problem, UX wise, if the experience differs slightly from the well known Entry Editor.

Like i wrote, it's simple to export it to a file.

Keeping it in a file is exactly the same - big file, with many lines of text. So the only difference is a place where data is kept.

Unless you use modern format and translation processes like with XLIFF, data is used the same way (simple string replacements, translations are pairs of phrases).

You just seem to not like the interface (textarea vs text editor :), but that is personal preference (i too sometimes prefer text editor, when editing big XSLT utitilies and/or pages :).

It is also possible to build two sections: "dictionaries" and then "translations", and use SubsectionManager. That would create list of translations, one source-destination pair per entry. To optimize it for production pages, one could create page that generates list of translations, and then use cached DynamicXML data-source on end-user pages. That might be better suited for bigger projects, with many translators updating stuff at the same time (and it would almost automatically add a way to compare which language is missing some of the translations).

Like i said, Symphony allows to set additional (meta?) information for each dictionary. It gives you interface out-of-the-box. So it has the same functionality as file-based way, plus a lot more :).

Also, if you prefer to keep everything in XML file, why not use StaticXML data-source? It would create file on disk, and give you basic interface out-of-the-box. Wrapping it in DynamicXML would allow for easy language-parameter based selection and would not require manipulating files in manifest directory (which may even be prohibited - i can imagine setup, where different workspaces may need different set of translations).

After thinking really hard about this, I remember one of my original reasons to create this extension: I had a hard time using Sections / Entries for labels in my DTAP setup.

I use a CI server to build and deploy code changes to my T/A/P environments. This basically runs some optimization commands (YuiCompressor) and copies all files to the correct folder. It also runs the update command of the CDI extension to sync structural / preference changes to the database.

This strategy does not include content synchronization. So there is no way for me to automatically get content updates to Sections / Entries from my development environment to T/A/P. So I had to make manual updates, which does not really go well with the whole Continuous Integration / Continuous Deployment plan.

Hence my requirement to keep these labels in files. Those can be updated, committed to a VCS, build and shipped automagically.

This does create a problem for adding a Text Editor to the back-end. Basically, the above scenario describes a situation where the development environment is leading. The files are copied to T/A/P and will overwrite those values.

I can however imagine a situation where you have a dictionary file with default values in the development environment, and offer a Text Editor to create and manage the translations on the production environment.

Forgive me for jumping in at this point, but have you seen Craig's Text Upload extension? This allows you to upload a file, and edit in the publish page but still have it under version control (as only the file path is stored in the database, not the content).

At least that's I how remember it working ;)

Good point, but there are two concerns here:

  1. During deployment in a DTAP setup, the files will be overwritten, not merged. So backend editing of those files on production is a problem (except if you choose to have a default (non-mutable) dictionary file on production and translation files that only live on production)
  2. What is the added benefit of using the entry editor for a large text file? From a UX perspective, I would personally prefer creating a custom key/value pair editor that is designed for dealing with these language files. Else I could just as well use the File Manager extension to edit the file.

ad. 1 - so you want to block editing of translations everywhere except for development environment? If that's the reason, then i can understand why you want to put file in manifest directory. Still, if it was StaticXML, regular authors would not be able to edit it anyway, and there would be no misunderstandings when you overwrite it with version from development environment.

ad. 2 - If it is large enough, then indeed there's not much added benefit (except for what i wrote above - setting up a way for additional settings through entry fields). In that case you can always build front-end page for editing it (once again: it's an entry - it can be edited with events :) and build whatever fancy interface you imagine for it :D.

@remie what are your current thoughts regarding this extension at the moment? You mentioned some changes but this thread mentions some other options (<xsl:key/>, static XML, your issues with the context of CI/DTAP etc) also.

Are you still planning on working on this extension or will you leave it as is?

I am asking because I am in need of a 'gettext-like' extension such as this, but decoupled from the Language Redirect extension. If you are not planning on decoupling it I might just need to fork it and try it myself. Otherwise I gladly leave this in (your) more capable hands ;)

@david: I'm currently on vacation, but will definitely continue working on the extension when I return next week. I will need to recap everything that has been said, and also check out the Parametrisator exentsion ahwayakchih created. I will post the details on what I will do with this extension to the forum!

le nice… Enjoy your holidays!

@david: when do you need this to be ready?

haha, wat een service! :)

I need this sometime the coming month. No huge pressure though since there are more ways to 'skin this cat' :)

I've renamed the extension to gettext, although for now the code hasn't changed. I will be implementing the following changes:

  1. Add support for .PO files (based on the GNU specifications)
  2. Add support for i18n property files (based on java specifications)
  3. Decouple extension from Language Redirect
  4. Add datasources to allow resources to be added to the page XML output
  5. Add configuration settings to make sure the above makes sense to users

Any last minute comments / thoughts?

Any last minute comments / thoughts?

For anyone who should need the same approach that @remie will take, I have a version (== I can make it public) of his thoughts that uses XML files instead of PO.

Subscribed to Page new / edit / delete delegates and automatically generate XML files which store the strings.

[...]/worskapce/translations/ro OR [...]/worskapce/translations/ro OR [...]/worskapce/translations/xx :
- master.xml
- cotact.xml
- events.xml
etc

Structure (master.xml):

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <language translated="no" code="en" handle="english">English</language>
    <item handle="imagine">Image</item>
    <item handle="pagina-inexistenta">Page not found</item>
    <item handle="sunteti-aici">you are here:</item>
    ...you get the point...
</data>

These are then loaded directly in XSLT:

<xsl:variable name="v_translations_colector">
    <!-- general translations -->
    <xsl:copy-of select="document(concat($workspace_xml_lang-code, '/template_master.xml'))/data/item" />

    <!-- current page translations -->
    <xsl:copy-of select="document(concat($workspace_xml_lang-code, '/', $current_page_here))/data/item" />

    <!-- hook to add even more if needed on pages -->
    <xsl:call-template name="add_translations" />
</xsl:variable>

<!-- translation variable -->
<xsl:variable name="__" select="exsl:node-set($v_translations_colector)" />

Usage:

<xsl:value-of select="$__/item[ @handle='sunteti-aici' ]" />

gettext updated to version 2.0.1 on 20th of October 2011

Cannot publish it in the extensions section yet, because I get a database error. However, feel free to grab the code from GitHub!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details