Skip to content

township-agency/ex_teal_pages

Repository files navigation

ExTealPages

A Simple ExTeal Plugin that pretends to be a CMS for KV Pairs. Use it for application settings, or static copy.

Installation

The package can be installed by adding ex_teal_pages to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_teal_pages, "~> 0.2"}
  ]
end

Add the plugin to your manifest:

  def plugins, do: [
    ExTealPages.new(%{
      pages: []
    })
  ]

Point ex_teal_pages at the schema you want it to manage for storing values:

config :ex_teal_pages,
  copy_schema: MyApp.CMS.Copy

Where MyApp.CMS.Copy looks like:

defmodule MyApp.CMS.Copy do
  @moduledoc false
  use Ecto.Schema
  import Ecto.Changeset

  schema "copy" do
    field :data, :map
    field :key, :string
    field :label, :string

    timestamps()
  end

  @doc false
  def changeset(copy, attrs) do
    copy
    |> cast(attrs, [:data, :key, :label])
    |> validate_required([:data, :key, :label])
  end
end

with a migration that looks like:

defmodule MyApp.Repo.Migrations.CreateCopy do
  use Ecto.Migration

  def change do
    create table(:copy) do
      add :data, :map
      add :key, :string
      add :label, :string

      timestamps()
    end

    create index(:copy, [:key])
  end
end

A word to the wise

Be sure that you seed any initial values for rows you want to manage in the copy schema. This plugin will only update, not insert.

Adding Pages

Write a new module for the page you want to manage:

defmodule MyAppWeb.ExTeal.Pages.PaginationSettings do
  @moduledoc """
  Page for default pagination values
  """
  use ExTealPages.Page

  alias ExTeal.Fields.Number

  def title, do: "Pagination Settings"

  def key, do: "pagination"

  def fields,
    do: [
      Number.make(:page_size)
    ]
end

Tell ex_teal_pages to manage the page in the manifest:

def plugins,
  do: [
    ExTealPages.new(%{
      pages: [PaginationSettings]
    })
  ]

Navigate to the page in /teal and profit!

Advanced Content

ResourceField

You can nest a resource index inside of a page. For example, you might have a list of careers on an about us page that you only want to display in Teal inside the context of an AboutUs page:

defmodule MyAppWeb.ExTeal.Pages.AboutUs do
  @moduledoc """
  Content of the About Us Page
  """

  use ExTealPages.Page

  alias ExTeal.Fields.RichText
  alias ExTealPages.ResourceField

  def fields,
    do: [
      RichText.make(:about_us_overview, "Overview"),
      ResourceField.make(:quotes),
      ResourceField.make(:careers)
    ]
end

ArrayField

You can use ArrayField.mut() to transform a KV field into a fieldset that contains a fixed length list of keys and values. For example:

def fields,
  do: [
    ExTeal.Fields.Text.make(:header_copy) |> ArrayField.mut()
  ]

Given an initial value of:

%{
  key: "header_copy",
  data: %{
    content_array: [
      %{
        title: "Greeting",
        content: "Hello Teal!"
      },
      %{
        title: "Description",
        content: "This is Teal. It's very fancy."
      },
      %{
        title: "People",
        content: "The cool people of Township built this thing"
      }
    ]
  }
}

Teal will render a panel with three text fields, all labeled based on their title.