How to format strings with zo strformat

From ESOUI Wiki

(Difference between revisions)
Jump to: navigation, search
(zo_strformat with <= 6 parameters)
 
Line 1: Line 1:
-
== zo_strformat with <= 6 parameters ==
+
== zo_strformat / ZO_CachedStrFormat with <= 6 parameters ==
The ESO API provides a very useful function called [https://github.com/esoui/esoui/blob/master/esoui/libraries/globals/localization.lua#L5 | 'zo_strformat'].
The ESO API provides a very useful function called [https://github.com/esoui/esoui/blob/master/esoui/libraries/globals/localization.lua#L5 | 'zo_strformat'].

Latest revision as of 18:57, 13 May 2019

Contents

zo_strformat / ZO_CachedStrFormat with <= 6 parameters

The ESO API provides a very useful function called | 'zo_strformat'. And it also provides a cached function for strings which are used more than once, called | 'ZO_CachedStrFormat'.


With it you can format strings with interpolation, pluralization, localization and many other features. It is also used together with ZO_LocalizeDecimalNumber (see below) to format human-readable numbers.

zo_strformat(format[, arg1[, arg2, arg3, arg4, arg5, arg6]])

The first argument is the actual string, and the following optional arguments are the parameters to be included in the string.
zo_strformat takes up to 6 parameters


The syntax '<<n>>' is used as placeholder for the replacement value, where the number 'n' is the position of the argument when you called the function.

d(zo_strformat("<<1>>, <<2>>, <<3>>, <<4>>, <<5>>, <<6>>, <<7>>", "one", "two", "three", "four", "five", "six", "seven"))
--> one, two, three, four, five, six
 
d(zo_strformat("Hello, <<1>>!", "player")) 
--> Hello, player!
 
d(zo_strformat("<<2>>, <<1>>!", "you", "Hey"))
 --> Hey, you!

Pluralisation

There's special syntax for pluralization.

zo_strformat("We've seen <<1[no examples/one example/$d examples]>>", 1) --> We've seen one example.
zo_strformat("We've seen <<1[no examples/one example/$d examples]>>", 0) --> We've seen no examples.
zo_strformat("We've seen <<1[no examples/one example/$d examples]>>", 3) --> We've seen 3 examples.

Modifiers

There's also another special syntax called modifiers. For instance, the modifier 'l' prepends "at the " to the value.

zo_strformat("I'm <<l:1>>.", "shrine") --> I'm at the shrine.

There's a myriad of modifiers you can use, check out the table below:

Modifier Effect
a Adds indefinite article in correct form ("a/an") if the value is not name (does not contain ^M, ^F, ^N). If used with 'm' (<<ma:1>>) it will add "some".
A Adds definite article if string is not name (does not contain ^M, ^F, or ^N).
c Converts the first character to lower case.
C Converts the first character to upper case, used to display names.
d Demonstrative pronoun; adds "this " if string is not a name (does not contain ^M, ^F, ^N).
D returns demonstrative pronoun
g Appends " of a". If string is a name it will append "'s" for singular, or "'" for plural
G Appends " of the". If string is a name it will append "'s" for singular, or nothing for plural
i Changes number to ordinal (1st, 2nd, 3rd, ..., 100th)
I  ?
l Prepends "at the ", used with locations.
L Prepends "to the ", used with locations.
m Multiplication, displays singular or plural according to the second argument. If you have a number on any other position, this will not work.
n Number to text (one, two, three, ..., twelve). Does not work for numbers higher then 12.
N Same as above. But the first letter is capital (One, Two, ..., Twelve)
o Possessive pronoun (subject). Returns "his", "her", or "its" according to the gender (^m, ^M, ^f, ^F, ^n, or ^N at the end of the string)
O possessive pronoun (object). Returns "his", "hers", or "its" according to the gender (^m, ^M, ^f, ^F, ^n, or ^N at the end of the string)
p Personal pronoun (subject). Returns "he", "she", or "it" according to the gender (^m, ^M, ^f, ^F, ^n, or ^N at the end of the string)
P Personal pronoun (object). Returns "him", "her", or "it" according to the gender (^m, ^M, ^f, ^F, ^n, or ^N at the end of the string)
r Reflexive pronoun. Returns "himself", "herself", or "itself" according to the gender (^m, ^M, ^f, ^F, ^n, or ^N at the end of the string)
R Number to roman numerals (I, II, III, ..., XII)
t Converts the first letter to upper case in all words that have more than 1 character (used by default to format item links).
T Converts the first letter to upper case in all words (including single letter words).
X Raw format (probably, it does not remove ^ control chars from strings, links are unchanged).
z Converts to lower case letters, works for special characters like ÁÉÄËÍÏ etc.
Z Converts to upper case letters, works for special characters like áäéëíï etc.
  1. Modifiers can be used in two forms: '<<Z:1>>' or '<<1{Z}>>'
  2. Instead of '<<2>><<m:1>>', it can be simplified to '<<2*1>>'

Almost all modifiers can be used together, so:

zo_strformat("<<C:1>> <<2>> <<tm:3>>.", "i have", 10, "blue colored item") -- I have 10 Blue Colored Items.

Translations

If you want to work with translations, there are some control characters that you can add to the end of a string:

^f Femine gender
^F Femine name
^m Masculine gender
^M Masculine name
^n Neuter gender
^N Neuter name
^p Plural
^P Plural name

Example:

zo_strformat("<<g:1>><<2>>.", "Peter^M", "item") -- "Peter's item."

Formatting and Localizing Numbers

The [| ZO_LocalizeDecimalNumber] function in [| libraries/globals/localization.lua] provides this function to format numbers nicely for humans.

Usage is simple: call this function on your number, and then pass the result through the zo_strformat function to localize it. If you do not, you will use English localization even in foreign languages.

zo_strformat("<<1>>", ZO_LocalizeDecimalNumber(1000000))
-- in English: 1,000,000
-- in German: 1.000.000

This also correctly handles decimals:

zo_strformat("<<1>>", ZO_LocalizeDecimalNumber(1000.987))
-- in English: 1,000.987
-- in German: 1.000,987

You should always use this method to format numbers that people will read.

Formatting currencies

You can format currencies via ZO_Currency_Format$Platform. Check the link for further info.

Coloring strings

You can color a string with handlers. The handler starts with |cXXXXXX and ends with |r.
The color definition takes the [| hex value.

local coloredString = string.format("|cFFFFFF%s|r %s", "White", "yellow")
 /script d(string.format("%s %s", "My", "string"))

Concatenating strings

LUA's operator for concatenating strings is ..

local string = "My " .. "string"

Run it from your ESO client via

 /script d("My " .. "string") 

Concatenating a lot of strings in LUA is expensive and can cause client crashes.
It is more performant to use string.format, because that executes the string operation in the c-backend and not in LUA:

local string = string.format("%s %s", "My", "string")

Lua uses [| patterns] instead of regular expressions.

 /script d(string.format("%s %s", "My", "string")) 


Concatenating lists

The wrong way

Everyone's first idea would be to do this:

local output = ""
for _, str in pairs(tbl) output = output .. ", " .. str end -- do not do this
d(output)

This is the least performant way to concatenate a table. While it will work for small amounts of data, it's bound to crash your client at some point.


the right way

table.concat

If you need to concatenate an unknown number of strings, or a large number of them, the best strategy is to use a table, and table.join:

function format_list()
    local out = {}
    for name, _ in pairs(...)
        table.insert(out, name)
    end
    return table.concat(out, " ")
end

ZO_GenerateCommaSeparatedList

To format a list of items, you should use [| ZO_GenerateCommaSeparatedList], which handles localization for you, much as ZO_LocalizeDecimalNumber does.

This takes an ordered table of strings, and outputs them as an appropriately localized list. In this example literal array-style tables are constructed, but in normal use they would be a table created elsewhere.

ZO_GenerateCommaSeparatedList({"one"})
-- one
 
ZO_GenerateCommaSeparatedList({"one", "two"})
-- one and two
 
ZO_GenerateCommaSeparatedList({"one", "two", "three"})
-- one, two, and three

You should always use one of these to format lists for display.


[1] Information originally provided by Garkin here http://www.esoui.com/forums/showpost.php?p=7321

Personal tools
Namespaces
Variants
Actions
Menu
Wiki
Toolbox