There are few ways (and types) of placeholders you can parse with PlaceholderAPI. So depending on your use case some of these will be more useful than others.
Placeholders should be provided with a context at all times. The context allows the placeholder parser to inject placeholders that require an optional context, such as a player.
A PlaceholderContext is created using one of the PlaceholderContext.of(...) variants. Depending on the objects passed, different placeholders may be available.
PlaceholderContext.of(...) Variants
MinecraftServer
May use placeholders that depend on the server
May use placeholders that depend on ServerCommandSource (Note: uses the command source from MinecraftServer.getCommandSource())
GameProfile
May use placeholders that depend on the server
May use placeholders that depend on ServerCommandSource (Note: creates a new dummy command source at (0,0,0))
May use placeholders that depend on GameProfile
ServerPlayerEntity
May use placeholders that depend on the server
May use placeholders that depend on ServerCommandSource
May use placeholders that depend on ServerWorld
May use placeholders that depend on ServerPlayerEntity
May use placeholders that depend on Entity
May use placeholders that depend on GameProfile
ServerCommandSource
May use placeholders that depend on the server
May use placeholders that depend on ServerCommandSource
May use placeholders that depend on ServerWorld
May use placeholders that depend on ServerPlayerEntityonly if the source has a player
May use placeholders that depend on Entityonly if the source has an entity
May use placeholders that depend on GameProfileonly if the source has a player
Entity
May use placeholders that depend on the server
May use placeholders that depend on ServerCommandSource
May use placeholders that depend on ServerWorld
May use placeholders that depend on ServerPlayerEntityonly if the source has a player
May use placeholders that depend on Entity
May use placeholders that depend on GameProfileonly if the source has a player
Parsing global placeholders is really simple, as long as you have access to ServerPlayerEntity or MinecraftServer object. You just need to simply import eu.pb4.placeholders.api.Placeholders and call parseText. This method will return fully parsed Text, which can be displayed to the user.
Placeholders itself will use default formatting of %category:placeholder%. If you want to use other formatting for them (which is recommended), you can use parseText(Text, PlaceholderContext, Pattern). Prefer those listed in Preferred Patterns for static.
To parse static placeholders you need to create a Map with String as a key and Text as a value. You also need a Pattern object (which can be taken from predefined ones). Then it's as simple as calling a parseText static method on PlaceholderAPI class.
publicclassStaticPlaceholders{/** * Formats a player message according to <code>inputText</code> * * Example input: * <code> * ${playerName} says "${message}" * </code> * * @param inputText The text that is parsed for placeholders. * Example input: * <code>${playerName} says "${message}"</code> * @param player The player name used to replace the ${playerName} * variable in the input. Example input: * the player who's name is 'ThePlayerUsername' * @param messageText The message text used to replace the ${message} * variable in the input. Example input: * <code>this is the message</code> * * @return The formatted message. Example return: * <code>ThePlayerUsername says "this is the message"</code> */publicstaticTextformatPlayerMessage(TextinputText,ServerPlayerEntityplayer,TextmessageText){Map<String,Text>placeholders=Map.of("message",messageText,// replace ${message} with the messageText"playerName",player.getName()// replace ${playerName} with the player's name);returnPlaceholders.parseText(inputText,Placeholders.PREDEFINED_PLACEHOLDER_PATTERN,placeholders);// parse the inputText}}
objectStaticPlaceholders{/** * Formats a player message according to [inputText] * * Example input: * ``` * ${playerName} says "${message}"! * ``` * * @param inputText The text that is parsed for placeholders. * Example input: * `${playerName} says "${message}"` * * @param player The player name used to replace the `${playerName}` variable in the input. * Example input: * the player who's name is `ThePlayerUsername` * * @param messageText The text used to replace the `${message}` variable in the input. * Example input: * `this is the message` * * @return The formatted message. * Example return: * ``` * ThePlayerUsername says "this is the message"! * ``` */funformatPlayerMessage(inputText:Text?,player:ServerPlayerEntity,messageText:Text):Text{valplaceholders=mapOf("message"tomessageText,// replace ${message} with the messageText"playerName"toplayer.name,// replace ${playerName} with the player's name)returnPlaceholders.parseText(inputText,Placeholders.PREDEFINED_PLACEHOLDER_PATTERN,placeholders)// parse the inputText}}
In case where you want to parse placeholder with a context similar to global one, you need to create a Map with Identifier as a key and PlaceholderHandler as a value (same as adding global ones). You also will need a pattern object, which is the same as with static ones.
As opposite to global ones, you don't need to define namespace/category as it can default to minecraft one (for simpler user input). Then you just parse it with parseText(Text, PlaceholderContext, Pattern, PlaceholderGetter).
publicclassDynamicPlaceholders{privatestaticfinalRandomrandom=newRandom();/** * Example input: * <code> * Hello! ${player blue}. Random number between 0 and 20: ${random 20} * </code> * * Example output: * <code> * Hello! <blue>ThePlayerName</blue>. Random number: 13 * </code> */publicstaticTextparseInputText(ServerPlayerEntityplayer,TextinputText){// parse the inputText messagereturnPlaceholders.parseText(inputText,PlaceholderContext.of(player),Placeholders.PREDEFINED_PLACEHOLDER_PATTERN,DynamicPlaceholders::getPlaceholder);}privatestaticPlaceholderHandlergetPlaceholder(Stringid){returnswitch(id){case"player"->DynamicPlaceholders::playerPlaceholder;case"random"->DynamicPlaceholders::randomPlaceholder;default->null;};}privatestaticPlaceholderResultplayerPlaceholder(PlaceholderContextctx,Stringarg){if(arg==null)returnPlaceholderResult.invalid("No argument!");if(!ctx.hasPlayer())returnPlaceholderResult.value(Text.literal("You are not a player!").setStyle(Style.EMPTY.withColor(TextColor.parse(arg))));returnPlaceholderResult.value(ctx.player().getName().copy().setStyle(Style.EMPTY.withColor(TextColor.parse(arg))));}privatestaticPlaceholderResultrandomPlaceholder(PlaceholderContextctx,Stringarg){if(arg==null){intrandomNumber=random.nextInt(10);returnPlaceholderResult.value(String.valueOf(randomNumber));}try{intrandomNumber=random.nextInt(Integer.parseInt(arg));returnPlaceholderResult.value(String.valueOf(randomNumber));}catch(NumberFormatExceptione){returnPlaceholderResult.invalid("Invalid number!");}}}
objectDynamicPlaceholders{privatevalrandom=Random()/** * Example input: * ``` * Hello! ${player blue}. Random number between 0 and 20: ${random 20} * ``` * * Example output: * ``` * Hello! <blue>ThePlayerName</blue>. Random number: 13 * ``` */funparseInputText(player:ServerPlayerEntity,inputText:Text):Text{// parse the inputText messagereturnPlaceholders.parseText(inputText,PlaceholderContext.of(player),Placeholders.PREDEFINED_PLACEHOLDER_PATTERN,DynamicPlaceholders::getPlaceholder)}privatefungetPlaceholder(id:String):PlaceholderHandler? {returnwhen(id){"player"->PlaceholderHandler(DynamicPlaceholders::playerPlaceholder)"random"->PlaceholderHandler(DynamicPlaceholders::randomPlaceholder)else->null}}privatefunplayerPlaceholder(ctx:PlaceholderContext,arg:String?):PlaceholderResult{if(arg==null)returnPlaceholderResult.invalid("No argument!")if(ctx.player==null)returnPlaceholderResult.value(Text.literal("You are not a player!").setStyle(Style.EMPTY.withColor(TextColor.parse(arg))))returnPlaceholderResult.value(ctx.player!!.name.copy().setStyle(Style.EMPTY.withColor(TextColor.parse(arg))))}privatefunrandomPlaceholder(ctx:PlaceholderContext,arg:String?):PlaceholderResult{returntry{valrandomNumber=random.nextInt(arg?.toInt()?:10)PlaceholderResult.value(randomNumber.toString())}catch(e:NumberFormatException){PlaceholderResult.invalid("Invalid number!")}}}