Adventure Series: Tag Resolvers
TagResolvers
are a way to declare custom
tags for your MiniMessage string. Most places which take in
TagResolvers
usually take in a varargs one.
That means that you can just put in however many you need. In case you do
require to have them all condensed in just one, Adventure provides the TagResolver.resolver(TagResolver...)
method for convenience.
Placeholders
Section titled “Placeholders”The simplest form of TagResolvers
are Placeholders
. These allow the direct insertion of
Components
or strings into serialized component. Each placeholder takes in the tag name as its first parameter and a value
as their second parameter. Tags should always follow the snake_case_naming_scheme
and only contain alphabetical characters and underscores.
There are three inserting placeholder, and one styling placeholder. The styling one will, instead of adding text content, modify the style of text.
Using insertion placeholders
Section titled “Using insertion placeholders”The most common use of placeholders are the inserting ones. You can use these whenever you have a Component
and want to embed it into your MiniMessage string.
This might look like this:
final Component msg = miniMessage().deserialize("I am currently holding a <aqua><item></aqua>!", Placeholder.component("item", Component.text("Diamond Pickaxe")));
In-game preview

Using style placeholders
Section titled “Using style placeholders”Styling placeholders can be used like this:
miniMessage().deserialize("<red><custom_style>Hey</custom_style> o/", Placeholder.styling("custom_style", TextDecoration.BOLD));
The code above would essentially be equal to just writing
miniMessage().deserialize("<red><bold>Hey</bold> o/");
But text decorations aren’t the only thing you can apply! Hover and click events also count as styling. The following code makes the <custom_style>
tag style with an acacia boat hover:
final ItemStack stack = ItemType.ACACIA_BOAT.createItemStack();final Component component = miniMessage().deserialize("<red><custom_style>Hey o/", Placeholder.styling("custom_style", stack.asHoverEvent()));
In-game preview

Constructing a TagResolver using Tags
Section titled “Constructing a TagResolver using Tags”These resolvers work similarly to the Placeholder
ones. The first parameter of the resolver(String, Tag)
method is, once again, the name of the tag. The second parameter is the Tag
itself.
The first pair of methods are the inserting
ones. These will just insert a Component
into the serialized component. Any content which is inside of the tag will be added as a child Component
, meaning that any style of the inserted component
will also be used on the child component, unless it specifies its own style.
Unstyled text, <inserted_component> now the text shares the inserted component's style</inserted_component> and now it doesn't.
The second pair of methods are the selfClosingInserting
ones.
These work similarly to the inserting
ones, but do not need closing. That also means that no styling will be applied to other components.
The styling
tag works the same way as Placeholder.styling(...)
.
Complicated Tag Resolvers
Section titled “Complicated Tag Resolvers”One of the more complex ways to retrieve a TagResolver
, but also one of the most versatile ones, is using a BiFunction<ArgumentQueue, Context, Tag>
. This allows for
argument input and a lot more control flow. A very good example of its use, made by @mbaxter
, is the following papi
tag resolver for PlaceholderAPI
.
This allows parsing placeholder api placeholders in MiniMessage (%player_name%
turns into <papi:player_name>
).
/*** Creates a tag resolver capable of resolving PlaceholderAPI tags for a given player.** @param player the player* @return the tag resolver*/public @NotNull TagResolver papiTag(final @NotNull Player player) { return TagResolver.resolver("papi", (argumentQueue, context) -> { // Get the string placeholder that they want to use. final String papiPlaceholder = argumentQueue.popOr("papi tag requires an argument").value();
// Then get PAPI to parse the placeholder for the given player. final String parsedPlaceholder = PlaceholderAPI.setPlaceholders(player, '%' + papiPlaceholder + '%');
// We need to turn this ugly legacy string into a nice component. final Component componentPlaceholder = LegacyComponentSerializer.legacySection().deserialize(parsedPlaceholder);
// Finally, return the tag instance to insert the placeholder! return Tag.selfClosingInserting(componentPlaceholder); });}
Learn Paper Dev is licensed under CC BY-NC-SA 4.0