Spark DSL extension for rendering Typst templates as Ash generic actions.
This extension adds a typst DSL section to your Ash resource where you can
declare reusable templates and render actions. Each render action is transformed
into an Ash generic action that compiles and exports a Typst document, returning
an AshTypst.Document struct.
Usage
Add the extension to your resource:
defmodule MyApp.Invoice do
use Ash.Resource,
domain: MyApp.Domain,
extensions: [AshTypst.Resource]
typst do
root "priv/typst"
template :invoice do
source "invoice.typ"
inputs %{"company" => "Acme Corp"}
end
template :receipt do
# ~TYPST sigil is auto-imported in template blocks
markup ~TYPST"""
#import "data.typ": record, args
= Receipt #args.receipt_number
*Customer:* #record.name
"""
end
render :generate_pdf do
template :invoice
format :pdf
argument :invoice_id, :string, allow_nil?: false
read :one do
filter expr(id == ^arg(:invoice_id))
load [:line_items, :customer]
end
pdf_options do
pdf_standards [:pdf_a_2b]
end
end
end
endThen call the action like any other Ash generic action:
input = Ash.ActionInput.for_action(MyApp.Invoice, :generate_pdf, %{invoice_id: "123"})
{:ok, %AshTypst.Document{format: :pdf, data: pdf_binary}} = Ash.run_action(input)How It Works
Templates are declared in the
typstsection. Each template has either an inlinemarkupstring (the~TYPSTsigil is auto-imported insidetemplateblocks) or asourcefile path relative to therootdirectory.Render actions reference a template and specify an output
format(:pdf,:svg, or:html). They can optionally declare arguments, areadto fetch resource data, and format-specific options likepdf_options.At compile time, the
BuildActionstransformer converts each render entity into a standardAsh.Resource.Actions.Action.At runtime, the action implementation creates a context, sets the template, injects data (arguments and/or read results) into a virtual file, compiles, and exports in the requested format.
Data Injection
The render action injects data into a virtual file (default "data.typ") that your
template can #import:
- No read: only
args(a dictionary of action arguments) is available. - Read
:one: bothrecord(the single resource) andargsare available. - Read
:many:records(an array, streamed in batches) andargsare available.
DSL Reference
For the complete DSL reference with all options, see AshTypst.Resource.