# `MishkaCmsCore.Runtime.PreviewHooks`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/preview_hooks.ex#L5)

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.

# `resolve`

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
