API Development

Dealing with multiple screens and multiple languages

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.