# `MishkaBlog.Tag`
[🔗](https://github.com/mishka-group/mishka_blog/blob/v0.0.1/lib/mishka_blog/resources/tag.ex#L5)

Manages blog post tags in the MishkaBlog plugin with full versioning support.

This resource represents hierarchical tags that can categorize and organize blog posts.
Each tag belongs to a specific site and can have parent-child relationships for nested
organization (e.g., "Technology > Programming > Elixir"). Tags support multiple languages
through the language variant system for internationalized taxonomies.

Tags feature full version control through PaperTrail integration, tracking all changes
with snapshot-based history and the ability to restore previous versions. The resource
implements soft deletion via archival and provides comprehensive metadata management
for building tag clouds, navigation systems, and content discovery features.

Database-level constraints ensure data integrity with slug validation and prevention
of modifications to archived tags. Multi-tenant isolation ensures tags are properly
segregated between sites. The resource provides extensive API actions for external
integrations and maintains complete audit trails of all modifications.

# `t`

```elixir
@type t() :: %MishkaBlog.Tag{
  __lateral_join_source__: term(),
  __meta__: term(),
  __metadata__: term(),
  __order__: term(),
  aggregates: term(),
  archived_at: term(),
  calculations: term(),
  child_tags: term(),
  description: term(),
  editions: term(),
  id: term(),
  inserted_at: term(),
  language: term(),
  language_group_id: term(),
  language_variants: term(),
  latest_version: term(),
  listed_post_count: term(),
  master_language_variants: term(),
  master_posts: term(),
  master_posts_join_assoc: term(),
  name: term(),
  paper_trail_versions: term(),
  parent_tag: term(),
  parent_tag_id: term(),
  permissions: term(),
  post_count: term(),
  posts: term(),
  posts_join_assoc: term(),
  published_post_count: term(),
  recent_versions: term(),
  seo_tags: term(),
  site: term(),
  site_id: term(),
  slug: term(),
  sorted_versions: term(),
  tenant_posts: term(),
  tenant_posts_join_assoc: term(),
  updated_at: term(),
  version_count: term()
}
```

# `__guarded_change__`

Apply the full GuardedStruct pipeline (sanitize → validate → derive →
main_validator) to `attrs` and return either `{:ok, transformed_attrs}`
or `{:error, errors}`. Wire this into an `Ash.Resource.Change` to plug
guardedstruct rules into Ash's changeset pipeline.

The function is named `__guarded_change__` because it does more than
validate — it can also transform values (trim, downcase, slugify,
auto-fill, etc.) before they reach the data layer.

# `__guarded_field_meta__`

O(1) lookup of a field's compile-time metadata by name. Returns
`nil` for unknown fields.

# `__guarded_field_name_set__`

Compile-time-baked `MapSet` of every field name owned by the
`guardedstruct` block. Used by `GuardedStruct.AshResource.Change`
to decide, in O(1), whether a key in `changeset.atomics`
belongs to the pipeline.

# `default_short_name`

# `input`

```elixir
@spec input(values :: map() | Keyword.t()) :: map() | no_return()
```

Validates that the keys in the provided input are valid for at least one action on the resource.

Raises a KeyError error at compile time if not. This exists because generally a struct should only ever
be created by Ash as a result of a successful action. You should not be creating records manually in code,
e.g `%MyResource{value: 1, value: 2}`. Generally that is fine, but often with embedded resources it is nice
to be able to validate the keys that are being provided, e.g

```elixir
Resource
|> Ash.Changeset.for_create(:create, %{embedded: EmbeddedResource.input(foo: 1, bar: 2)})
|> Ash.create()
```

# `input`

```elixir
@spec input(values :: map() | Keyword.t(), action :: atom()) :: map() | no_return()
```

Same as `input/1`, except restricts the keys to values accepted by the action provided.

# `json_api_match_route`

# `primary_key_matches?`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
