Manages reusable UI components in the MishkaCMS runtime system.
This resource handles the lifecycle of dynamically compiled UI components that can be shared across different sites in a multi-tenant environment. Components are template-based building blocks supporting HEEx, EEx, and Markdown formats, with the ability to define custom attributes, slots, and helper functions. Each component can be scoped to a specific site or made globally available.
The resource implements soft deletion through archival, allowing components to be recovered after deletion. It enforces strict validation rules including name uniqueness per site, template presence, and priority ordering for rendering sequences. Components automatically trigger background compilation jobs when created, updated, or destroyed, integrating seamlessly with the runtime compiler system.
Database-level constraints and triggers ensure data integrity, particularly preventing modifications to archived components except for unarchiving operations. The resource supports permission-based access control and maintains full audit trails through timestamps.
Summary
Functions
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.
O(1) lookup of a field's compile-time metadata by name. Returns
nil for unknown fields.
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.
Validates that the keys in the provided input are valid for at least one action on the resource.
Same as input/1, except restricts the keys to values accepted by the action provided.
Types
@type t() :: %MishkaCmsCore.Runtime.Component{ __lateral_join_source__: term(), __meta__: term(), __metadata__: term(), __order__: term(), active: term(), aggregates: term(), archived_at: term(), attrs: term(), body: term(), calculations: term(), component_module: term(), dependencies: term(), description: term(), doc_url: term(), examples: term(), extra: term(), form_meta: term(), format: term(), furnishing: term(), has_examples: term(), helpers: term(), icon_name: term(), id: term(), inserted_at: term(), is_global: term(), latest_version: term(), name: term(), paper_trail_versions: term(), permissions: term(), precompile: term(), priority: term(), recent_versions: term(), required: term(), site: term(), site_id: term(), slots: term(), sorted_versions: term(), stateful: term(), template: term(), type: term(), ui_kit_label: term(), updated_at: term(), version_count: term(), version_preview: term() }
Functions
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.
O(1) lookup of a field's compile-time metadata by name. Returns
nil for unknown fields.
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.
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
Resource
|> Ash.Changeset.for_create(:create, %{embedded: EmbeddedResource.input(foo: 1, bar: 2)})
|> Ash.create()
Same as input/1, except restricts the keys to values accepted by the action provided.