Skip to content

Commit

Permalink
[1.1.0] Lots of improvements, create good documentation
Browse files Browse the repository at this point in the history
- Broken TextParser tags in an safe and all categories,
- Gradients now work with Unicode Emojis
- Added TextParser.parseSafe(String) for simpler parsing of user input,
- Added multiple new aliases to tags,
- Added `style` and `raw` tags, which allow usage of json style and json text,
- Marked it as library in ModMenu,
- Added logo to mod (and replaced the old one)
- Created a documentation,
  • Loading branch information
Patbox committed Aug 1, 2021
1 parent 785c756 commit b56e34f
Show file tree
Hide file tree
Showing 28 changed files with 874 additions and 38 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Release

on:
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v2
with:
python-version: 3.x
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ jobs:
with:
files: 'build/libs/*.jar;!build/libs/*-sources.jar;!build/libs/*-dev.jar'
repo-token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v2
with:
python-version: 3.x
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Fabric Placeholder API
# About Placeholder API
It's a small, jij-able API that allows creation and parsing placeholders within strings and Minecraft Text Components.
Placeholders use simple format of `%modid:type%` or `%modid:type/data%`.
It also includes simple, general usage text format indented for simplifying user input in configs/chats/etc.

For list of currently available placeholders, check [wiki](https://github.com/Patbox/FabricPlaceholderAPI/wiki).
For list of currently available placeholders, check [wiki](https://github.com/Patbox/TextPlaceholderAPI/wiki).

## Usage:
Add it to your dependencies like this:
Expand All @@ -26,3 +27,5 @@ PlaceholderAPI.register(new Identifier("server", "name"), (ctx) -> PlaceholderRe
If you want to parse placeholders, you need to use `PlaceholderAPI.parseString(String, MinecraftServer or ServerPlayerEntity)`
for strings or `PlaceholderAPI.parseText(Text, MinecraftServer or ServerPlayerEntity)` for Vanilla Text Components.
These function don't modify original one, instead they just return new String/Text.


Binary file added docs/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/assets/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.md-header__button.md-logo img, .md-header__button.md-logo svg {
width: auto;
}
54 changes: 54 additions & 0 deletions docs/dev/adding-placeholders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Adding placeholders
Creation of new placeholders is simple. You just need to import `eu.pb4.placeholders.PlaceholderAPI`
and call static `register` method. You only need to provide 2 arguments:

- Identifier with your mod id as namespace and path as argument name (with one additional limitation being not allowed to use `/` in it).
- A function (in form of lambda for example) that takes PlaceholderContext and returns PlaceholderResult,

Example
```
PlaceholderAPI.register(
new Identifier("example", "placeholder"),
(ctx) -> PlaceholderResult.value(new LiteralText("Hello World!"))
);
```

## Using the context
PlaceholderContext object passed to placeholder contains allows getting player (if exist), server and argument value.
It also includes few methods for checking if they are present.

Here is example for player only placeholder
```
PlaceholderAPI.register(new Identifier("player", "displayname"), (ctx) -> {
if (ctx.hasPlayer()) {
return PlaceholderResult.value(ctx.getPlayer().getDisplayName());
} else {
return PlaceholderResult.invalid("No player!");
}
});
```

And one for usage of argument
```
PlaceholderAPI.register(new Identifier("server", "name_from_uuid"), (ctx) -> {
if (ctx.hasArgument()) {
return PlaceholderResult.value(ctx.getServer().getUserCache().getByUuid(UUID.fromString(ctx.getArgument())).get().getName()));
} else {
return PlaceholderResult.invalid("No argument!");
}
});
```

## Returning correct value
Placeholders need to return instance of PlaceholderResult. It can be created by usage of provided static methods on this class.

If it was successful:

* `PlaceholderResult.value(Text text)` - Creates a value with text
* `PlaceholderResult.value(String text)` - Creates a value from string, by parsing it with TextParser

If it was invalid (no player or argument for example):

* `PlaceholderResult.invalid()` - Creates simple invalid result
* `PlaceholderResult.invalid(String reason)` - Creates invalid result with a reason,
which is currently unused, but can be implemented by other parsers
23 changes: 23 additions & 0 deletions docs/dev/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Getting Started

To begin, you need to add Nucleoid's maven to your build `build.gradle`.

```groovy
repositories {
// There might be other repos there too, just add it at the end
maven { url "https://maven.nucleoid.xyz/" }
}
```

Then you just declare it as dependency!
```groovy
dependencies {
// You will have other dependencies here too
modImplementation include("eu.pb4:placeholder-api:[VERSION]")
}
```
This will also include it in yours mods, so users won't need to download it separately.

You just need to replace `[VERSION]` with version you want to use (which should be usually the latest available).
For list of version names, you can check [maven](https://maven.nucleoid.xyz/eu/pb4/placeholder-api/)
82 changes: 82 additions & 0 deletions docs/dev/parsing-placeholders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Parsing placeholders
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.

## Parsing global placeholders
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.PlaceholderAPI` and call
`parseText`. This method will return fully parsed Text, which can be displayed to the user.

Example
```
// for ServerPlayerEntity
Text message = PlaceholderAPI.parseText(textInput, player);
// for Server
Text message2 = PlaceholderAPI.parseText(textInput, server);
```

Placeholders itself will use default formatting of `%category:placeholder%`.
If you want to use other formatting for them (which is recommended), you can use
`parseTextAlt(Text, ServerPlayerEntity or MinecraftServer)` for `{category:placeholder}`.

## Parsing own/custom/predefined placeholders
If you want to parse your own placeholders, you can do this in 2 ways.

### Static placeholders
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 `parsePredefinedText` static method on `PlaceholderAPI` class.

Example
```
ServerPlayerEntity player = something.getPlayer(); // MinecraftServer server = something.getServer()
Text inputText = new LiteralText("Hello! ${player}");
Map<String, Text> placeholders = Map.of("player", new LiteralText("You are a player!"));
Pattern pattern = PlaceholderAPI.PREDEFINED_PLACEHOLDER_PATTERN;
Text output = PlaceholderAPI.parsePredefinedText(inputText, pattern, placeholders);
```

### Dynamic placeholders
In case where you want to parse placeholder with a context similar to global one, you need to
create a Map with `Identifier` (with `/` being disallowed) 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 `parseTextCustom(Text, ServerPlayerEntity or MinecraftServer, Map<String, PlaceholderHandler>, Pattern)`.

Example
```
ServerPlayerEntity player = something.getPlayer(); // MinecraftServer server = something.getServer()
Text inputText = new LiteralText("Hello! ${player/blue}");
Map<Identifier, Text> placeholders = Map.of(new Identifier("player"),
(ctx) -> {
if (ctx.hasPlayer()) {
return PlaceholderResult.value(new LiteralText("You are a player!")
.setStyle(Style.EMPTY.withColor(TextColor.parse(ctx.getArgument()))));
} else {
return PlaceholderResult.value(new LiteralText("You are a server!")
.setStyle(Style.EMPTY.withColor(TextColor.parse(ctx.getArgument()))));
}
});
Pattern pattern = PlaceholderAPI.PREDEFINED_PLACEHOLDER_PATTERN;
Text output = PlaceholderAPI.parseTextCustom(inputText, player, pattern, placeholders);
// Text output = PlaceholderAPI.parseTextCustom(inputText, server, pattern, placeholders);
```

### Preferred Patterns for static
PlaceholderAPI has few Patterns you can use, which are accessible as static objects on `PlaceholderAPI` class.

* `PREDEFINED_PLACEHOLDER_PATTERN` (`${placeholder}`) - works the best in most cases, doesn't collide with other ones.
* `ALT_PLACEHOLDER_PATTERN_CUSTOM` (`{placeholder}`) - second best, but have more chance of colliding with user formatting.

There are other ones, which usage is allowed, but they might work worse.

* `PLACEHOLDER_PATTERN_CUSTOM` (`%placeholder%`) - is the same as default one, but doesn't require `:`.
* `PLACEHOLDER_PATTERN` (`%category:placeholder%`) - used by default global placeholders (requires category).
* `PLACEHOLDER_PATTERN_ALT` (`{category:placeholder}`) - used as alternative formatting for global ones (requires category).

30 changes: 30 additions & 0 deletions docs/dev/text-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Using Simplified Text Format/TextParser
[*You can read about format here!*](/user/text-format)

Usage of TextParser is simple and really customisable. You just need to import `eu.pb4.placeholders.TextParser`
and call static `parse` method for admin provided configs or `parseSafe` for player provided ones.
They both take only one String argument and output a Text object.

Example
```
String inputString = "<red>Hello <rb>World</rb>!"
Text output = TextParser.parse(inputString); // Text output = TextParser.parseSafe(inputString);
```

## Parsing with only selected ones
If you want to only use selected tags, you can simply get map of all with `TextParser.getRegisteredTags()`
or `TextParser.getRegisteredSafeTags()`. Then you can copy these to your own Map with String keys
and `TextParser.TextFormatterHandler` values.
Then you just use them with `TextParser.parse(String, Map<String, TextFormatterHandler>)`.

Example
```
String inputString = "<red>Hello <blue>World</blue>!"
Map<String, TextParser.TextFormatterHandler> tags = Map.of("red", TextParser.getRegisteredTags().get("red"),
"blue", TextParser.getRegisteredTags().get("yellow") // renames works too!
);
Text output = TextParser.parse(inputString, tags);
```
27 changes: 27 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# About Placeholder API
It's a small, jij-able API that allows creation and parsing placeholders within strings and Minecraft Text Components.
Placeholders use simple format of `%modid:type%` or `%modid:type/data%`.
It also includes simple, general usage text format indented for simplifying user input in configs/chats/etc.

## For users
It allows users to configure multiple mods in similar way without losing compatibility between mods.
Placeholders allow changing what and where any information is present within compatible mods.

Additionally, Simplified Text Format allows to style them in readable way without requirement of writing JSON manually or using
generators.

* [Using placeholders](user/general)
* [Default placeholder list](user/default-placeholders)
* [Mod placeholder list](user/mod-placeholders)
* [Simplified Text Format](user/text-format)

## For developers
Usage of Placeholder API is a simple way to achieve good mod compatibility without having to implement
multiple mod specific apis. Additionally, the placeholder parsing system can be used for replacing
own static (or dynamic placeholders) in Text created by player or read from config. This with combination
of Simplified Text Format allows creating great user/admin experience.

* [Getting Started](dev/getting-started)
* [Adding placeholders](dev/adding-placeholders)
* [Parsing placeholders](dev/parsing-placeholders)
* [Using Simplified Text Format/TextParser](dev/text-format)
52 changes: 52 additions & 0 deletions docs/user/default-placeholders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Default placeholder list
These placeholders are provided by default and are available for every mod using Placeholder API.

## List of placeholders
### Server
- `%server:tps%` - server's tps
- `%server:tps_colored%` - colored server's tps
- `%server:mspt%` - server's mspt
- `%server:mspt_colored%` - colored server's mspt
- `%server:time%`/`%server:time/[formatting]%` - server's time
- `%server:version%` - server's version
- `%server:name%` - server's name
- `%server:used_ram%`/`%server:used_ram/gb%` - amount of ram used by server
- `%server:max_ram%`/`%server:max_ram/gb%` - maximal amount of ram, that can be used by server
- `%server:online%` - number of online players
- `%server:max_players%` - maximal player count

### Server
- `%world:time%` - world's time
- `%world:time_alt%` - world's time (alternative formatting)
- `%world:day%` - world's day
- `%world:player_count%` - world's player count
- `%world:mob_count%`/`%world:mob_count/[group]%` - Shows amount of spawned mobs
- `%world:mob_cap%`/`%world:mob_cap/[group]%` - Shows maximum amount of mobs that can spawn is player's world
- `%world:id%` - world's id
- `%world:name%` - world's name

### Player
- `%player:name%` - player's name
- `%player:name_unformatted%` - player's name (without formatting)
- `%player:displayname%` - player's displayname (used on chat)
- `%player:displayname_unformatted%` - player's displayname (without formatting)
- `%player:ping%` - player's ping
- `%player:ping_colored%` - colored player's ping
- `%player:pos_x%` - player's x coordinate
- `%player:pos_y%` - player's y coordinate
- `%player:pos_z%` - player's z coordinate
- `%player:health%` - player's health
- `%player:max_health%` - player's max health
- `%player:hunger%` - player's health
- `%player:saturation%` - player's health
- `%player:playtime%`/`%player:playtime/[formatting]%` - player's playtime
- `%player:statistic/[statistic]%` - value of player's statistic

Vanilla statistics:
```
leave_game, play_one_minute, time_since_death, time_since_rest, sneak_time, walk_one_cm, crouch_one_cm, sprint_one_cm, walk_on_water_one_cm, fall_one_cm, climb_one_cm, fly_one_cm, walk_under_water_one_cm, minecart_one_cm, boat_one_cm, pig_one_cm, horse_one_cm, aviate_one_cm, swim_one_cm, strider_one_cm, jump, drop, damage_dealt, damage_dealt_absorbed, damage_dealt_resisted, damage_taken, damage_blocked_by_shield, damage_absorbed, damage_resisted, deaths, mob_kills, animals_bred, player_kills, fish_caught, talked_to_villager, traded_with_villager, eat_cake_slice, fill_cauldron, use_cauldron, clean_armor, clean_banner, clean_shulker_box, interact_with_brewingstand, interact_with_beacon, inspect_dropper, inspect_hopper, inspect_dispenser, play_noteblock, tune_noteblock, pot_flower, trigger_trapped_chest, open_enderchest, enchant_item, play_record, interact_with_furnace, interact_with_crafting_table, open_chest, sleep_in_bed, open_shulker_box, open_barrel, interact_with_blast_furnace, interact_with_smoker, interact_with_lectern, interact_with_campfire, interact_with_cartography_table, interact_with_loom, interact_with_stonecutter, bell_ring, raid_trigger, raid_win, interact_with_anvil, interact_with_grindstone, target_hit, interact_with_smithing_table
```




37 changes: 37 additions & 0 deletions docs/user/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Using placeholders

Usage of placeholder mostly depends on implementation of mod itself. If mod uses simple, one/multiline text
(for example with Simple Text Format) you just need to add it by just writing `%placeholder%`
(or in some cases`{placeholder}`, `${placeholder}` or other format which should be provided on mods page).

Inner part of placeholder can take shape of either `category:placeholder` or `category:placeholder/argument`,
where `category` is replaced by type (`player`, `world`, etc) or ID of the mod and `placeholder` is the placeholder itself.
Additionally, some placeholders might have additional or required argument provided after first `/` symbol. It's format
fully depend on mod providing it.

You can check list of [build in placeholders here](/users/default-placeholders)
and [placeholders from mods here](/users/mod-placeholders).

### List of mods supporting displaying Placeholder API's placeholders:

- Styled Player List -
[CurseForge](https://www.curseforge.com/minecraft/mc-mods/styled-player-list),
[Modrinth](https://modrinth.com/mod/styledplayerlist),
[Github](https://github.com/Patbox/StyledPlayerList)

- Styled Chat -
[CurseForge](https://www.curseforge.com/minecraft/mc-mods/styled-chat),
[Modrinth](https://modrinth.com/mod/styled-chat),
[Github](https://github.com/Patbox/StyledChat)

- Holograms -
[CurseForge](https://www.curseforge.com/minecraft/mc-mods/server-holograms),
[Modrinth](https://modrinth.com/mod/holograms),
[Github](https://github.com/Patbox/Holograms)

- Player Events -
[CurseForge](https://www.curseforge.com/minecraft/mc-mods/player-events),
[Github](https://github.com/ByMartrixx/player-events)


*Are you a mod dev, and your mod is missing? Feel free to create an issue!*
Loading

0 comments on commit b56e34f

Please sign in to comment.