API
The Glossa API is designed entirely around Kotlin and its DSL capabilities. Although the API can be used in Java, many parts will be less developer-friendly. It also uses Java Locale objects as the main source of locale-specific info, so make sure you can get a Locale object for whatever language you are working with.
Usage
See the repository page to get:
- the latest version
- the artifact coordinates for Maven/Gradle
Glossa
The main type you will be working with is Glossa
, which provides methods for generating translations.
To create an implementation, use glossaStandard
:
// specify a default locale
val english: Locale = Locale.forLanguageTag("en-US")
// specify the strategy for when a message doesn't exist for a given message key
// `Default` will simply output the key itself
// use `JavaLogging(Logger)` to output the key and a warning to the logger
// or `Logging((String) -> Unit)` to output the key and a warning to the logging function provided
val invalidMessageProvider: InvalidMessageProvider = InvalidMessageProvider.Default
// create the Glossa instance
val glossa: Glossa = glossaStandard(
defaultLocale = english,
invalidMessageProvider = invalidMessageProvider,
) {
// DSL scope here
}
You can then use the functions inside the DSL scope to add data for the engine to use:
glossaStandard(...) {
substitutions {
// to insert a raw substitution
substitution("icon_info", Component.text("(!)", NamedTextColor.GRAY))
// to insert a substitution parsed by MiniMessage
miniMessageSubstitution("icon_info", "<gray>(!)")
}
styles {
style("style_info", Style.style(NamedTextColor.GRAY))
}
translation(english) {
message("hello_world", "Hello world!")
messageList("splashes",
"Unleash Your Power!",
"Embark on an Epic Journey!",
"Join the Battle and Conquer!",
)
section("a_section") {
message("message_in_section", "This is a message in a section")
section("nested") {
message("msg", "Message in a nested section - a_section.nested.msg")
}
}
}
}
Message proxies
Glossa allows creating a rich, type-safe message generation API from a Kotlin interface. Use Glossa.messageProxy<T>()
to
create a MessageProxy<T>
, on which you can use .default
or .forLocale(Locale)
to get a T
object representing your
messages.
Function and section names automatically map to snake_case
names, unless specified otherwise.
// typealias Message = List<Component>
interface Messages {
// automatically maps to the message key `hello_world`
fun helloWorld(): Message
// maps to messages under `the_section`
val theSection: TheSection
interface TheSection {
fun aMessageList(): List<Message>
}
@MessageKey("another_key") // remap this function to point to a different key
fun withSpecialKey(): Message
@SectionKey("the_section") // remap this property to point to a different section
val sectionWithSpecialKey: TheSection
// provide arguments as well
fun withArguments(
// equivalent to the argument `replace("text", ...)`
text: Component,
// equivalent to the argument `format("coins", ...)`
coins: Int,
// `format("player_health", ...)`
@Placeholder("player_health") health: Float,
// `format("date_sold", ...)`
dateSold: Date,
)
}
val messages: MessageProxy<Messages> = glossa.messageProxy<Messages>()
val forEnglish = messages.forLocale(english)
val msg: Message = forEnglish.helloWorld() // generates `hello_world`
val list: List<Message> = forEnglish.theSection.aMessageList()
val msg2 = forEnglish.withArguments(
text = Component.text("Hello"),
coins = 350,
health = 0.5f,
dateSold = Date(0),
)
Configurate
Using the Configurate module, you can automatically load data from ConfigurationNode
s in the model DSL, via model extensions:
val langFile = dataFolder.resolve("en-US.yml")
glossaStandard(...) {
fromConfigLoader(
YamlConfigLoader.builder()
.file(langFile)
.build()
)
}
This uses the format as described in Format.