View Source Add Custom Page Fields
Every Beacon page contains a set of pre-defined fields which behave the same way across all pages. For example, the Title and Description fields are used to fill meta tags for SEO purposes; that's the same behavior regardless of whether the page is your homepage, a blog post, or something else.
However, you often need to store custom data, perform some logic on that data, or display extra information on the page. Some examples include tags for blog posts, authors, links, and so on.
In this recipe we'll add a custom page field Type
to allow users identify the type of the page on the admin interface and use that data to list recent blog posts.
Add a module that implements the Beacon.Content.PageField
behavior
In this module we'll define how the data is stored and validated, and how the field is displayed on the admin interface. Create a file with this content:
defmodule MyApp.Beacon.PageFields.Type do
@moduledoc false
@behaviour Beacon.Content.PageField
use Phoenix.Component
import Beacon.Web.CoreComponents
import Ecto.Changeset
@impl true
def name, do: :type
@impl true
def type, do: :string
@impl true
def default, do: "page"
@impl true
def changeset(data, attrs, %{page_changeset: _page_changeset}) do
cast(data, attrs, [:type])
end
@impl true
def render(assigns) do
assigns = Map.put(assigns, :opts, [{"Page", "page"}, {"Blog Post", "blog_post"}])
~H"""
<.input type="select" label="Type" prompt="Choose type" options={@opts} field={@field} />
"""
end
end
Let's break down each part of the module:
name/0
- can be any atom that represents the field name, for example:tags
for a lists of tags or:author_id
to store a reference to the page author.type/0
- any valid Ecto Schema typedefault/0
- the value with which to pre-populate the fieldchangeset/3
- this is where you can add your own validation logic to that field (note:page_changeset
is the changeset for the%Beacon.Content.Page{}
itself)render/1
- the template to display the field on the page editor in Beacon LiveAdmin
Add the field to Beacon.Config
Next we'll configure Beacon to include this type for your pages. In application.ex
add to your
existing Beacon config:
sites: [
[
name: :my_site,
...
extra_page_fields: [
...
MyApp.Beacon.PageFields.Type
]
]
]
Access the field content
Now, when a page is created or updated with your custom field, the content will be stored in the :extra
field of the %Beacon.Content.Page{}
record, under the name of the custom field.
With the example code above, a page with type blog_post
will look like this:
%Beacon.Content.Page{
# ...
extra: %{"type" => "blog_post"},
}
You can make use of this field to filter pages on the backend or display that extra information in the page template!