Skip to content

Placeholder

Lorenzo Rossi edited this page Jan 5, 2018 · 1 revision

Placeholders are a simple way to store data that might contain values resolved only when the object is used by or on a player.
Examples of this are customized enter messages, like "%player_name% joined the game!"

Create Placeholders

PlaceholderValue<String> message = PlaceholderValue.stringValue("%player_name% joined the game!");

The api already checks if the string has placeholders or not and resolves the strings where possible.
But if you already have a compile-time value to put in?

PlaceholderValue<String> adminMessage = PlaceholderValue.fake("Admin joined the game!");

Messages created like this won't be resolved in any case.
Other types are supported by default like ints, floats or similar and you can support custom types by creating your resolving function:

PlaceholderValue<Integer> playerLevel = PlaceholderValue.intValue("%player_level%");
PlaceholderValue<Double> playerHealth = PlaceholderValue.doubleValue("%player_health%");
PlaceholderValue<Foo> playerFoo = PlaceholderValue.value("%player_foo%", parser, null);// null -> value on error

Resolve Placeholders

String str = message.resolve(player);

This is the simplest method, but sometimes you may need to add some custom resolutions, so we created the registries

PlaceholderRegistry

A PlaceholderRegistry contains how a placeholder is resolved, a parent might be specified for fallback support.
The default PlaceholderRegistry can be obtained with PlaceholderRegistry.def() and it's the default used by resolving the Placeholder without specifying any registry.
If you want to add more placeholders for a Placeholder resolution the safest option is to create another PlaceholderRegistry were you register your resolvers

PlaceholderValue<String> message = PlaceholderValue.stringValue("%foo%");
String resolved = message.resolve(player, PlaceholderRegistry.wrap("foo", "bar"));

The value in resolved will be bar, this is useful in system where custom variables can be displayed like a countdown.
By default every created PlaceholderRegistry will have the default one as the parent so every old placeholder will continuate to work. If you want to disable it just set the parent to null using registry.setParent(null);
If you need to add resolutions across methods you can create the PlaceholderRegistry and then pass it around and change it using set(key, value), Example:

PlaceholderRegistry registry = PlaceholderRegistry.create();
registry.set("foo", "bar").set("language", "java"); // Chainable!
registry.set("countdown", "5");
message.resolve(player, registry);


You can also support real placeholder functions like

PlaceholderRegistry registry = PlaceholderRegistry.create()
    .set("millis", () -> System.currentTimeMillis())
    .set("echo", (player, arg) -> arg + "!"); // Placeholder arguments

Creating PlaceholderManagers

What if you want to add support to a placeholder mod different than (and I hope better than) PlaceholderAPI?
Just override BasePlaceholderManager and define how to get the placeholders overriding the find method and hook your custom manager by listening to the PlaceholderManagerHookEvent and adding your manager.

Fallback custom placeholders

Even when no supported API is found we support some really basic custom placeholders, here's a list:

  • player_displayname
  • player_food_level
  • player_health
  • player_level
  • player_name
  • player_saturation
  • player_world
  • vault_eco_balance

This might help in testing servers where no PlaceholderAPI is set up