Nested Message Data
If you're using linked message, you may want to pass a data to the linked message. For example, you have a message like this:
{
"greet": "Welcome to GM-I18n, {name}! [[greet2]]",
"greet2": "Hope this library useful for you, {who}!"
}
And then you get the static message or create a message reference like this:
// assume the system is initialized on global variable
// static message
my_msg = i18n_get_messages("greet", {
name : "John",
who : "John"
}, "en");
// dynamic message
global.ref_msg = i18n_create_ref_message("global.ref_msg", "greet", {
name : "John",
who : "John"
});
The my_msg
and global.ref_msg
variable will return the same message:
Welcome to GM-I18n, John! Hope this library useful for you, {who}!
The {who}
is not replaced, even though we've passed the data. Why is that? It's because the data is not passed to the linked message. The data is only passed to the main message (greet
), but not to the linked message (greet2
).
- It's confusing. Should we pass the
data
to the main message, or to the linked message? What if we want to pass different data to the linked message? - It's dangerous. What if the linked message is used in another message, but with different
data
? It will cause a data collision. For example, in the example above, what if we're using the same placeholder ({name}
) in thegreet2
instead of{who}
, but with different data? - It's unnecessary. You can just pass the
data
to the linked message directly, without passing it to the main message first. - It's not always needed. The linked message can be used without any
data
, and it will still work as expected. - It's not consistent. The linked message should be treated as a separate message, not as a part of the main message.
{0}
, {1}
, {2}
, etc.) is not affected by this issue, because the indexed data doesn't support linked message. You can still pass the data to the linked message, but you need to do it manually.
Data in Linked Messages
As I mentioned before, the linked messages should be treated as a separate message.
To pass the data
to the linked message, you need to use a child
or child_*
key in the main message data.
// assume the system is initialized on global variable
// static message
my_msg = i18n_get_messages("greet", {
name : "John", // interpolate {name} in "greet" message
child : { // act as the "data" for the linked message
who : "John" // interpolate {who} in "greet2" message
}
}, "en");
// dynamic message
global.ref_msg = i18n_create_ref_message("global.ref_msg", "greet3", {
user : "Reader of GM-I18n", // interpolate {user} in "greet3" message
child : { // works the same as the static message
user : "John" // using the same key (`user`) is fine, because it's in different "scope"
}
});
That's the basic of passing data to the linked message. Are you ready for the next section?
Default Child Data
The child
key is used to pass the data to all of the linked message in the main message. It's good choice if you want to pass the same data to all of the linked message.
Think the child
key as an else
block in an if-else
statement, or a default
keyword in a switch
statement. You can override the default data by using the child_*
key. But we will discuss about it in the next section.
// assume the system is initialized on global variable
// applicable on both static and dynamic message
// in this example, we will only focus on the data passing
// no data passed
npc1 = i18n_get_messages("dialog.npc_1", , "en"); // return the raw string in `dialog.npc_1`, because the linked message is not activated
npc1 = i18n_get_messages("dialog.npc_1", {}, "en"); // remember, you still need to pass the data (struct), even if it's empty, to activate the linked message
// "Do you have 20 apples? How about trading them with me for 5 bamboos? " (in English)
msg_arr = [
i18n_get_messages("welcome", { // "Selamat datang di desa Sukamakan, John! Harap betah di desa ini!" (in Indonesian)
village: "Sukamakan",
name: "John"
}, "id")
];
// only pass to the child message
npc2 = i18n_create_ref_message("npc2", "dialog.npc_2", {
child : { // pass the data to the child message (`item.apple_trait`, `item.bamboo_trait`, and `item.potion_trait`)
adj : "Shiny" // "adj" is the placeholder in those child messages
} // all of them will be replaced with "Shiny"
});
global.npc3 = i18n_get_messages("dialog.npc_3", {
child : ["Fresh"] // using indexed data? why not? GM-I18n system accepts both named and indexed data in the `child` key
}); // it's because the system treats the `child` key as a separate message
// with pluralization
my_apple = 10;
buy_apple = 5;
confirm_buy = i18n_create_ref_message("confirm_buy", "shop.buyable", {
plural: function(val) {
return (val > 1) ? 1 : 0; // explicitly return the index value
},
plural_value: my_apple, // the system will do the pluralization first before processing the `child` key
suffix: "s",
child: { // pass the data to the child message (`shop.template_1`)
count: buy_apple, // will return "Are you sure you want to buy 5 Apples?"
item: i18n_get_messages("item.apple")
}
});
// nested child
global.npc_dialogs = {
npc4 : i18n_create_ref_message("global.npc_dialogs.npc4", "dialog.npc_4.num_1", { // activate the `dialog.npc_4.num_2` linked message
child : { // activate the `welcome` child message
child : { // pass `village` and `name` to the `welcome` message
village: "Sukamakan", // and activate the `welcome_2` grandchild message
name: "John"
}
}
})
}
child
key as deep as you want, but it's not recommended to have a very deep nesting, because it can be hard to manage the data. Just look at the example above, it's already 3 levels deep. It's already hard to read, right?plural
key (with plural_value
) in the child
data, it will only executed once (when the message is created), and can't be updated later using i18n_update_plurals()
function.Specific Child Data
The child
key is used to pass the data to all of the linked message in the main message. But, what if you want to pass different data to different linked message?
You can use the child_*
key to pass the data to the specific linked message. The *
is the key of the linked message. For example, if you want to pass the data to the greet2
linked message, you can use the child_greet2
key.
// assume the system is initialized on global variable
// applicable on both static and dynamic message
// in this example, we will only focus on the data passing
// activate the linked message feature, but not passing any data to the linked message
msg_struct = {
my_msg : i18n_get_messages("welcome", { // "Selamat datang di desa Sukamakan, Agus! Harap betah di desa ini!" (in Indonesian)
village: "Sukamakan",
name: "Agus"
}, "id")
};
// only pass to the child message
npc2 = i18n_create_ref_message("npc2", "dialog.npc_2", {
// specific child data
child_item_apple_trait : { // pass the data to the `item.apple_trait` linked message
adj: "Bad" // "adj" is the placeholder in the `item.apple_trait` message
}, // the {adj} placeholder in this linked message will be replaced with "Bad"
child_item_bamboo_trait : {
adj: "Premium"
},
// default child data
child : { // will only be applied to the `item.bamboo_trait` and `item.potion_trait` linked messages
adj : "Shiny" // the {adj} placeholder all of those non-specified child data will be replaced with "Shiny"
} // "Welcome to my shop! Take a look at this Bad Apple, Premium Bamboo, and Shiny Potion. Do you want to buy any of them?"
});
global.npc3 = i18n_get_messages("dialog.npc_3", { // for specified child data in indexed data message, you can just use a diferent index value
child : ["Fresh", "Beautiful"] // {0} is "Fresh", {1} is "Beautiful"
}); // "Ah, how about Fresh Chicken and Beautiful Duck then?"
// with pluralization
my_coins = global.coins; // assume you have declared `global.coins` somewhere in your code
buy_resc = "Copper Coin";
confirm_buy = i18n_create_ref_message("confirm_buy", "dialog.npc_5", {
plural: function(val) {
return (val >= 500) ? 1 : 0; // explicitly return the index value
}, // use form 2 (index 1) if the player have 500 coins or more, otherwise use form 1 (index 0)
plural_value: my_coins,
resc: buy_resc,
// pass a data to `item.bamboo_trait` child message
child_item_bamboo_trait: {
adj: "Premium"
},
// pass a data to other child message
child: {
adj: "Legendary"
}
});
// nested child
global.npc_dialogs = {
npc4 : i18n_create_ref_message("global.npc_dialogs.npc4", "dialog.npc_4.num_1", { // activate the `dialog.npc_4.num_2` linked message
child : { // activate the `welcome` child message
child_welcome : { // pass `village` and `name` to the `welcome` message
village: "Sukamakan", // there's no `child` key, but it still work as long as you use the `child_*` key
name: "John"
}
}
})
}
child
and child_*
keys at the same time, either static or dynamic message. Use those as efficient as possible. As you can see in the example above, the dot separator (
[key].[subkey]
) of the message key used in child_*
is replaced by underscore ([key]_[subkey]
). You need to follow this rule to make sure the child_*
key works properly. The
child_*
key can be defined in the main message or in the child message. You can even define 2 or more child_*
key, like you're using if-else
statement. You can also use the
child_*
key in the child message or deeper, but it's not recommended to have a very deep nesting, because it can be hard to manage the data.plural
key (with plural_value
) in the child
data, it will only executed once (when the message is created), and can't be updated later using i18n_update_plurals()
function.