Can someone please explain the xliff:g for strings/localization.
I understand that xliff:g is not supposed to translate anything inside the <> things, but I'm confused how exactly I'd use this in code.
An example I have in my case is the practice spanish translations that I have has:
<string name="order_quantity">Cantidad: <xliff:g id="quantity" example="2">%d/xliff:g</string>
I am now trying to get localized strings with xliff:g to work.
What is id here and what does it do? And what does it call?
Also what is the %d and what does it do? What is the point of example? Also, how would I call that into code, if at all?
Why can't someone just do the following code to insert the following xml:
<string name="quant">Quantity: </string>
into java like so:
getString(R.string.quant) + quantity
so that way it concactenates the quantity variable into the getString?
Minor typo in your example, there should be a closing tag:
<string name="order_quantity">Cantidad: <xliff:g id="quantity" example="2">%d</xliff:g></string>
The id attribute is just used to identify what the substitution parameter represents (in your case, it represents the quantity). It's as you said, a note, and not actually used programmatically.
That said, in Android Studio, if you have Code Folding enabled for strings, it will substitute in the ID when it shows the collapsed string. You'd see something like this:
// This...
mTextView.setText(getString(R.string.order_quantity, 2));
// Will show as this when folded:
mTextView.setText("Cantidad: {quantity}");
As for your second question, why not just use string concatenation? In other languages, the substitution may not go at the end of the string. You could have something like:
values/strings.xml
<string name="order_quantity">%d items</string>
values-es/strings.xml
<string name="order_quantity">Cantidad: %d</string>
So you can see that in this case, simply appending the strings together would not give you a valid result.
%d is used to represent a part of memory as an integer.
It's most commonly used to print some number to standard output, as follows:
#include <stdio.h>
int main()
{
int n = 42;
printf("The answer to life, universe and everything is %d", n);
return 0;
}
Unlike Java, where you simply concatenate numbers and strings etc., C uses this %something to indicate what is being written. %d indicates, that for example in the printf(), after the comma there will be an argument (in our case it's n), which should be represented as an int.
Refer to List of all format specifiers in C programming for a complete list of format specifiers
Also refer to Official Android Developers Documentation
Related
It is known that Androd string resources support xliff namespace to annotate non-translatable string formatting placeholders, like this
<string name="max_file_size_exceeded_template">File
<xliff:g example="some_image.jpg" id="file_name">%1$s</xliff:g>
is too big and could not be uploaded.</string>
It helps translators to undestand what parts of string should not be modified. But sometimes I need to annotate some strings max length it they are used in UI control with limited size. What I want is add text length limit to warn translators about this. Something like max-length="24" max-lines="2" length-unit="char" Maybe, xliff supports such thing or it can be achieved in other way.
I use Weblate for translations if it matters.
You can set this in Weblate, the Andoid format does not support this directly.
Click on edit (pencil) icon next to flags on the string.
Enter max-length:LENGTH as check flag.
See also https://docs.weblate.org/en/latest/admin/translating.html#additional-information-on-source-strings
Just a little while ago, I was looking around on GitHub, and I found there were some double quotation marks beside the string value in some strings.xml just like this:
<string name="ClipMmi" msgid="6952821216480289285">"来电显示"</string>
In short I mean this
"来电显示"
For full example please click here.
I don't know what is the "" used for? Because if I remove the "" beside the string value (e.g. "来电显示" change to 来电显示), the output won't change any more, both "来电显示" and 来电显示 will print 来电显示 as the output.
So does the quotations make any sense here?
It makes sense on languages that are using simple quotes '.
If simple quotes aren't escaped like this, \', Lint will detect an error.
Using double quotes at the start and at the end of a string value will allow you to omit these backslashes.
There may be other purposes I didn't discovered yet.
I have a configuration.xml file which I hold all the (yep, you guessed it!).. configuration strings and values and stuff.
One of those values is a string which is an oauth client id, and it has a hyphen..
<string name="server_clientid">5467656-blahblahblah.apps.googleusercontent.com</string>
Now I get the warning message..
Replace "-" with an "en dash" character (–, –) ?
Ok fair enough, but if I escape with this then the client id is not valid when I fetch it within the app. I can't use & #8211; basically. How do I get around this?
You wrap your values in
<![CDATA[ ]]>
which stops the parser from parsing the contents. E.g.
<string name="server_clientid"><![CDATA[ 5467656-blahblahblah.apps.googleusercontent.com ]]></string>
You can also suppress the lint warning (which is false since the dash is not used in a typographical context):
<resources xmlns:tools="http://schemas.android.com/tools">
...
<string name="server_clientid" tools:ignore="TypographyDashes">5467656-blahblahblah.apps.googleusercontent.com</string>
The "n dash" (–, –) and the "m dash" (—, —)
characters are used for ranges (n dash) and breaks (m dash). Using
these instead of plain hyphens can make text easier to read and your
application will look more polished.
Replace smaller "-" with bigger "–". You are good to go.
I am using Plural strings provided by android-sdk. I have used following code to create a plural string:
<plurals name="valuestr">
<item quantity="zero">Choose a value.</item>
<item quantity="one">%d unit.</item>
<item quantity="other">%d units.</item>
</plurals>
Java Code:
textView.setText(getResources().getQuantityString(R.plurals.valuestr,0,0));
When i am setting any value other than '0', this is working fine but when i am setting '0' it is showing '0 unit.'.
Please help!
Update
While searching more on the internet i came across a workaround which uses java.text.MessageFormat class:
<resources>
<string name="item_shop">{0,choice,0#No items|1#One item|1<{0} items}</string>
</resources>
Then, from the code all you have to do is the following:
String fmt = resources.getText(R.string.item_shop);
textView.setText(MessageFormat.format(fmt, amount));
You can read more about the format strings in the javadocs for MessageFormat
A post was recently made on G+ about this.
In short, it is because this will not pick the closest match by Integer ( 0 = zero), but because it will look for the best grammatical pick.
In your example, you use units.
The correct usage would be;
0 units
1 unit
2 units
Making, zero equal to pretty much any other quantity above 1
Read the full story here;
https://plus.google.com/116539451797396019960/posts/VYcxa1jUGNo
Plurals defined in <plurals> sections of resource files are only to be used for a grammatical distinction with respect to singular/plural strings. You should not use them for other display logic, as you did. You should add some checking logic in your code instead.
The Android developer's guide clearly states this:
Although historically called "quantity strings" (and still called that
in API), quantity strings should only be used for plurals. It would be
a mistake to use quantity strings to implement something like Gmail's
"Inbox" versus "Inbox (12)" when there are unread messages, for
example. It might seem convenient to use quantity strings instead of
an if statement, but it's important to note that some languages (such
as Chinese) don't make these grammatical distinctions at all, so
you'll always get the other string.
Your workaround - although working technically for your current implementation - does not appear like a clean solution either, in my opinion. Future business requirements may make it necessary to include more sophisticated logic than just displaying a different text. Or you may have a generic "no items selected" string in your resource file used at different locations, which could be reused only if you did not stick to your solution.
Generally, I would avoid using two different formatting techniques (String.format style formatter %d vs. MessageFormat style formatter {0} and pick one that you'd stick to in your whole application.
I'm trying to store a fully qualified url, with also query params:
www.miosito.net?prova®=bis
but it's causing a problem because ® is similar to ® entity and android tell me that and html entity is not well written.
I need this because every locale uses a fully different set of url query param.
I tried with [[CDATA[.. ]] but this syntax disliked by xml parser.
The problem is not with &req but with & itself. For XML/HTML you would have to use & entity (or &), but for URLs you should rather URL-encode (see docs) strings, and in that case said & should be replaced with %26. So your final string should look like:
www.miosito.net?prova%26reg=bis
Store it like this:
<string name="my_url">"www.miosito.net?prova®=bis"</string>
Where & is the XML equivelant of the ampersand symbol &.
Percent encoding may do the trick: http://en.wikipedia.org/wiki/Percent-encoding
You'll basically have something like this: www.miosito.net?prova%26reg=bis
You can enclose your url in double quotes, something like :
<string name="my_url">"www.miosito.net?prova®=bis"</string>
This is a recommended way to enclose string resources in Android.
Update 1 : Have a look at the following link for more info :
http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
Update 2:
#WebnetMobile.com : Correct, indeed :)
'&' is being treated a special character by xml and enclosing in quotes doesn't work. I tried out
www.miosito.net?prova%26reg=bis
and it didn't work out either. I even tried enclosing it in quotes but still didn't work. Am I missing something ?
Meanwhile, the following does work :
<string name="my_url">www.miosito.net%1$sprova%2$sreg=bis</string>
and then in code :
Resources resources=getResources();
String url=String.format(resources.getString(R.string.my_url),"?","&") ;
The '%1$s' and '%2$s' are format specifiers, much like what is used in printf in C. '%1$s' is for strings, '%2$d' is for decimal numbers and so on.