Skip to content

leycm/i18label4j

Repository files navigation

Contributors Forks Stargazers Issues LGPL License


i18label4j

A simple and lightweight registry library with flexible identifiers and namespaces for Java.
Localize your application cleanly — with typed labels, dynamic placeholders, and pluggable serializers.

Explore the docs »  ·  Report Bug  ·  Request Feature


Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Architecture
  5. Roadmap
  6. Contributing
  7. License
  8. Contact
  9. Acknowledgments

About The Project

i18label4j is a modular Java library for managing localizable text labels with a clean, fluent API. It provides:

  • Typed labels — distinguish between locale-aware i18n labels and immutable literal labels at compile time.
  • Placeholder substitution — register static or dynamic Mapping objects on any label and apply them via configurable MappingRule strategies (supports ${key}, {key}, %key%, <key>, and more out of the box).
  • Pluggable serializers — convert labels to any target type (plain String, Adventure Component, etc.) by registering a LabelSerializer.
  • Multiple localization sources — load translations from a flat directory (FileSource), a nested directory tree (DirSource), or implement your own LocalizationSource.
  • Format support — JSON, YAML, TOML, and Java .properties files are supported out of the box.
  • Translation caching — the CommonLabelProvider caches translations per locale with thread-safe ConcurrentHashMap internals and explicit cache eviction.

(back to top)

Built With

(back to top)


Getting Started

Prerequisites

  • Java 21+
  • Gradle 9+ (wrapper included)

Installation

Add the repository and dependency to your build.gradle.kts:

repositories {
    maven("https://leycm.github.io/repository/")
}

dependencies {
    // API only (compile against the interface)
    compileOnly("de.leycm:i18label4j-api:1.0")

    // Full implementation (includes CommonLabelProvider, FileSource, DirSource, etc.)
    implementation("de.leycm:i18label4j-impl:1.0")
}

Or with Maven (pom.xml):

<repository>
  <id>leycm-repo</id>
  <url>https://leycm.github.io/repository/</url>
</repository>

<dependency>
  <groupId>de.leycm</groupId>
  <artifactId>i18label4j-api</artifactId>
  <version>1.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>de.leycm</groupId>
  <artifactId>i18label4j-impl</artifactId>
  <version>1.0</version>
</dependency>

(back to top)


Usage

1. Set up a LabelProvider

// Load translations from a flat directory of JSON files:
// resources/lang/en.json, de.json, ...
LocalizationSource source = FileSource.json(
    URI.create("resource://lang")
);

LabelProvider provider = CommonLabelProvider.builder()
    .locale(Locale.ENGLISH)                      // default locale
    .defaultMappingRule(MappingRule.DOLLAR_CURLY) // ${placeholder} syntax
    .withSerializer(String.class, new MyStringSerializer())
    .buildWarm(source, Locale.ENGLISH, Locale.GERMAN); // pre-load cache

// Register as singleton
Instanceable.register(provider, LabelProvider.class);

2. Create and resolve labels

// Translatable label — looks up "greeting" in the active locale
Label hello = Label.of("greeting");
System.out.println(hello.in(Locale.ENGLISH)); // -> "Hello!"
System.out.println(hello.in(Locale.GERMAN));  // -> "Hallo!"

// Literal label — always returns the fixed string
Label version = Label.literal("v1.0.0");
System.out.println(version.in(Locale.JAPANESE)); // -> "v1.0.0"

3. Placeholder substitution

Label message = Label.of("welcome.message")
    .mapTo("name", () -> currentUser.getDisplayName())
    .mapTo("count", itemCount);

// Translation: "Welcome, ${name}! You have ${count} items."
System.out.println(message.mapped(Locale.ENGLISH));
// -> "Welcome, Alice! You have 3 items."

4. Serialize to a custom type

// Assuming an Adventure Component serializer is registered:
Component component = Label.of("server.motd").serialize(Component.class);

5. Translation file layout (FileSource)

resources/lang/
  en.json      -> {"greeting": "Hello!", "welcome.message": "Welcome, ${name}!"}
  de.json      -> {"greeting": "Hallo!", "welcome.message": "Willkommen, ${name}!"}

6. Nested directory layout (DirSource)

resources/lang/
  en/
    messages.json  -> {"greeting": "Hello!"}
    errors.json    -> {"not_found": "Not found."}
  de/
    messages.json  -> {"greeting": "Hallo!"}

Keys are prefixed with the filename stem: messages.greeting, errors.not_found.

Available MappingRule styles

Constant Example
MappingRule.DOLLAR_CURLY ${variable}
MappingRule.CURLY {variable}
MappingRule.DOUBLE_CURLY {{variable}}
MappingRule.PERCENT %variable%
MappingRule.TAG <variable>
MappingRule.SHELL $variable
MappingRule.MINI_MESSAGE <var:variable>
... ...

(back to top)


Architecture

i18label4j
├── i18-api/          # Public API — Label, LabelProvider, Mapping, MappingRule, LabelSerializer, LocalizationSource
└── i18-impl/         # Implementation — CommonLabelProvider, LiteralLabel, LocaleLabel,
                      #                  FileSource, DirSource, FileParser, FileUtils

The library is split into two modules so downstream projects can depend only on the API and swap implementations at runtime via Instanceable.register(...).

(back to top)


Roadmap

  • Core Label API with LiteralLabel and LocaleLabel
  • CommonLabelProvider with thread-safe translation cache
  • MappingRule with 10+ built-in placeholder styles
  • FileSource and DirSource with JSON, YAML, TOML, .properties support
  • Classpath (resource://), filesystem (file://), and remote (http(s)://) URI schemes
  • Nested/hierarchical key support in DirSource
  • Hot-reload support for translation files
  • Maven / Gradle plugin for compile-time key validation
  • Additional serializer modules (Adventure, MiniMessage)

See the open issues for the full list of proposed features and known bugs.

(back to top)


Contributing

Contributions are what make open source such a great place to learn and build. Any contributions you make are greatly appreciated.

  1. Fork the project
  2. Create your feature branch (git checkout -b feat/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add some amazing Features')
  4. Push to the branch (git push origin feat/amazing-feature)
  5. Open a Pull Request

(back to top)


License

Distributed under the GNU Lesser General Public License v3.0. See LICENSE.LGPL for more information.

(back to top)


Contact

Lennardleycm@proton.me

Project Link: https://github.com/leycm/i18label4j

(back to top)


Acknowledgments

(back to top)


About

A fast, server-side translation and label provider for high-performance Text & MiniMessage localization

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

Generated from leycm/gradle-template