MishkaCmsCore.Runtime.DraftPreviewAssets (Mishka CMS Core v0.0.5-alpha.5)

Copy Markdown View Source

Temporary, isolated CSS and compiled module for a runtime preview — a draft (Page/Layout/ErrorPage) or a live original reached by its preview_token — NEVER the live site bundle or the live page module.

The CSS is compiled on every request and kept nowhere (css/2): the saved stylesheets, Tailwind over the record's own markup (so a draft with brand-new classes is styled), and a draft's own element CSS (element_css) laid over its document's row as its publish writes it. A draft's CSS therefore lives in the draft alone, and goes when the draft is published or deleted. Served at /_preview/:resource/:token/css (see MishkaCmsWeb.DraftPreviewController), and linked by MishkaCmsWeb.DraftPreviewLive. JS is NOT compiled per-draft — the preview is a real LiveView that loads the site's existing JS bundle, which already exports every active hook (a draft template's phx-hook references JsHook rows in that bundle), so hooks run with no extra work. The token records the site its JS belongs to in AssetsState (remember_site/2) — the record's own, or for a global record the host's it is opened on — so the bundle is handed to whoever holds the link, by that site's state (site/1), on an address served_on?/2 allows.

A page or a layout is drawn by its compiled module (ensure_module/2), built by the compiler its site uses, so its own helpers and the live components it nests render as on the published page. The module is named after the token, so a draft never replaces the live one, and is compiled again only when the record was saved since or is opened on another site. purge/1 unloads it with the site, and MishkaCmsWeb.DraftPreviewLive unloads it when the preview closes.

Summary

Functions

The preview's temporary CSS, compiled now from the record as it is, as the site's own CSS is: the host shell, the global and the site's saved stylesheets, the record's own markup, and a draft's own element CSS laid over its document's element-CSS row (element_css, see MishkaCmsCore.Runtime.Authoring.Drafts).

The module a Page, Layout or one of their drafts is previewed with, compiled if missing or older than the record, against asset_site's hooks. {:ok, module}, or {:error, message} when it does not compile.

Delete the record's preview site and its compiled module (on publish / discard).

Records the site the preview's assets under the record's token belong to: the record's own, or for a global record asset_site, the host's it is opened on.

Whether a preview of a record of site_id (nil for a global one) may be served on the address of current_site, the site the request's host resolved to.

The site the preview's assets under token belong to: {:ok, site_id}, {:ok, nil} for a global record opened with no site, or :error when no preview has been opened under it.

Unloads the record's preview module. A process still drawing it keeps the old code, and the next ensure_module/2 compiles it again.

Functions

css(record, asset_site)

@spec css(map(), map() | nil) :: {:ok, String.t()} | :error

The preview's temporary CSS, compiled now from the record as it is, as the site's own CSS is: the host shell, the global and the site's saved stylesheets, the record's own markup, and a draft's own element CSS laid over its document's element-CSS row (element_css, see MishkaCmsCore.Runtime.Authoring.Drafts).

asset_site is the site a record with none of its own — a global layout — is compiled against: the host the preview is opened on.

NOTHING IS CACHED. A preview is opened to see the draft as it stands, so it is compiled on every call, a Tailwind pass of a few seconds. One record compiles one at a time: its markup is written to a temporary folder named after it, which a second compile alongside would delete under the first. Returns {:ok, css} or :error.

ensure_module(record, asset_site)

The module a Page, Layout or one of their drafts is previewed with, compiled if missing or older than the record, against asset_site's hooks. {:ok, module}, or {:error, message} when it does not compile.

A compile is the [:mishka_cms, :runtime, :draft_preview, :compile] span, with the module as its metadata: it starts in the calling process before it asks for the module's lock, and stops with the answer.

purge(record)

Delete the record's preview site and its compiled module (on publish / discard).

remember_site(record, asset_site)

Records the site the preview's assets under the record's token belong to: the record's own, or for a global record asset_site, the host's it is opened on.

served_on?(site_id, arg2)

@spec served_on?(String.t() | nil, map() | nil) :: boolean()

Whether a preview of a record of site_id (nil for a global one) may be served on the address of current_site, the site the request's host resolved to.

The master site's address serves every site's previews, and a site's own address serves its own. A global record belongs to every site, so any site's address serves it. Another site's address, or a request no site answers for, serves nothing: a preview of site A is never shown on site B.

served_on?(site_a_id, %{id: site_a_id, master: false})  #=> true
served_on?(site_a_id, %{id: master_id, master: true})   #=> true
served_on?(site_a_id, %{id: site_b_id, master: false})  #=> false
served_on?(nil, %{id: site_b_id, master: false})        #=> true

site(token)

The site the preview's assets under token belong to: {:ok, site_id}, {:ok, nil} for a global record opened with no site, or :error when no preview has been opened under it.

unload_module(record)

Unloads the record's preview module. A process still drawing it keeps the old code, and the next ensure_module/2 compiles it again.