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—:pagekeeps it beside the document it was saved from (document_id),:sharedoffers 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
@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
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.
@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.
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.