# `MishkaCmsCore.Runtime.Page`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/resources/page.ex#L5)

Manages web pages in the MishkaCMS runtime system with full versioning support.

This resource represents individual web pages that are dynamically compiled and rendered
at runtime. Pages are the core content units of the CMS, containing templates, metadata,
SEO configurations, and interactive elements. Each page belongs to a specific site and
can optionally use a layout for consistent structure. The resource supports various
template formats (HEEx, EEx, Markdown) and provides comprehensive content management
including sections, schemas, events, and helper functions.

Pages 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, priority-based ordering for path matching, and
precompilation options for performance optimization. Pages can define custom event handlers
for LiveView interactions and include resource links for external assets.

Database-level constraints ensure data integrity with path validation, template presence
checks, and prevention of modifications to archived pages. Multi-tenant isolation ensures
pages are properly segregated between sites. The resource provides extensive API actions
for external integrations and maintains complete audit trails of all modifications including
actor tracking and action recording.

# `t`

```elixir
@type t() :: %MishkaCmsCore.Runtime.Page{
  __lateral_join_source__: term(),
  __meta__: term(),
  __metadata__: term(),
  __order__: term(),
  active: term(),
  aggregates: term(),
  archived_at: term(),
  calculations: term(),
  content: term(),
  description: term(),
  events: term(),
  extra: term(),
  format: term(),
  helpers: term(),
  id: term(),
  infos: term(),
  inserted_at: term(),
  language: term(),
  language_group_id: term(),
  language_variants: term(),
  latest_version: term(),
  layout: term(),
  layout_id: term(),
  loaded_layout: term(),
  master_language_variants: term(),
  name: term(),
  page_module: term(),
  paper_trail_versions: term(),
  path: term(),
  permissions: term(),
  precompile: term(),
  preview_token: term(),
  priority: term(),
  recent_versions: term(),
  resource_links: term(),
  schema: term(),
  section: term(),
  seo_tags: term(),
  site: term(),
  site_id: term(),
  sorted_versions: term(),
  state: term(),
  template: term(),
  tenant_layout: term(),
  title: term(),
  updated_at: term(),
  uploads: term(),
  version_count: term(),
  version_preview: 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`

# `format_badge_config`

Format → badge colours and labels, in the shape the Gervaz `:badge` column type expects. Shared by the
Format table column and the page detail modal so both draw the same badge from one definition.

# `generate_token`

Unguessable token for the shareable preview URL (generated on create).

# `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*
