Skip to content

Messages

Leo edited this page Dec 25, 2023 · 4 revisions

Plugin messages are represented by Message objects. Messages implement the ComponentLike interface of Adventure and can be used wherever you would normally use Components (Chat messages, books, scoreboard, GUI title, item names/lores, ...).

Namespaced Key

The identifier of a Message is the combination of a namespace and a key. The namespace is the path to the Translation application separated by dots (.). The namespace of the global Translations instance is global, every fork of it with name xy has the namespace global.xy and so forth.

The key of a message is the identifier within any Translations instance. Like error.no_perm or prefix. In combination, the PathFinder plugin would have a Message of namespaced key global.PathFinder:prefix.

The Translations instance will load all messages from specified locale files (see chapter about storages) and store the translated value into the according dictionary of a Message. When converting a Message to a Component, it will use the default locale en and load its value from the dictionary. See per player locale if you want to specify a locale.

Translations Ownership

A message needs a reference to any Translations instance to function. Therefore, you must either create the Message directly from a Translations, or assign them before using them.

Create them from Translations:

private Message prefix = null;

void anyContext(Translations t) {
   prefix = t.message("prefix");
   //or
   prefix = t.messageBuilder("prefix").withDefault("<rainbow>Prefix</rainbow> ").build();
}

Assign them later:

public static final Message PREFIX = new MessageBuilder("prefix").withDefault("<rainbow>Prefix</rainbow> ").build();

void anyContext(Translations t) {
   t.addMessage(PREFIX);
   // or simply add all constants from a class with
   t.addMessages(TranslationsFramework.messageFieldsFromClass(MyMessagesClass.class));
}

Embedding

Messages can be embedded into each other. To do so, you can use the <msg> tag with according namespace and key. You can reference all global translations or any child or nestmate translation (not advised) by specifying a namespace.

public static final Message PREFIX = new MessageBuilder("prefix")
        .withDefault("<rainbow>Prefix</rainbow> ").build();
public static final Message NO_PERM = new MessageBuilder("error.no_perm")
        .withDefault("{msg:MyPlugin:prefix}...").build();

In most cases, the namespace is pretty redundant. You can therefor skip it and simply write the message key.

public static final Message NO_PERM = new MessageBuilder("error.no_perm")
        .withDefault("{msg:prefix}...").build();

This can cause collisions with parenting Translations, if for example both global and your plugin have a message with key prefix. In this case, the more specified Translations instance will provide the translation (further down the Translations tree). If both your plugin and global define a Message prefix, the prefix Message of your plugin will be used. Again, to explicitly use the message of global, use {msg:global:prefix}.