Showing posts with label GeekFEST2013. Show all posts
Showing posts with label GeekFEST2013. Show all posts

Sunday, July 14, 2013

So came functionality

The brief update:
It makes me very sad that all my work for this week can be put in one sentence: "You can vote translations and submit translations now". There it is, all of it in one sentence.

Guidelines and Progress bar

As I added stuff to the plugin I became aware that it might cause confusion, so I added guidelines into the mix. It is a link next to the plugin name and will basically just show a static list of what I think are important instructions.
The other thing, not really necessary is the progress bar. The red-ish thing under the language name. I thought it would be nice to see how much of the language is translated. Since this is a clean start the progress bar is all red but it could look something like this (in the future)



There are a few other visual tweaks to the plugin but those are related to the functionality while this is purely for the appearance so they will be presented bellow.

Not visible code changes

I have cleaned up the code a bit. For one I realized that the creation of the translation form is getting too 'heavy' for the JS. So this part is moved to a PHP script. Additionally the code is a bit updated to improve performance and ease further data manipulation. Some of the files are moved from the Plugin folder to the Public_HTML folder. I changed the JS code for the form slider. Now it uses a bit more jQuery (which means that it also works much better) One problem still persists, I can't seem to get the $_TABLE['translations'] syntax to get working. This is another beautiful feature of Geeklog. It will allow the CMS user to add prefixes to their tables and developers can then refer to their tables using the Geeklog interface, I probably missed something there and fixing this is on the top of my 'to do' list.
However the plugin went from 1 table up to 3. 1 table for the translations. 1 table for formatted original language strings where Don't have an account yet?  Sign up as a <a href=\"{$_CONF['site_url']}/users.php?mode=new\" rel=\"nofollow\">New User</a> will be saved as Don't have an account yet?  Sign up as a <tag>New User<tag> , the <tag> values will also be saved as a JSON object, and of course the variables inside the tags will be saved - {"html":["<a href=\\\"{VAR}\/users.php?mode=new\\\" rel=\\\"nofollow\\\">","<\/a>"],"vars":["$_CONF['site_url']"]}.
Later on when the assembling of the new language file is done these values will be moved back to their strings. Finally the last table is for votes.

Submitting translations

A faulty input

As we are talking about translations here there is no way (at least  I have not figured out any jet) to validate the user input. It literally can be anything, except in the case of translating strings such as Comments (<var>).  These the plugin will validate. Again in some cases the language grammar might be different so the actual place of the <var> will not be the same, but what I can do is count the occurrences of <var> and <tag> pseudo tags. It looks something like this:


After trying to submit this the user would get a warning. If for example I try to submit a'faw  as a translation for Comments (<var>) I will get an error. (According to VLD a'faw is Vulcan for  comment)


The first part of the 'message' is at the beginning of the form. Indicating that there has been an error, what the error is and in which place(es).
If there had been valid inputs those would have been processed regardless of the faulty one. This could look as such: 
In the second case the successful translation is processed and the input box is removed, the faulty input is marked. The phrase postì säplltxevi is Na'vi for Post a comment at least according to these guys.
If you wonder why the progress bar did not change - I just submitted 1 translation (as can bee seen in the plugin interface) the Geeklog language arrays have around 1700 strings in total and the rounding is done on 2 decimal places.

Voting

The voting interface has been show last week. It is basically 2 buttons next to the proposed translation.
Now the voting actually works. As proposed by +Dirk Haun the vote can be changed.
If another user now came to the same page they could see my translation (in the general case the translation with the most up votes is shown). As the user did not vote on this translation jet the vote buttons both have reduced opacity. However as soon as the user does vote on the translation the vote he gave will be highlighted. The new user can also submit their own translation. In any case if a translation reaches a certain number of negative votes the translation is removed from the database. Currently I have set this limit to be a vote count of -5. (every up vote increases the value of vote count by 1, every negative decreases it by 1)


In summary I think the hardest part of the project is done. That was building this interface, not because building a HTML form is a hard task but finding the correct strings on the page was hard. Especially if you try not to be intrusive on the original code base and dare I say this I have done. Geeklog developers will not ever have to worry about the plugin, except in one case: when adding to the language files, an array element has to be in exactly one line.


Not related

I finally got the pictures from my presentation, here is one. I had some feedback and it seems my future colleagues liked what I had to say.


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.