Monday, June 24, 2013

Big decisions

This has been the first week of coding, officially. And it has been a surprisingly tough one. One of the major design decisions has been made, I have a somewhat bigger understanding of Geeklog plugin development and I feel a slight sense of accomplishment.


Baby steps
The first thing was to make something, a good place to start (if you are interested in making a plugin for Geeklog) is here. This is a detailed handbook. If however you are like me and like to see things examining the plugins which ship with Geeklog is a good approach. I use the Polls plugin as my reference as it has most resemblance with what I am doing. Last but definitely not least, the thing that gave me a kick start is the Plugin Toolkit. It is useful, after providing some basic data about your plugin it will generate a lot of code for you. After that you have to divide the generated files to the right places and of course edit what you need. Again it is a good start it will not develop a plugin.

So what I did was use the plugin to generate some files. After that things went south for a bit. First of all was the decision on who is allowed to do translations. The community decided that logged in users, with credentials provided by the central Geeklog "page" would be allowed to translate. This discusion also included a discussion about how the database should look like and well the final form is as suggested by Wim Niemans. Creating a database table with Geeklog is as simple as editing a sql file (a sample file is generated by the toolkit).
After that I played a bit with the configuration. It is not final it is not even a large step towards the final it was more a exercise for me than providing actual code. But after doing it I am ready to do some real damage when I get to that part. My approach so far was to build simple parts, working good enough to allow me to tackle what I though would be the "big" problem.... And a big problem it was.

The big bad LANG
Before I get to the problem, let me describe how Geeklog core works.
Geeklog has it's language folder with language files, e.g. english.php, bosnian.php, german.php...
A snipet from the english.php file:
$LANG01 = array(
    1 => 'Contributed by:',
    2 => 'read more',
    3 => 'comments',
    4 => 'Edit',
    5 => '',
    6 => '',
    7 => '',
    8 => '',
    9 => 'Admin Functions:',
    10 => 'Submissions',
    11 => 'Stories',
    12 => 'Blocks',
    13 => 'Topics',
    14 => '',
    15 => '',
    16 => '',
    17 => 'Users',
    18 => 'SQL Query',
    19 => 'Log Out',
    20 => 'User Information:',
    21 => 'Username',
    22 => 'User ID',
    23 => 'Security Level',
    24 => 'Anonymous',
...

There are a lot more arrays with a lot more element. The elements can be one word elements or multiple sentences. They can include html code and so forth and so on. They also include common words such as "Save" which can be otherwise included in the page, as a user comment, as a page generated by the static pages plugin... So the big problem is identifying the strings on a rendered page. This is important as the whole goal of the plugin is to provide a context for the translation.

There were several possibilities for solving this. My first idea was to add HTML tags to the array elements such as <span class="translator">.....</span> but the problem with this was that these spans can not be included in places such as the <title></title> or inside a <input value="">. Another approach was to add a API to Geeklog, although this would probably work perfect, and without much hiccups I wanted to avoid doing changes to the Geeklog core.

My (currently) final solution
I went on with the idea of adding some kind of identification to the array elements. Spent some time trying out special HTML symbols such as &#8204. This symbol is invisible for the user, which made it perfect it also was invisible to JavaScript which made it useless.
So I moved on to adding simple text. What I finally have is that all the elements (in the default language file) have these marks: _-start_ and _-end_. I tried to devise something unlikely to appear otherwise on the page.
This change is done when the plugin is installed and is removed if and when the plugin is removed. It will (in the near future) also provide a way to add the identification to other language files (if by some chance the default language of the page is changed).
After doing this, in order to save computation time later I also added data on which array and which element the current string belongs to.
The english.php file now looks like this:
$LANG01 = array(
    1 => '_-start_||array=$LANG01index=1||Contributed by:_-end_',
    2 => '_-start_||array=$LANG01index=2||read more_-end_',
    3 => '_-start_||array=$LANG01index=3||comments_-end_',
    4 => '_-start_||array=$LANG01index=4||Edit_-end_',
    5 => '',
    6 => '',
    7 => '',
    8 => '',
    9 => '_-start_||array=$LANG01index=9||Admin Functions:_-end_',
    10 => '_-start_||array=$LANG01index=10||Submissions_-end_',
    11 => '_-start_||array=$LANG01index=11||Stories_-end_',
    12 => '_-start_||array=$LANG01index=12||Blocks_-end_',
    13 => '_-start_||array=$LANG01index=13||Topics_-end_',
    14 => '',
    15 => '',
    16 => '',
    17 => '_-start_||array=$LANG01index=17||Users_-end_',
    18 => '_-start_||array=$LANG01index=18||SQL Query_-end_',
    19 => '_-start_||array=$LANG01index=19||Log Out_-end_',
    20 => '_-start_||array=$LANG01index=20||User Information:_-end_',
    21 => '_-start_||array=$LANG01index=21||Username_-end_',
    22 => '_-start_||array=$LANG01index=22||User ID_-end_',
    23 => '_-start_||array=$LANG01index=23||Security Level_-end_',
    24 => '_-start_||array=$LANG01index=24||Anonymous_-end_',
...

I am not saying that this is the best possible solution. I am saying that it works and it does not demand changing the coding style of Geeklog. If you have a better solution leave a comment, write me an email, write an email to Geeklog-Devel mailing list...

Doing just this (of-course) makes the page ugly, very ugly.
About this much:




That is why I added some JavaScript magic, to remove the marks and to extract the data I will need to create the translation interface.

This is a sample object I get:
string: Advanced Search, array: $LANG01, index: 75

And this is how the page looks after JavaScript:


Note that not all the strings will be red all the time. The plan is that the user can pick the string he wants to translate and that the picked string will be highlighted. The highlight might be changing the color, or increasing the font size or all of it.

That is the big step I made towards completing this project.

Again If you have any suggestions please feel free to contact me.

For the Geeklog community: You Rock!!! And thank you for having patience with me.

Thanks for reading.