MishkaCmsCore.ExtensionLiveView (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Shared LiveView module for extensions.

Use this instead of MishkaCmsWeb, :live_view in extension LiveViews. Automatically embeds templates from the same directory.

Features

  • Phoenix.LiveView
  • Phoenix.HTML
  • Phoenix.Component
  • Phoenix.LiveView.JS
  • Gettext (translations)
  • CoreComponents (UI components: button, input, table, modal, etc.)
  • Runtime path helpers (path/2, url/2)
  • embed_templates (auto-loads .html.heex files from same directory)

Usage

# index.ex
defmodule MishkaBlogWeb.Live.Admin.Dashboard.Blogger.Index do
  use MishkaCmsCore.ExtensionLiveView

  @impl true
  def mount(_params, _session, socket) do
    {:ok, assign(socket, count: 10)}
  end
end

# index.html.heex (same directory)
<div class="container mx-auto px-4 py-8">
  <.header>
    Bloggers {@count}
    <:subtitle>Manage all bloggers</:subtitle>
    <:actions>
      <.button navigate={path(@socket, "/admin/dashboard/blog/bloggers/new")}>
        New Blogger
      </.button>
    </:actions>
  </.header>

  <.table id="bloggers" rows={@bloggers}>
    <:col :let={blogger} label="Name">{blogger.name}</:col>
    <:col :let={blogger} label="Email">{blogger.email}</:col>
  </.table>
</div>

Available Components

From MishkaCmsCore.CoreComponents:

  • <.button> - Buttons with navigation support
  • <.input> - Form inputs with labels and error handling
  • <.table> - Tables with streams support
  • <.flash> - Flash messages
  • <.header> - Page headers with actions
  • <.icon> - Heroicons
  • <.list> - Data lists

Path Helpers

Since extensions compile before the main CMS, they cannot use ~p sigils. Instead, use the runtime path helpers:

# In templates - use path/2 with @socket:
<.link navigate={path(@socket, "/admin/dashboard")}>Dashboard</.link>

# With dynamic segments:
<.link navigate={path(@socket, "/posts/#{@post.id}")}>View</.link>

# For full URLs:
url(@socket, "/posts/#{@post.id}")

Translations

Use gettext/1 for translations:

<h1>{gettext("Welcome")}</h1>
<p>{ngettext("1 item", "%{count} items", @count)}</p>