# Tagger ![Latest Release Download Count](https://img.shields.io/github/downloads/fantasycalendar/FoundryVTT-Tagger/latest/module.zip?color=2b82fc&label=DOWNLOADS&style=for-the-badge) [![Forge Installs](https://img.shields.io/badge/dynamic/json?label=Forge%20Installs&query=package.installs&suffix=%25&url=https%3A%2F%2Fforge-vtt.com%2Fapi%2Fbazaar%2Fpackage%2Ftagger&colorB=006400&style=for-the-badge)](https://forge-vtt.com/bazaar#package=tagger) ![Foundry Core Minimum Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fgithub.com%2Ffantasycalendar%2FFoundryVTT-Tagger%2Freleases%2Flatest%2Fdownload%2Fmodule.json&label=Foundry%20Minimum%20Version&query=$.compatibility.minimum&colorB=orange&style=for-the-badge) ![Foundry Core Verified Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fgithub.com%2Ffantasycalendar%2FFoundryVTT-Tagger%2Freleases%2Flatest%2Fdownload%2Fmodule.json&label=Foundry%20Verified%20Version&query=$.compatibility.verified&colorB=orange&style=for-the-badge) ![Latest Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fgithub.com%2Ffantasycalendar%2FFoundryVTT-Tagger%2Freleases%2Flatest%2Fdownload%2Fmodule.json&label=Latest%20Release&prefix=v&query=$.version&colorB=red&style=for-the-badge) --- Fantasy Computerworks Logo A module made by [Fantasy Computerworks](http://fantasycomputer.works/). Other works by us: - [Fantasy Calendar](https://app.fantasy-calendar.com) - The best calendar creator and management app on the internet - [Sequencer](https://foundryvtt.com/packages/sequencer) - Wow your players by playing visual effects on the canvas - [Item Piles](https://foundryvtt.com/packages/item-piles) - Drag & drop items into the scene to drop item piles that you can then easily pick up Like what we've done? Buy us a coffee! Buy Me a Coffee at ko-fi.com --- ## What is Tagger? This module allows you to put unique tags on objects in scenes and use Tagger's powerful API to quickly retrieve them. ## Placeables Sidebar On Foundry v14, the new Placeables sidebar tab (which lists every token, tile, light, etc. in the current scene) gets two Tagger features. ### Tag Pills Each entry in the sidebar shows its tags as pills under the entry's name. No configuration is needed. If a placeable has tags, the pills appear. ### `tag:` Search Prefix The sidebar's search box accepts `tag:` terms that filter entries by tag. Tag terms can be combined with the regular name search: | Query | Effect | | --- | --- | | `goblin` | Entries whose name contains "goblin" (Foundry's normal name search) | | `tag:enemy` | Entries that have a tag containing "enemy" | | `tag:"boss fight"` | Entries that have a tag containing the phrase "boss fight". Use quotes for tags with spaces. | | `tag:enemy tag:elite` | Entries that have **both** an "enemy" tag **and** an "elite" tag. Multiple `tag:` terms must all match. | | `tag:enemy goblin` | Entries with an "enemy" tag whose name also contains "goblin" | | `tag:foo*` | Entries that have a tag matching `foo` followed by anything. See wildcards below. | **Matching rules in the sidebar:** - **Case-insensitive.** `tag:Enemy` and `tag:enemy` behave the same. - **Substring by default.** `tag:enemy` will match tags like `enemy`, `enemyBoss`, and `arch-enemy`. - **Wildcards with `*`.** If your term contains `*`, the match uses the same wildcard syntax as `Tagger.getByTag`. `tag:foo*` matches `foo` followed by anything; `tag:*bar` matches anything ending in `bar`; `tag:foo*bar` matches anything starting with `foo` and ending with `bar`. ### Pill Match States The sidebar's matching is more lenient than `Tagger.getByTag`. The API is case-sensitive and matches the whole tag by default, so `Tagger.getByTag("enemy")` will not return a placeable tagged `enemyBoss` or `Enemy`, even though both show up when you type `tag:enemy` in the sidebar. To make this clear, pills are drawn in three colors: - **Green** - the tag matches one of the active search terms exactly (or there is no active search). `Tagger.getByTag(term)` will return this entry. - **Amber** - the tag matches the search term, but only because the sidebar ignores case or allows substrings. `Tagger.getByTag(term)` with default options will not return it. Hover the pill for a tooltip explaining the mismatch. - **Gray** - the entry is shown because another tag on it matched, but this tag does not match any active search term. To get the API to return everything the sidebar shows, use one of: - `Tagger.getByTag("enemy", { caseInsensitive: true })` to ignore case - `Tagger.getByTag("*enemy*")` to match as a substring - `Tagger.getByTag("*enemy*", { caseInsensitive: true })` for both ## Supported Modules These may not fully work in v14, as the modules may not be updated, or Tagger's interpretation of these modules' data has not been fully updated to be in line with what they expect, please allow some grace here. - [Token Attacher](https://foundryvtt.com/packages/token-attacher/) - If you have tag rules (like `{#}`) on attached objects, they will get applied when the prefab is first created, even on nested attached objects - [Monks Active Tile Triggers](https://foundryvtt.com/packages/monks-active-tiles) - This module also integrates Tagger to be able to select objects in the scene in its actions, and similarly to above, tag rules are evaluated when an active tile is created, either manually or through Token Attacher! ## Download `https://github.com/fantasycalendar/FoundryVTT-Tagger/releases/latest/download/module.json` Or if you want to try **experimental** features: `https://raw.githubusercontent.com/fantasycalendar/FoundryVTT-Tagger/next/module.json` ## Dialogs All major PlaceableObjects' configuration dialogues (such as actor prototype tokens, tokens, tiles, walls, lights, etc), now has a "Tags" field. Each tag is separated by a comma. ![img.png](docs/token-config.png) # Documentation > The block below is generated from the JSDoc in `src/tagger.js` (descriptions, > `@param`, `@returns`, and `@example` blocks). Edit the JSDoc and run > `npm run docs` to regenerate. ## Functions
Tagger.getByTag(inTags, inOptions)Array

Gets PlaceableObjects with matching tags provided to the method

Tagger.hasTags(inObjects, inTags, inOptions)Boolean

Verifies whether a given PlaceableObject or Document has the tags given

Tagger.getTags(inObject)Array

Gets all tags from a given PlaceableObject or Document

Tagger.setTags(inObjects, inTags)Promise

Set the tags on an PlaceableObject or Document, completely overwriting existing tags on the object

Tagger.toggleTags(inObjects, inTags)Promise

Toggles the tags on an PlaceableObject or Document. If a tag is present, it will be removed. If it not present, it will be added.

Tagger.addTags(inObjects, inTags)Promise

Adds tags to an object

Tagger.removeTags(inObjects, inTags)Promise

Removes tags from an object

Tagger.clearAllTags(inObjects)Promise

Removes all tags from PlaceableObjects

Tagger.applyTagRules(inObjects)Promise

Applies all tag rules to every tag found on the given PlaceableObjects

Tag Rules

Tag rules that are applied on object creation.

## Tagger.getByTag(inTags, inOptions) ⇒ Array Examples: ```js // Find objects whose tags contain "tag_to_find" const objects = Tagger.getByTag("tag_to_find"); // Find objects with JUST and ONLY the tag "tag_to_find" const objects = Tagger.getByTag("tag_to_find", { matchExactly: true }); ``` Gets PlaceableObjects with matching tags provided to the method **Returns**: Array - Returns an array of filtered Documents (or PlaceableObjects when `returnObjects` is true) based on the tags | Param | Type | Description | | --- | --- | --- | | inTags | String/RegExp/Array.<String/RegExp> | An array of tags or a string of tags (separated by commas) that will be searched for | | inOptions | Object | An optional object that can contain any of the following:
- `matchAny` {Boolean} - whether the PlaceableObjects can contain any of the provided tags
- `matchExactly` {Boolean} - whether the tags on the PlaceableObjects must contain ONLY the tags provided
- `caseInsensitive` {Boolean} - whether the search is case insensitive (capitals vs lowercase is not considered)
- `allScenes` {Boolean} - whether to search in all scenes, this will return an object with the key as the scene ID, and an array for objects found within that scene
- `objects` {Array} - an array of PlaceableObjects to test
- `ignore` {Array} - an array of PlaceableObjects to ignore
- `sceneId` {String} - a string ID for the scene to search in
- `returnObjects` {Boolean} - if true, returns the canvas PlaceableObject instances instead of the underlying Documents (falls back to the Document when the placeable is not on the active canvas) | ## Tagger.hasTags(inObjects, inTags, inOptions) ⇒ Boolean Examples: ```js // Whether the selected token has the tag "tag_to_find" const objects = Tagger.hasTags(token, "tag_to_find"); // Whether the token has a tag that resembles "tag_to_find" or "TAG_TO_FIND" or "tAg_To_FiNd" const objects = Tagger.hasTags(token, "TAG_to_FIND", { caseInsensitive: true }); ``` Verifies whether a given PlaceableObject or Document has the tags given **Returns**: Boolean - Returns a boolean whether the object has the given tags | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | A PlaceableObject, or an array of PlaceableObjects to check for tags on | | inTags | String/Array | An array of tags or a string of tags (separated by commas) that will be searched for | | inOptions | Object | An optional object that can contain any of the following:
- `matchAny` {Boolean} - whether the PlaceableObjects can contain any of the provided tags
- `matchExactly` {Boolean} - whether the tags on the PlaceableObjects must contain ONLY the tags provided
- `caseInsensitive` {Boolean} - whether the search is case insensitive (capitals vs lowercase is not considered) | ## Tagger.getTags(inObject) ⇒ Array Example: ```js // If the token has several tags, this method will return all of those tags as an array const tags = Tagger.getTags(token); ``` Gets all tags from a given PlaceableObject or Document **Returns**: Array - An array of tags from the Document | Param | Type | Description | | --- | --- | --- | | inObject | PlaceableObject | The PlaceableObject or Document get tags from | ## Tagger.setTags(inObjects, inTags) ⇒ Promise Examples: ```js // Sets the tags on the token to be ONLY "tag_to_set" await Tagger.setTags(token, "tag_to_set"); // You can also set multiple tags with an array await Tagger.setTags(token, ["tag_to_set", "tag_to_also_set"]); // Or as a string with each tag separated with a comma await Tagger.setTags(token, "tag_to_set, tag_to_also_set"); ``` Set the tags on an PlaceableObject or Document, **completely overwriting existing tags on the object** **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | A PlaceableObject, or an array of PlaceableObjects to set tags on | | inTags | String/Array | An array of tags or a string of tags (separated by commas) that will override all tags on the PlaceableObjects | ## Tagger.toggleTags(inObjects, inTags) ⇒ Promise Examples: ```js // If the token had the tag "tag_to_toggle", it no longer has it await Tagger.toggleTags(token, "tag_to_toggle"); // You can also toggle multiple tags with an array await Tagger.toggleTags(token, ["tag_to_toggle", "tag_to_also_toggle"]); // Or as a string with each tag separated with a comma await Tagger.toggleTags(token, "tag_to_toggle, tag_to_also_toggle"); ``` Toggles the tags on an PlaceableObject or Document. If a tag is present, it will be removed. If it not present, it will be added. **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | A PlaceableObject, or an array of PlaceableObjects to toggle tags on | | inTags | String/Array | An array of tags or a string of tags (separated by commas) that will be toggled on the PlaceableObjects | ## Tagger.addTags(inObjects, inTags) ⇒ Promise Example: ```js // Adds "tag_to_add" to the token's existing tags await Tagger.addTags(token, "tag_to_add"); ``` Adds tags to an object **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | A PlaceableObject, or an array of PlaceableObjects to add tags to | | inTags | String/Array | An array of tags or a string of tags (separated by commas) that will be added to the PlaceableObjects | ## Tagger.removeTags(inObjects, inTags) ⇒ Promise Example: ```js // Removes "tag_to_remove" from the token's tags await Tagger.removeTags(token, "tag_to_remove"); ``` Removes tags from an object **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | A PlaceableObject, or an array of PlaceableObjects to remove tags from | | inTags | String/Array | An array of tags or a string of tags (separated by commas) that will be removed from the PlaceableObjects | ## Tagger.clearAllTags(inObjects) ⇒ Promise Example: ```js // Clears all tags from the given object await Tagger.clearAllTags(token); ``` Removes all tags from PlaceableObjects **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | The PlaceableObjects to remove all tags from | ## Tagger.applyTagRules(inObjects) ⇒ Promise Example: ```js // If the token has a tag that looks like this: "test_{#}_tag", running this method: await Tagger.applyTagRules(token); // The tag will now be "test_1_tag", but the number depends on how many other objects in the scene that also has that same tag ``` Applies all tag rules to every tag found on the given PlaceableObjects **Returns**: Promise - A promise that will resolve when the PlaceableObjects' tags have been updated | Param | Type | Description | | --- | --- | --- | | inObjects | PlaceableObject/Array | The PlaceableObjects to apply tag rules to | ## Tag Rules | Tag Rule | Description | | -------- | ----------- | | `{#}` | The `{#}` gets replaced with an unique number, and the number depends on how many other objects in the scene also has that tag | | `{id}` | The `{id}` gets replaced with an unique ID |