Friday, July 5, 2013

The plugin is getting in shape

It has been a while since the last post. Somehow I had the feeling there is not much to report. However when I take a look at the changeset on my repro I see that there has been work done, a lot of it. It is kind of hard to be objective about this. What may seem to be only one little feature can require a lot of coding, planing a bit of crying... This project is very special this way as the most part is not adding code, but finding less ugly ways to solve problems. +Dirk Haun said "There is no beautiful way to do this".

The big bad language file

So lets start, since the last blog post I have changed the language_markup.php file, the file that marks the core Geeklog strings I have to identify on the page later on. In addition to the actual markup it will now take all the strings, edit them and save them to the database. This has been done mainly because some of those strings have PHP variables, html code and so on and so forth. All of those are replaced with pseudo tags such as <tag> and <var> so the final display for the translator is Comments (<var>) , the user is required to type the <var> code in the translation, in the appropriate place. Say a translation to Swahili would be Maoni (<var>) (I used Google Translate for the example). Later on, when we do the 'packing' of the translations the <var> and <tag> will be replaced with whatever variable, or HTML was original there.


This is how the string looks inside the database:
englishcoreLANG0159"Don't have an account yet?  Sign up as a <tag>New...{"html":["<a href=\\\"{VAR}\/users.php?mode=new\\\" rel=\\\"nofollow\\\">","<\/a>"],"vars":["$_CONF['site_url']"]}
And the original string from Geeklogs language file:
"Don't have an account yet?  Sign up as a <a href=\"{$_CONF['site_url']}/users.php?mode=new\" rel=\"nofollow\">New User</a>"

It might very well be that this approach will need some editing. As currently I treat all the language files as text files, read them line by line and edit them as strings. I do this to prevent the PHP variables to display the variable value instead of the variable name.

After I had something which could be translated, and a way to identify the Geeklog core strings on a fully rendered HTML page, it was time to add the user interface.


User interface

The user interface is written in 2 places. Geeklog has it's API for adding content to the sides of the page (where this plugin is located). In this place I only add the core of the interface. In my case this is the name of the plugin, and a <form> in which the user should type the language to which he/she is translating.
Everything else is (and has to be) added from the JS file. The content has to be created dynamically.

Picking the language

To prevent creating languages such as Engrish or Geraman (English and German) I have use jQueryUI to add autocomplete to the input field. This is more or less how the whole thing looks like when you open the page (start a new session).
 
Selecting the language
You may have noticed that the language in the image is test_language_name, this is the language I used in the database. The auto complete is generated from the languages shipped with Geeklog and all the languages submitted previously to the plugin.

After the user has selected his language of choice the plugin will save it as a Cookie, this way the user has to (but is not bound to) select the language only once. The selection can be changed.
 
Changing the language will present the user with the same <form> as if he never picked a language before.

The Translation Form

After the language is picked the actual translation form is generated by JavaScript. Actually most of the preparations are done before the language is selected. The AJAX call to get all the formatted strings from the database is done when the page is loaded. Now the data is 'just' used to create the form and all it's goodies.
The form has 4 basic parts :

1) Highlighter (and remover)
2) Input field
3) Display of previous translation
4) Votes

The highlighter allows the user to identify the string they are translating on the page. Originally I used a onclick() function to highlight the string and onblur() to remove the highlight, but more often then not the user 
would have to scroll to see the highlighted string, which can produce a on blur (unless they use the browser's scroll bar) and the highlight would be lost. So now it is handled via button click.This also allows for multiple strings to be highlighted.

The script will get translations for previously translated strings. It will select the one with the largest 'like' (up vote) value. And display it to the user, the user can then either like or dislike the translation or add his/her own to it. The plan is to pack the translations with the largest up votes, and to periodically (before packing) remove translations with a certain negative vote value. 


Another 'problem' was deciding on which strings to show. As you can guess there are a lot and I mean a lot of Geeklog strings on the page. Showing all of them would reduce the user experience for the rest of the page. As they would, for example, have to scroll a lot just to log off. So instead of making some complicated algorithm to decide upon which 5 or 10 strings to show in the form, I decided to make my own little scroll function. Which looks like on the picture bellow.



Loosely related

My university hosed Summer school of innovation-GeekFEST2013, as one of the students who participated in the Sarajevo Startup weekend and one of the better students of the Computer Science and Engineering  departement I was called to tell them about my projects, the startup weekend and how it is to be a CS student in general. Being the Google fanboy I am I used the oportunity to promote Google Summer of Code, Android Developer Challenge, Android Camp and Summer Trainee Engineering Program (STEP). As well as the idea of contributing to open source/free software projects, and the mutual benefits of doing so.