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

Copy Markdown View Source

Makes a hook named for one site work while another site's draft is being previewed.

The problem this solves

A runtime hook is registered in the browser under its site's prefix — LocalhostClipboard, ApiMishkaToolsClipboard — because two sites may both have a clipboard and they are different code. MishkaCmsCore.Runtime.Compilers.JavaScriptCompiler.browser_name/2 is the one rule that decides that name.

So a template that names LocalhostClipboard works on the localhost site and nowhere else. On a published page that is correct and stays correct: the page belongs to a site, and a hook it cannot have is a hook it does not get.

A DRAFT PREVIEW is a different situation. It is an editing tool, reached by an unguessable token, and it exists to answer "what does this look like and does it work". A master administering three sites opens the same page on each of them, and the one that names another site's hook answers with a button that draws and does nothing — unknown hook found for "LocalhostClipboard" in the console and no other sign. The preview is where that is least useful, because it is the one place the author is asking the question.

What it does

Reads the name the author wrote as what it is — a PREFIX and a base — and points it at the base's hook on the site being previewed. LocalhostClipboard previewed under api-mishka-tools becomes ApiMishkaToolsClipboard: that site's own clipboard, its own code, nothing borrowed.

What it does not do

It never serves another site's code, so it moves nothing across a tenant boundary — the bundle is still only this site's hooks and the global ones. It never invents a hook: a name whose base this site does not have is left exactly as written, and behaves in the preview as it will in production. And it touches nothing outside the preview; the stored template is not rewritten.

Parsed rather than pattern-matched. phx-hook is an attribute on an element, and finding it by searching text would match it inside a string, a comment or an unrelated attribute. The parse only decides WHICH names change; each is then changed where it is written as that attribute, and every other byte of the template is the author's — writing the parsed tree back out re-ordered a component's classes and marked them !, which the preview's stylesheet, compiled from the stored template, has no rule for.

Summary

Functions

The template with every unresolvable hook name pointed at this site's hook of the same base.

Functions

resolve(template, site)

@spec resolve(String.t() | nil, map() | nil) :: String.t() | nil

The template with every unresolvable hook name pointed at this site's hook of the same base.

Returns the template unchanged when there is nothing to do, when the site is unknown, or when the template cannot be parsed — a preview that renders the author's markup is worth more than one that refuses over a hook name.