Sayfa.Theme (Sayfa v0.5.0)

Copy Markdown View Source

Theme loading and layout resolution with inheritance.

A theme is a directory under themes/ containing layouts and optional static assets. Themes can inherit from a parent (defaulting to "default").

Layout resolution walks the inheritance chain: custom theme -> parent -> default.

Theme Directory Structure

themes/my_theme/
 layouts/
    article.html.eex
    custom.html.eex
 assets/
     css/
     images/

Configuration

config :sayfa, :site,
  theme: "my_theme",
  theme_parent: "default"

Examples

config = Sayfa.Config.resolve(theme: "my_theme")
dirs = Sayfa.Theme.resolve_layouts_dirs(config)
#=> ["themes/my_theme/layouts", ".../priv/default_theme/layouts"]

Summary

Functions

Copies theme assets to the output directory.

Finds the first existing layout file by walking the theme chain.

Returns an ordered list of layout directories for the theme chain.

Functions

copy_assets(config, output_dir)

@spec copy_assets(map(), String.t()) :: :ok

Copies theme assets to the output directory.

Copies files from themes/<name>/assets/ to <output_dir>/assets/. Does nothing if the theme has no assets directory.

Examples

Sayfa.Theme.copy_assets(config, "dist")

resolve_layout(layout_name, config)

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

Finds the first existing layout file by walking the theme chain.

Returns the path to the layout file, or nil if not found in any theme.

Examples

iex> config = %{theme: "default", theme_parent: "default"}
iex> path = Sayfa.Theme.resolve_layout("base", config)
iex> String.ends_with?(path, "base.html.eex")
true

iex> config = %{theme: "default", theme_parent: "default"}
iex> Sayfa.Theme.resolve_layout("nonexistent_layout_xyz", config)
nil

resolve_layouts_dirs(config)

@spec resolve_layouts_dirs(map()) :: [String.t()]

Returns an ordered list of layout directories for the theme chain.

Walks from the current theme through its parent(s) to the default theme. Only directories that exist are included.

Examples

iex> config = %{theme: "default", theme_parent: "default"}
iex> dirs = Sayfa.Theme.resolve_layouts_dirs(config)
iex> length(dirs) >= 1
true