Awesome Kivy Revelations

We are using kivy for the GUI of the knit editor. It can be used to create Android, Windows, Linux, Mac and IOS apps. You can divide UI-design and code by using the kv language. In this blog post, I want to share some revelations I had when using kivy. This includes showing you how you can update translations automatically when the configuration changes and subtracting values. This awaits you:

Automatic Update of Translated Text in the Kivy UI

In projects like Django, there is the “_” function that allows translations of text. The implementation usually look calls a “gettext” function of some sort, which takes a string and returns its translation as a string. What we have in the kniteditor, is an observable translation, with the same interface:

def _(string):
    """Translate a string using the current language.
    :param str string: the string to translate
    :return: the translated string
    :rtype: str
    """
    return _locales.gettext(string)
_ = ObservableTranslation(_)

The difference is that the observable translation can be used like the “_” function but has additional methods that allow the UI to register and be notified when the language changes. When the language is changed, the global “gettext” is replaced by the “gettext” in the new language and, inthe last line, the observers are notified about the change.

def change_language_to(new_language):
    """Change the language to a language from the translations folder.

    :param str new_language: the language code of the new language
    """
    global _locales, _current_language
    _locales = gettext.translation(DOMAIN, _locale_dir,
                                   languages=[new_language])
    _current_language = new_language
    _.language_changed()

To see what this does, we can look at the whole implementation. I would like to give the whole picture, first, as it clarifies the context and discuss them below.

"""Observable Translations for kivy that change when the language changes.
The functionality of this module is highly inspired by
`kivy-gettext-example <https://github.com/tito/kivy-gettext-example>`.
"""
from kivy.lang import Observable


class ObservableTranslation(Observable):

    """This class allows kivy translations to be updated with the language."""

    def __init__(self, translate):
        """Create a new translation object with a translation function.
        :param translate: a callable that translates the text. 
          Even when the language is changed,
          it returns the text for the current language.
        """
        super().__init__()
        self._translate = translate
        self._observers = []

    def __call__(self, text):
        """Call this object to translate text.
        :param str text: the text to translate
        :return: the text translated to the current language
        """
        return self._translate(text)

    def fbind(self, name, func, args, **kwargs):
        """Add an observer. This is used by kivy."""
        self._observers.append((name, func, args, kwargs))

    def funbind(self, name, func, args, **kwargs):
        """Remove an observer. This is used by kivy."""
        key = (name, func, args, kwargs)
        if key in self._observers:
            self._observers.remove(key)

    def language_changed(self):
        """Update all the kv rules attached to this text."""
        for name, func, args, kwargs in self._observers:
            func(args, None, None)

__all__ = ["ObservableTranslation"]

The constructor takes the “_” function. When the object is called like a function, the “__call__” method is invoked, translating like “_”. If we only have these two methods, the observable translation works just like the “_” function.

“fbind” and “funbind” are the methods that are called when a translation is used in the kv language. They add and remove the observes from the list of observes.

“language_changed” walks through the observers and tells everyone of then to update. With this, you already have a updated translations when “change_language_to” is called.

Here is how you create a button in the kv language that uses the translation function:

#:import _ kniteditor.localization._
Root:
    Button:
        text: _("Load")

Updating the Translations From the Configuration

Ultimately, you want the translations to be changed, when the built-in kivy configuration changed. In the video, seconds, you have seen what it can look like.

LANGUAGE_SECTION = "language"
LANGUAGE_CODE = "current"
LANGUAGES = ["English", "Deutsch"]

class EditorWindow(App):

    """The editor window."""

    def build_config(self, config):
        """Build the configuration.

        :param kivy.config.ConfigParser config: the configuration parser
        .. seealso:: `Application Configuration
         <https://kivy.org/docs/api-kivy.app.html#application-configuration>`__
        """
        config.setdefaults(LANGUAGE_SECTION, {
            LANGUAGE_CODE: LANGUAGES[0]
        })

    def build(self):
        """Build the application."""
        self.update_language_from_config()

    def update_language_from_config(self):
        """Set the current language from the configuration.
        """
        config_language = self.config.get(LANGUAGE_SECTION, LANGUAGE_CODE)
        change_language_to(config_language)

    def build_settings(self, settings):
        """Create the applications settings dialog.

        :param  kivy.uix.settings.Settings settings: the settings 
          for this app
        .. seealso:: `Create a settings panel
          <https://kivy.org/docs/api-kivy.app.html#create-a-settings-panel>`__,
          :meth:`kivy.uix.settings.Settings.add_json_panel`,
          :mod:`kivy.uix.settings`
        """
        settings.add_json_panel(_('KnitEditor'), self.config,
                                data=self.settings_specification)

    @property
    def settings_specification(self):
        """The settings specification as JSON string.

        :rtype: str
        :return: a JSON string
        """
        settings = [
            {"type": "title",
             "title": _("KnitEditor")},

            {"type": "options",
             "title": _("Language"),
             "desc": _("Choose your language"),
             "section": LANGUAGE_SECTION,
             "key": LANGUAGE_CODE,
             "options": LANGUAGES},
        ]
        return json.dumps(settings)

    def on_config_change(self, config, section, key, value):
        """The configuration was changed.

        :param kivy.config.ConfigParser config: the configuration that was
          changed
        :param str section: the section that was changed
        :param str key: the key in the section that was changed
        :param value: the value this key was changed to
        """
        if section == LANGUAGE_SECTION and key == LANGUAGE_CODE:
            change_language_to(new_language)

“build_config” is calls when the application starts to fill the empty configuration with useful values.

“build” is called when the application creates its window, at this point in time, the translation is updated.

“build_settings” is called when the F1 key is pressed or the Android settings menu is activated. “settings_sepcification” is a JSON string used by kivy to build the settings.

“on_config_change” is called, when the configuration is updated. Through e.g. the settings dialog.

With these components together, you can have a updated language every time the language is changed. The video shows an application which uses this code.

Bonus Material: Kivy’s Update is Mighty

In the kv language, variables are accessed via identifiers and not via global variables. As such, the kv language can register every time a Property (like “StringProperty” and “ObjectProperty”) is used. It an register when they change. Thus you can automatically update formulas whenever a value changes.

in this example you can see how a value is subtracted but still, an automatic update is possible:

    Slider:
        min: 0
        max: 100
        value: 100 - other_slider.value

 

Credits

Thanks to Mathieu Virbel for the kivy-gettext-example. It was the basis of this work and an inspiration.

 

 

 

 

 

Language Localization for Engelsystem

Localization takes place when you adapt content to a specific location. In translation, it means that your content can be read by another in their native language with as much ease as if the information were written in that language to begin with. In other words, just translating a document does not mean that it has been localized. When it is your brand, information, or material at stake, it is important to understand the elements that separate a mere translation from the language localization necessary to maximize impact with your target audience.

Some Examples of Localized Content

Understanding excellent localization may be easier with some positive examples.

  • Google is the search engine of choice in much of the English-speaking world. It accounts for only one percent of the search market in China, however. Baidu gives Chinese users the look and feel that they understand. Has Google given up? Hardly, they are working on improving the localization of their content.
  • Many television and phone manufacturers compete for the French markets. Samsung is made in Korea, but they marketed themselves according to the French tastes and desires. The manufacturer stressed the artistic design and high definition of its televisions. Their phones were tailored to the French market with apps specifically designed for the French lifestyle and location of the users.
  • Packaging is very important to an American consumer, even with toiletries; it is not very important at all to Chinese consumers. Proctor and Gamble localized their product marketing for Crest toothpaste by reducing their packaging costs and focusing on the flavors, which the Chinese do value. The localization not only increased their market share but cut their costs by 50 percent.

Remember, the purpose of localization is to give your text or product the impression that they were designed or written specifically for that market regardless of the language, culture, or location.

Understanding the Localization Process in Translation

Within the world of translation, localization includes a number of critical elements such as:

  • Modification of grammar, punctuation, and lexical elements
  • Adaptation of formality and other culturally-based items of etiquette
  • Ensuring figurative language is replaced with localized idioms and metaphors
  • Making sure content is culturally sensitive and relevant
  • Aligning conversions such as money, time, dates, voltages, and so forth
  • Formatting numbers, values, and so on according to local variations
  • Verifying the text and format meet legal requirements

In order to localize content, the translator must have a comprehensive understanding of the culture, the language, and the specific field the information references. Note, in the list above, those cultural adaptations are as important to the translation as lexical and grammatical issues. Local sensitivities must be considered to avoid conflicts with culture, customs, or habits.

Some specific items that might be tailored to the local populace are references to political leaders or situations that are deemed offensive (think about China and Taiwan), animals (rats are looked upon favorably in china as is the chicken), flowers, gestures, shoes (wearing shoes inside can be taboo), gum (illegal in Singapore), meats (think about Kosher or Halal ideals, vegetarianism is also stressed in some places), smoking (banned for Sikhs), and bodily functions (what is funny or cute for some is offensive to others).

If your documents, texts, or project will be going to several locations and translated into several local languages, you might want to consider “internationalizing” it first. This is the process of highlighting or adjusting any questionable text or ideas in advance to save the translator’s time when preparing it for the local dialect. The process is most effective when done during the formulation stages of the document, but it can be done later as well. For papers that are going to be translated into multiple languages, the time and expense that could be saved through this step are tremendous.

Whether your documents go through an intermediary step or are translated straight to a local language, it is imperative that your translation service understands the importance of an exhaustive and thorough localization process.

09

When selecting translation services, one of the most important questions you can ask is whether or not you want your documents prepared for internationalization or localization.

Localization is the process of translating a document or project for use within a specific target market. Localization includes all of the components of translation required to meet cultural and linguistic adaptations of text. Localization can be accomplished from an original source text, or from a test that has been prepared for international translation.

Internationalization is the process of preparing a document or project to be used anywhere in the world and localized as necessary. The process of creating a document that is bothlinguistically deliverable and culturally sensitive for a worldwide audience is not easy or quick. Yet, when internationalization takes place during the initial stages of product development it is far easier than trying to work backwards, and a document that has been successfully internationalized can be quickly and easily localized.

Understanding the Elements

Some of the elements that are impacted during the internationalization or localization process include:

  • Formatting: Not everybody formats their date the same way. Time signatures are also not universal. Even numbers are not standard. Deciding where to put colons, commas, symbols and the like will make a huge difference in the readability of your final document.
  • Symbols/Abbreviations: English speakers often do not realize that their symbols are not universal. When symbols are used in text, they can take on many different meanings based upon the target language. Other times, the symbol may have no meaning at all, in which case the intent of the content will have been lost without a proper translation. Consider such a simple abbreviation as E. for east: since the German word for east is osten, east would be O. Even if we agreed to use metric vs imperial or American units, a square kilometer (sq km) would be a German Quadratkilometer or qkm.
  • Gender: English does not assign gender to most items, Spanish and French assign gender to just about everything, Japanese has gender, but also special rules for adults and children.
  • Graphics:Items that are just fine in one culture may be meaningless in another culture, or, worse, offensive and derogatory. For example, the stork delivers babies in many cultures; however, in Japan, a stork and baby will not have the same meaning. Colors also have different meanings in different cultures. Not everybody associates white with purity, weddings, and truth.
  • Legal Requirements: who has to sign documents, where do signatures go, are witnesses required, who is allowed to be a witness, and so forth. If you are doing business in an international community, these are essential elements of translation.

Why Internationalization or Localization is so Important

If your document is going to go to one region or local, and only one region or local, direct translation into the target text is the cheapest and most expedient way to translate your document. However, suppose you have a document that is going to be translated into 10, 20, even 50 different languages.

While you could hire a unique translator for each language independent of all others, another approach would be to go through the internationalization process. During this process, translators would create a master document that addresses the main elements that would be difficult to translate. They would standardize the elements that could be standardized, and highlight those ideas which are going to need more elaboration by a local translator. This way, when the translators who will be working on the localized documents start their translations, much of the groundwork has already been done for them.

When choosing a translation service, you will want to know the number of target languages. If you only have one or two, you may be better off going with a straight translation; however, if you are going to be addressing multiple languages (even many within the same family: Mexican Spanish, Puerto Rican Spanish, Argentinian Spanish, Andalusian Spanish) you may be able to save considerable time.

During the 3rd week of my Summer of Code, I’ve implemented localization on Engelsystem. Users can get more information on my previous blog post, here.

In the later weeks, other developers and I would be working on adding more languages to the system. Anyone who would like to work in the project are welcome. Developers can feel free to take up any issues they would like to work on just like any other open source projects.

Development: https://github.com/fossasia/engelsystem                                           Issues/Bugs:https://github.com/fossasia/engelsystem/issues

Language Localization on Engelsystem

During the 3rd  week of my Summer of Code, I worked on implementing Localization of different languages on the system and creating a different settings page for user and admin.

One of our goals is for Engelsystem to be a great experience for users worldwide. To achieve this goal we need to make some significant changes. The main reason of localization is that it can be used by different people with different native languages across the world and help them to understand the system better .

First, a little background.

Right now, Engelsystem has two localization systems available:

  • Deutsch
  • English

All of the current translations will be updated. We are also expanding the list of supported languages to as many as we can. Currently, I’ve implemented:

  • Bulgarian
  • Chinese- simplified
  • English UK
  • French
  • Hindi-IN
  • Hungarian
  • Irish
  • Punjabi-IN
  • Spanish
  • Tamil-IN

The tools used in implementing localization are poedit where we create the .po files .

For installing Poedit on Linux distro’s, users can use the following command in the terminal,

sudo apt-get install poedit

For Windows and Mac users, they can download the executable file here.

Steps to run Poedit in Linux/Windows/Mac:

  1. choose File → New Catalog.Enter the details in Translation properties like your email. Source code charset should be selected as UTF-8.Now the source path should be selected as (.) dot to tell Poedit to search for PHP files in the same folder.
    06
  2. In the source, there are three options ‘_’ , ‘gettext’ and  ‘gettext_noop’.Make sure all necessary functions are added and press OK.
  3. Now we can see the list of strings on left and their translated strings on the right.we need to install the necessary dictionary for this.
    07
  4. Save the file  with an extension ‘.po’ . 

    In Engelsystem, to implement the translated localization file we need to make the changes in the file,internationalization_helper.php

    $locales = array(
    ‘de_DE.UTF-8’ => “Deutsch”,
    ‘hi_IN.UTF-8’ => “Hindi”,
    ‘sp_EU.UTF-8’ => “Spanish”,
    ‘en_US.UTF-8’ => “English”
    );

    During the week 3 of my Summer of Code I also worked on creating different settings page for user and Admin. Earlier settings page for user and admin were same, providing same privileges to both of them. Now we have separate pages for both.

                                                                             User Settings
    Admin Settings
                                                                        Admin Settings

    In the later weeks, other developers and I would be working on adding more languages to the system. Anyone who would like to work in the project are welcome. Developers can feel free to take up any issues they would like to work on just like any other open source projects.

    Development: https://github.com/fossasia/engelsystem                                           Issues/Bugs:https://github.com/fossasia/engelsystem/issues