MishkaCmsCore.Layouts (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Layouts shared by extension LiveViews.

Mirrors the host app's MishkaCmsWeb.Layouts module: one module holds the layout templates (auto-embedded from layouts/*.html.heex) and any helper components that belong to the chrome.

Wiring

Extension LiveViews opt in via MishkaCmsCore.ExtensionLiveView, which does use Phoenix.LiveView, layout: {MishkaCmsCore.Layouts, :app}. The result: every extension admin page is automatically wrapped by app.html.heex and gets the flash group without each template repeating it.

Why not reuse MishkaCmsWeb.Layouts?

Extensions compile before MishkaCmsWeb, so calling MishkaCmsWeb.Layouts.flash_group/1 from an extension template raises an "undefined" warning at compile time. This module is the extension-side counterpart and owns the flash chrome for everything under MishkaCmsCore.ExtensionLiveView.

Summary

Functions

The years the footer's copyright line covers, from 2026 up to today's year: "2026" during 2026, "2026-2027" in 2027, and so on.

Renders both :info and :error flashes from the @flash map.

The line under every admin page: "© <years> · Powered by <name>", where the name links to the product's own page.

The admin sidebar — logo, collapsible nav groups, and the active item highlighted from @current_path (set by MishkaCmsCore.Layouts.Nav). Groups collapse client-side via JS.toggle.

The admin topbar — search, theme toggle, notifications, and the user's menu: Account settings, the language the dashboard is read in, and Sign out.

Functions

app(assigns)

flash_group(assigns)

Renders both :info and :error flashes from the @flash map.

Styled with classes rather than style attributes. Every surface that renders this — the admin chrome via app.html.heex and the page builder shell — sets admin_css, so the compiled admin stylesheet is always there to carry them; the canvas iframe, the one admin surface without it, mounts with layout: false and never draws a flash. Keeping the colours in classes is what lets the policy in MishkaCmsCore.Runtime.Plugs.SecurityHeaders close style-src-attr, which no nonce can ever reopen for an attribute.

<.flash_group flash={@flash} />

Whatever the inner block holds is stacked under the notices — the admin chrome puts MishkaCmsCoreWeb.Live.Admin.Components.TranslationsRefusal there.

Attributes

  • flash (:map) (required)

Slots

  • inner_block

sidebar(assigns)

The admin sidebar — logo, collapsible nav groups, and the active item highlighted from @current_path (set by MishkaCmsCore.Layouts.Nav). Groups collapse client-side via JS.toggle.

The nav itself is data, not markup: MishkaCmsCore.Sidebar.menu/1 collects it from every extension's "sidebar:menus" plugin, drops what @current_user may not see, and orders it from Settings. This component only paints what it is handed, so an empty section is one that was filtered away rather than one that has to be spelled out here. version is @sidebar_version: the sidebar is drawn again each time it changes.

Attributes

  • current_path (:string) - Defaults to nil.
  • current_user (:any) - Defaults to nil.
  • version (:integer) - Defaults to 0.

topbar(assigns)

The admin topbar — search, theme toggle, notifications, and the user's menu: Account settings, the language the dashboard is read in, and Sign out.

language is the admin's language and languages the ones the menu offers (MishkaCmsCore.Layouts.Nav assigns both); picking one sends PUT /admin/language with current_path to come back to. Two are listed, the admin's own among them, and the rest behind "Show more".

Attributes

  • current_user (:any) - Defaults to nil.
  • notification_count (:integer) - Defaults to 0.
  • notification_recent (:list) - Defaults to [].
  • current_path (:string) - Defaults to nil.
  • language (:string) - Defaults to "en".
  • languages (:list) - Defaults to [].
  • sign_out (:string) - Defaults to "/auth/sign-out".