Reputation: 163
I'm developing an application using GWT (first-timer) and am now at the stage where I want to establish a central structure to provide actual text-based content to my views.
Even though it's obviously possible to define those text-values inline (using UiBinder or calling the appropriate methods on the corresponding objects), I'd be much more comfortable storing them in a central place as is possible using GWT's Constants
. Indeed, my application will only be available in one language (for now), so all-the-way i18n may seem overkill, but I'm assuming that those facilities might be best-suited for what I require, seeing how they, too, must have been designed with providing all (constant) text content in mind.
However, my application features several passages of text that are somewhat longer and more complex than your average label text, meaning they could span several lines and might require basic text formatting. I have come up with several ideas on how to fix those issues, but I'm far from satisfied.
First problem: Lengthy string values.
import com.google.gwt.i18n.client.Constants;
public interface AppConstants extends Constants {
@Constants.DefaultStringValue("User Administration")
String userAdministrationTitle();
// ...
}
The sample above contains a very simple string value, defined in the manner that static string internationalization dictates (as far as I know). To add support for another language, say, German, one would provide a .properties
file containing the translation:
userAdministrationTitle = Benutzeradministration
Now, one could easily abuse this pattern to a point and never provide a DefaultStringValue
, leaving an empty string instead. Then, one could create a .properties
file for the default language and add text like one would with a translation. Even then, however, it is (to my knowledge) not possible to apply line-breaks for long values simply to keep the file somewhat well-formatted, like this:
aVeryLongText = This is a really long text that describes some features of the
application in enough detail to allow the user to act on a basis
of information rather than guesswork.
Second problem: Formatting parts of the text.
Since the values are plain strings, there isn't much room for formatting there. Instinctively, I would do the same thing as I would if I were writing the text straight into the regular HTML document and add HTML-tags like <strong>
or <em>
.
Further down the road, at the point where the strings are read and applied to the widget that's going to display them, there is a problem though: setting the value using a method like setText(String)
causes that string to be escaped and the HTML-tags to be printed alongside the rest of the text rather than to be interpreted as formatting instructions. So no luck.
A way to solve this would be to disect the string provided by the i18n file and isolate any HTML-tags, then baking the mess together again using a SafeHtmlBuilder
and using that to set the value of the widget, which would indeed result in a formatted text being displayed. That sounds like much of an overcomplication though, so I don't quite like that idea.
So what am I looking for now, dear user who actually read this all the way through (thanks!)? I'm looking for solutions that don't require hacks like the ones described above and provide the functionality that I'm looking for. Alternatively, I welcome any guidance if I'm on the wrong path entirely (GWT first-timer, as I mentioned one eternity ago :-) ). Or basically anything that's on topic and might help find a solution. An acceptable solution, for example, would be a system like the string value files used in Android development (which allows for HTML-styling the texts but obviously requires the containing UI elements to accept that).
Upvotes: 1
Views: 127
Reputation: 64561
If you're using UiBinder, i18n support is built-in. Otherwise, use Messages and Constants and use the value with setHTML rather than setText.
For long lines, you should be able to use multiline values in properties files by ending lines with a backslash.
Upvotes: 3
Reputation: 41100
Fortunately, there is a standard solution that you can use. First, you need to create a ClientBundle:
public interface HelpResources extends ClientBundle {
public static final HelpResources INSTANCE = GWT.create(HelpResources.class);
@Source("account.html")
public ExternalTextResource account();
@Source("organization.html")
public ExternalTextResource organization();
}
You need to put this bundle into its own package. Then you add HTML files to the same package - one for each language:
account.html
account_es.html
organization.html
organization_es.html
Now, when you need to use it, you do:
private HelpResources help = GWT.create(HelpResources.class);
...
try {
help.account().getText(new ResourceCallback<TextResource>() {
@Override
public void onError(ResourceException e) {
// show error message
}
@Override
public void onSuccess(TextResource r) {
String text = r.getText();
// Pass this text to HTML widget
}
} catch (ResourceException e) {
e.printStackTrace();
}
You need to use HTML widget to display this text if it contains HTML tags.
Upvotes: 4