MishkaCmsCore.Runtime.Snippet (Mishka CMS Core v0.0.1)

Copy Markdown View Source

A named piece of markup an author saved out of the visual editor to reuse somewhere else.

A snippet is the editor's own clipboard made durable: source is the same HEEx the canvas serialises, so inserting one is the same operation as inserting a palette example — parse, place, done. Nothing about it is kit-specific, which is why it lives here rather than under the UI-kit handler.

Two things scope it:

  • scope — :page keeps it beside the document it was saved from (document_id), :shared offers it anywhere on the site. The Studio's chips are exactly these two plus "all".
  • section — which editor it came from (page, layout, error_page, component). A layout's header markup is rarely what an error page wants, and offering it there is noise.

Multitenancy is global? true, matching MishkaCmsCore.Runtime.Layout: a row with a nil site_id is a snippet every site can insert, which only a master user can create.

Blocks, byte size and the swatch tint are NOT stored — they are read off source by MishkaCmsCore.Runtime.PageBuilder.Snippets, so they cannot drift from the markup they describe.

Summary

Functions

Turns the save box's visibility choice into the attributes the create action actually stores.

Puts the editor's own scoping onto a :for_editor query, from the table's path_params.

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

t()

@type t() :: %MishkaCmsCore.Runtime.Snippet{
  __lateral_join_source__: term(),
  __meta__: term(),
  __metadata__: term(),
  __order__: term(),
  aggregates: term(),
  calculations: term(),
  document_id: term(),
  id: term(),
  inserted_at: term(),
  name: term(),
  scope: term(),
  section: term(),
  site: term(),
  site_id: term(),
  source: term(),
  updated_at: term()
}

Functions

apply_visibility(params, state)

@spec apply_visibility(map(), map()) :: map()

Turns the save box's visibility choice into the attributes the create action actually stores.

The radio posts one of "page", "shared" or "global" because "All sites" is a site_id decision while the other two are scope decisions — one control, two columns. The editor's own context (which section, which document, which site) rides in on the form's defaults, so the author never has to restate what the editor already knows.

site_id is written only for a master. A tenant's :create action does not accept it — it forces the value from the tenant — and Ash rejects an input an action does not accept, so sending it would turn every tenant save into an error.

default_short_name()

for_editor_arguments(query, state)

@spec for_editor_arguments(Ash.Query.t(), map()) :: Ash.Query.t()

Puts the editor's own scoping onto a :for_editor query, from the table's path_params.

The keys are PREFIXED — :editor_site_id, not :site_id. Gervaz turns any path param whose name matches an attribute into an equality filter, and site_id == X would drop exactly the global rows (site_id nil) this read exists to include.

input(opts)

@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

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

input(opts, action)

@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.

primary_key_matches?(left, right)