Search code examples
javascriptjqueryfacebookjquery-templatesxfbml

Javascript Translation Templating


I'm currently working on re-implementing the frontend to Facebook's internationalization XFBML tag that has been broken for quite some time. I'm almost finished but have one hangup: replacing tokenized translations without losing child nodes' information.

For background, the translation tags look something like this:

<fb:intl>
Text goes here and you can have {a-token} like this.
<fb:intl-token name="a-token">parameters</fb:intl>
</fb:intl>

You pass them a string like this: Text goes here and you can have {a-token} like this.

And you get back a translated string like this: El texto va aquí y usted puede tener {a-token} como ésta.

This lets you translate strings only once even though you can put in dynamic data. The cool part (and the problem) is that you can nest these strings. So instead of the plain text of "parameters" inside the token it may have another nested fb:intl tag inside of it (which in turn may have another inside of it, etc).

What I am trying to do is do this replacement without losing the context of the child nodes. So I want to just take the <fb:intl-token> tag and move it to replace the {token} that represents its place in the string.

Any ideas on how to do this effectively?


Solution

  • After quite a bit of hacking I was able to come up with a solution.

    The psuedocode is this:

    1. Clone the original element using jQuery's .clone(true) (to maintain all the original data, etc).
    2. Empty the cloned element with .empty().
    3. Set the .html() to be a regex replacement of the tokens into html elements so they can be manipulated easily via jQuery: .replace(/{([a-zA-Z\-]+)}/, '<span id="$1"></span>').
    4. Loop through the original element's fb:intl-token children and for each one, do $(this).insertBefore(placeHolder); (where placeHolder is the replaced token from step 3 -- that's why its id is based on the token name)
    5. Remove the placeholder from the cloned element.
    6. Replace the original element with the clone.

    So far this appears to be working just dandy.