Skip to content

Using PlaceholderAPI (for consumers)

This page shows how to use PlaceholderAPI from your plugin when you want to parse messages or fetch single values.

Note: Only built-in placeholders and placeholders from installed providers will resolve. If a third-party plugin exposes a Provider, server admins must run /papi download <id> once to enable that plugin’s placeholders.

Parse text with placeholders

use NetherByte\PlaceholderAPI\PlaceholderAPI;
use pocketmine\player\Player;

/** @var Player|null $player */
$msg = "Welcome %player_name% to %server_name%! TPS: %server_tps%";
$out = PlaceholderAPI::parse($msg, $player);

Notes: - Player can be null for server-only placeholders. - Unknown placeholders remain unchanged.

Get a single value

$tps = PlaceholderAPI::get('server_tps');
$time = PlaceholderAPI::get('server_time:Y-m-d H:i'); // parameterized style

Parameterized placeholders

You can pass a parameter with identifier:param.

Examples: - server_time:<Y-m-d H:i> - server_online:world

The plugin also accepts underscore-style for backwards compatibility: - server_time_<format> - server_online_<world>

Debugging

  • Use /papi info <identifier[:param]> [player] to see:
  • Which expansion handles it
  • The resolved value
  • Expansion metadata (author, version, description)

Performance tips

  • Parsing once and reusing the result is cheaper than parsing every tick.
  • If you poll frequently (e.g., scoreboards), design your own cache where possible.
  • The API supports light caching per expansion when the expansion declares an update interval.

Setting Placeholder in your plugin (practical examples)

Below are end-to-end examples showing how to integrate PlaceholderAPI output into common plugin scenarios.

1) Custom join message including the player's primary group

This example listens for PlayerJoin and broadcasts a formatted message that includes the player's primary group via either NetherPerms or PocketVault.
<?php

use NetherByte\PlaceholderAPI\PlaceholderAPI;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\plugin\PluginBase;

final class JoinMessagePlugin extends PluginBase implements Listener{
    protected function onEnable() : void{
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }

    /** @priority MONITOR */
    public function onJoin(PlayerJoinEvent $event) : void{
        $p = $event->getPlayer();

        // Prefer NetherPerms if installed; fallback to PocketVault
        // Placeholders:
        //   %netherperms_primary_group%
        //   %pocketvault_group%
        $template = "&aWelcome &e%player_name% &7[&b%netherperms_primary_group%%pocketvault_group%&7]&a!";

        // If NetherPerms is not installed, %netherperms_primary_group% resolves to empty string.
        // If PocketVault is not installed, %pocketvault_group% resolves to empty string.
        $message = PlaceholderAPI::parse($template, $p);
        $this->getServer()->broadcastMessage($message);
    }
}

Tips: - Ensure the relevant provider is installed: - NetherPerms: /papi download netherperms - PocketVault: /papi download pocketvault

2) Scoreboard lines using primary group, money, name, and ping

If your scoreboard plugin supports placeholders in its configuration, you can reference PlaceholderAPI keys directly. Below is a generic YAML-style example of lines:

Scoreboard config using placeholders
scoreboard:
  title: "&6Server &7| &a%player_name%"
  lines:
    - "&fGroup: &b%netherperms_primary_group%%pocketvault_group%"
    - "&fMoney: &a%pocketvault_eco_balance_formatted%"
    - "&fPing: &e%player_ping% ms"
    - "&fWorld: &d%player_world%"

Notes: - Primary group can come from either %netherperms_primary_group% or %pocketvault_group% depending on which provider is installed. - Use %pocketvault_eco_balance_formatted% for currency symbol/commas if configured by your economy provider, or %pocketvault_eco_balance% for raw numeric.

3) Using placeholders in a GUI/Form title, content, or button tooltip

You can parse strings before sending a form to the player. Example using a common FormAPI-like interface:

Runtime form parsing with placeholders
use NetherByte\PlaceholderAPI\PlaceholderAPI;
use dktapps\pmforms\MenuForm; // Example; adapt to your forms library
use dktapps\pmforms\MenuOption;

$player = /* Player instance */;

$title = PlaceholderAPI::parse("&bProfile of %player_name%", $player);
$content = PlaceholderAPI::parse("&7Group: &a%netherperms_primary_group%%pocketvault_group%\n&7Money: &e%pocketvault_eco_balance_formatted%\n&7Ping: &6%player_ping% ms", $player);

$button1 = new MenuOption(PlaceholderAPI::parse("Open Menu &8(&b%nethermenus_opened_menu_name%&8)", $player));
$button2 = new MenuOption(PlaceholderAPI::parse("Last Menu: &d%nethermenus_last_menu_name%", $player));

$form = new MenuForm($title, $content, [$button1, $button2], function(){});
$player->sendForm($form);
Menus config with placeholders in UI
menus:
  profile:
    title: "&bProfile &7| &f%player_name%"
    buttons:
      group:
        name: "&aGroup: &f%netherperms_primary_group%%pocketvault_group%"
        lore:
          - "&7Money: &e%pocketvault_eco_balance_formatted%"
          - "&7Ping: &6%player_ping% ms"