Cherry.Theme.Resolver (cherry v0.6.1)

Copy Markdown View Source

The three-level template lookup: site overlay → theme → framework.

Three levels, never more (Hugo's specificity matrix is the cautionary tale), and always printable via cherry theme.which. Overlays are keyed per-theme (themes/<theme-name>/templates/…) so swapping themes never silently applies overrides written for a different theme.

Summary

Functions

The full lookup chain for a template: {level, path, exists?} in priority order. The first existing entry wins.

The .html.heex twin of an .html.eex template path.

Where a site's overlay file for this theme + template would live, or nil when the theme is site-local.

Resolves a template to the winning {level, path}.

Whether this theme is loaded from inside the site itself.

Functions

chain(site, theme, name)

@spec chain(Cherry.Site.t(), Cherry.Theme.t(), atom()) :: [
  {atom(), Path.t(), boolean()}
]

The full lookup chain for a template: {level, path, exists?} in priority order. The first existing entry wins.

Each level offers two candidates — <name>.html.heex, then <name>.html.eex — so a HEEx rewrite wins over the EEx original at the same level, and a site overlay in either language beats the theme.

heex_variant(path)

@spec heex_variant(Path.t()) :: Path.t()

The .html.heex twin of an .html.eex template path.

overlay_path(site, theme, name)

@spec overlay_path(Cherry.Site.t(), Cherry.Theme.t(), atom()) :: Path.t() | nil

Where a site's overlay file for this theme + template would live, or nil when the theme is site-local.

An overlay only means something relative to an installed theme. A theme that lives inside the site — what cherry gen.theme writes, and what theme: "themes/mine" selects — owns its templates outright, so the overlay path would land on the theme's own files and report every one of them as untracked drift.

resolve(site, theme, name)

@spec resolve(Cherry.Site.t(), Cherry.Theme.t(), atom()) ::
  {:ok, {atom(), Path.t()}} | {:error, String.t()}

Resolves a template to the winning {level, path}.

site_local?(site, theme)

@spec site_local?(Cherry.Site.t(), Cherry.Theme.t()) :: boolean()

Whether this theme is loaded from inside the site itself.

Built-in themes are never site-local, wherever they live on disk: when Cherry is a dependency, its priv/ (and the official themes in it) sits under the site's own _build, which is inside the site root — without the exception, every hex-dep site would lose overlays entirely.