Appcelerator Blog

The Leading Resource for All Things Mobile

Dealing with multiple screens and multiple languages

0 Flares 0 Flares ×

In the upcoming 1.5, we’re adding some additional functionality to help you improve dealing with the various screens (thank you Android and RIM) as well as handling applications for a variety of languages around the world. These are two big areas that have needed much improvement and we’ve made some big changes (that landed this weekend in Git) to start to make the easier for you.

Internationalization and Localization (i18N)

Up until to date, there wasn’t a built-in Internationalization and Localization framework per se in Titanium. We’ve had numerous different approach to handling this, mainly through meta frameworks on top of Titanium. However, for 1.5, we’ve brought this in as a first-class citizen in Titanium. We’ve also made is cross-platform out of the box to help you deal with the various types of devices and specifics around how each platform handles it differently.

We’re adopting a new directory (optional) in the project root, aptly titled i18n. Inside this directory, you’ll create one or more directories for each locale/language combination you’re localized for. For example, for English, you could create a directory titled “en”. Or, for US english, you might create one titled “en-us”.

Inside this directory, you’ll create an XML file titled “strings.xml”. Save it either as UTF-16 or UTF-8 and then create your strings like so:

< ?xml version="1.0" encoding="UTF-8"?>

Hello

My name is %s

Now, you might want to provide this localization also in Spanish. Let’s create another directory, titled “es” and create the following file:

< ?xml version="1.0" encoding="UTF-8"?>

¡Hola

Mi nombre es %s

Now, this will automatically create the appropriate platform-specific localization files/bundles/etc when your application is compiled.

You have a couple of options for handling these strings in your application code.

First, you can use the new built-in L function. This is a short-cut to the longer Titanium.Locale.getString method.

alert(L("welcome"));

alert(Ti.Locale.getString(“welcome”));

You’ll also sometimes need to format your strings. We’ve provided some new helper functions to make it easier to do that as well. For example, you can perform formatting for example:

var message = String.format(L("format_test"),"Jeff");

String.format takes a string formatted using IEEE printf specification.

You can retrieve the current locale using Ti.Locale.currentLanguage property.

Dealing with multiple screen sizes and varying layouts

We’ve been working on various techniques for how to deal with the differences in platforms, screen sizes and densities. As Android continues to grow and as we expand to new devices, it’s becoming apparent we need to provide better capabilities in this area and we’re making the first step of several in this direction.

In our experience and looking at all the source code of applications that come through support, it’s apparent that more than 60% of your time and code is spent in layouts. Constructing the UI can be rather easy in Titanium but can become tedious as you’re trying to make it work seamlessly and natively across different screens. It’s also hard to reuse layouts and code as well as make it portable if you’re not careful and thoughtful from the beginning.

We’re introducing a new native framework built-in that we’re calling JS Stylesheets or JSS. They’re are syntactically the same as Cascading Stylesheets (CSS) for the most part, but we’re calling the JSS to not confuse or interfere with HTML5 CSS you might want to include in your application.

Titanium does special stuff now with the introduction of JSS. First, you’ll create a file with the name of your context and the jss file extension and place it in your Resources directory. The Titanium compiler knows how to compile this file into special code.

Let’s give you a simple demonstration on how you’d use it in app.js. First, let’s start out by creating the new JSS-powered app.js file that creates a window with a simple button.

var window = Ti.UI.createWindow();

var button = Ti.UI.createButton( { id : "b" } );

window.add(button);

window.open();

OK, much less code. Now, let’s create the layout/styling of the button by creating a file named app.jss:

#b

{

width:100;

height: 40;

title: “Hello”;

}

Now, we’ve externalized the layout/styling from the actual business logic. We have some very specific ideas on how to take this to the next level, including some layout tools, however, we’re going to stop there for 1.5 and make this solid first.

So, you’ll be able to also do some advanced layouts by naming convention. Say, you have a high-density device you want to have the sizes or positioning different. In those cases, the business logic of the application is the same. No more “if than else” in your code. Let’s do it with compile time JSS files.

Create a file named app.android.high.jss.

#b

{

width:200;

height: 45;

title: "Hello";

}

In this case, we’re saying on an Android high-density device, you a different set of stylings for the button with the id “b”.

You can also use CSS keywords like @import to import other files to combine them and to make it easy for meta frameworks on top of Titanium.

@import “common.jss”;

So, how about internationalization and JSS? That’s easy with locale-aware keywords like titleid:

#b

{

width:200;

height: 45;

titleid: “button_b”;

}

Beyond 1.5, we’ll have a lot more capabilities beyond as this is just one of the many ways we’re going to make it easier and faster for you to use Titanium in your cross-platform applications.

We’d love your feedback and ideas, too.

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×

19 Comments

  1. Ben

    Will this be rolled into the next Blackberry beta?

  2. You might want to rethink that name — the JavaScript Style Sheets spec, circa 1996: http://www.w3.org/Submission/1996/1/WD-jsss-960822. 😉

  3. when is 1.5 going to drop so we can test out the language support?

    thanks!

    rocksteady,
    danno~

  4. You wrote that the *.jss files go into the Resources folder – what if we organized our files in different sub-folders? Is the compiler globally looking for the specific *.jss file or do you have to put the file next to the *.js?

    • @Dominik – yeah, you can put them in any subfolder too. The only limitation (right now) is that it will map the base name of the file when it attempts to resolve any stylesheets. So if you opened a window in “subfolder/foo.js” it would look for “foo.jss” (regardless of subdirectory). We might have to allow relative paths but we’re trying to keep it simple.

      @Danno – 1.5 probably drops in early September timeframe.

  5. @Jeff: Thanks! Another question that crossed my mind: You said it’s basically CSS for the most part.
    You are demonstrating an id-selector, will class-selectors also be available?

  6. @Dominik – yes, both class and ids selectors will work.

  7. Vic

    Nice additions, thanks. However I would have rather seen the localization done in javascript instead of xml. This would probably be easiest for most developers because everything else except the tiapp is done in javascript. Regular js objects with key value pairs would require less markup as well.

  8. Sebastian

    Wow, these are great news! Do you know a good editor for the localization XML files? We are currently using POEDIT for our localized website, but I think that is not capable of saving as XML. Thanks for the help & keep up the great work!

  9. Matt

    Looking good.

    So for localisation & using the titleid in JSS, how would I do a substitution at the same time, i.e. String.format(L(“format_test”),”Jeff”);

    Also, I presume you’re pulling the language from the handset setting? And if a specific locale isn’t supported it’ll default back up to ‘en’, or maybe ‘en-US’, or is that definable?

    In some ways I don’t like the multiple sub-folder approach to the language layers, but I guess you could put other resources in each folder (like localised graphics). I just find it tidier (on my localisation framework I built for Titanium) to have localisation files in the same folder & suffix them like whatever_i18n.js, and whatever_i18n_fr.js. It makes it really easy to open all the localisations without having to go into multiple sub-folders, hunting out the files.

  10. Sindre

    Why aren’t you using JSON for the localization?

    XML is not very JS. JSON or even pure Javascript would fit much better, and would not be so verbose.

    Example:
    {
    “welcome”: “Hello”,
    “format_test”: “My name is %s”
    }

    About the JSS, will you support floating and fixed positioning?

  11. Nice one Jeff,

    Making screens consistent across an app does indeed take up a large amount of time. Looks like that’ll be an enormous help speeding-up the process there.

    cheers,
    Chris.

  12. This is fantastic! Can’t wait to see the details on JSS. Hopefully LESS or SASS can be modified to support JSS. Hmm, sounds like a potential project to work on …

  13. Tim

    These are both great additions and I can’t wait. But I will add my vote to those suggesting something other than XML: JSON, js objects, etc.

  14. Very nice additions !

    I’ve also a little question about multiple size capability : can we create as jss files as we want ?

    Thanks for reply :)

  15. John Holman

    A severe language-related bug has just been brought to my attention in all iOS versions of Titanium. Text Areas cannot receive input from the iPad/iPhone PinYin Chinese keyboard. I don’t know if this extends to the traditional Chinese keyboard or other language keyboards as well.

    This is very easy to test. The symptoms are that letters disappear as fast as they are typed in – some kind of automatic backspace is being inserted.

    Once again customers are asking for refunds because the core functionality of native controls is not there.

    regards,
    JH

  16. Jag

    Hi Jeff,
    This is a great addition and I look forward to it. I hope 1.5 has many improvements, specifically Event Handling, zIndex..etc. which are the fundamentals to creating and maintaining layouts.

  17. obaid

    I have put i18n folder in app/assets/i18n/en/strings.xml as per guide and also I have declared the code in .tss and also in views.xml file in this way

    i18n consists of

    Username_Ar
    Password
    Login
    Members List
    Organizations List
    Membership Number
    real_estate

    and view.xml

    And also I have tried to put the code in .tss file

    “#password_label”:{
    font:

    { fontSize:12 }
    ,
    top: 300,
    left: 100,
    height: 30,
    text:L(“password”)
    }

    But there is no success instead, the mobile view is removing that particular text as i have displayed in the image. (3 brown dots must have ‘username’,’password’ and password) but its empty.

    Check this screenshots

    https://jira.appcelerator.org/secure/attachment/51472/3.png
    https://jira.appcelerator.org/secure/attachment/51473/4.PNG

    issue already raised:
    https://jira.appcelerator.org/browse/TC-4754

  18. Pretty! This was a really wonderful article. Thank you for
    providing this information.

Comments are closed.

Sign up for updates!

Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
Get in touch
computer and tablet showing Appcelerator software
Start free, grow from there.
0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×