View Source Beacon.Content (Beacon v0.2.1)
The building blocks for composing web pages: Layouts, Pages, Components, Stylesheets, and Snippets.
Templates
Layout and Pages work together as pages require a layout to display its content, the minimal template for a layout that can exist is the following:
<%= @inner_content %>
And pages templates can be written in HEEx or Markdown formats.
Meta Tags
Meta Tags can are defined in 3 levels:
- Site - fixed meta tags displayed on all pages, see
default_site_meta_tags/0
- Layouts - applies to all pages used by the template.
- Page - only applies to the specific page.
Summary
Functions: Layouts
Returns an %Ecto.Changeset{}
for tracking layout changes.
Counts the total number of layouts based on the amount of pages.
Creates a layout.
Creates a layout.
Returns a map of attrs to load the default layout into new sites.
Returns the latest layout event.
Gets a single layout by id
.
Same as get_layout/2
but raises an error if no result is found.
Gets a single layout by clauses
.
Get latest published layout.
Returns all layout events with associated snapshot if available.
List layouts.
Returns all published layouts for site
.
Publishes layout
and reload resources to render the updated layout and pages.
Same as publish_layout/2
but accepts a site
and layout_id
with which to lookup the layout.
Updates a layout.
Functions: Pages
Returns an %Ecto.Changeset{}
for tracking page changes.
Counts the total number of pages based on the amount of pages.
Creates a new page that's not published.
Creates a page.
Returns the list of meta tags that are applied to all pages by default.
Returns the latest page event.
Gets a single page by id
.
Same as get_page/3
but raises an error if no result is found.
Gets a single page by clauses
.
Get latest published page.
Returns all page events with associated snapshot if available.
List pages.
Lists and search all published pages for site
.
Publish page
.
Same as publish_page/1
but accepts a site
and page_id
with which to lookup the page.
Publish multiple pages
.
Given a map of fields, stores this map as :extra
fields in a Page
.
Unpublish page
.
Updates a page.
Validate page
with the given params
.
Functions: Page Variants
Returns an %Ecto.Changeset{}
for tracking variant changes.
Creates a new page variant and returns the page with updated :variants
association.
Deletes a page variant and returns the page with updated :variants
association.
Updates a page variant and returns the page with updated :variants
association.
Functions: Stylesheets
Creates a stylesheet.
Creates a stylesheet, raising an error if unsuccessful.
Gets a single stylesheet by clauses
.
Returns the list of stylesheets for site
.
Updates a stylesheet.
Functions: Components
Returns an %Ecto.Changeset{}
for tracking component changes.
Returns an %Ecto.Changeset{}
for tracking component_attr changes.
Returns an %Ecto.Changeset{}
for tracking slot changes.
Returns an %Ecto.Changeset{}
for tracking slot_attr changes.
Returns a list of all existing component categories.
Counts the total number of components based on the amount of pages.
Creates a component.
Creates a component, raising an error if unsuccessful.
Creates a slot attr.
Creates a new component slot and returns the component with updated :slots
association.
Deletes a slot attr.
Deletes a component slot and returns the component with updated slots association.
Gets a single component by clauses
.
List components.
List components by name
.
Updates a component.
Updates a slot attr.
Updates a component slot and returns the component with updated :slots
association.
Functions: Snippets
Creates a snippet helper.
Creates a snippet helper, raising an error if unsuccessful.
Returns the list of snippet helpers for a site
.
Renders a snippet template
with the given assigns
.
Functions: Event Handlers
Returns an %Ecto.Changeset{}
for tracking event handler changes.
Creates a new event handler.
Creates an event handler, raising an error if unsuccessful.
Deletes an event handler.
Updates an event handler with the given attrs.
Functions: Error Pages
Returns an %Ecto.Changeset{}
for tracking error page changes.
Creates a new error page.
Creates a new error page, raising if the operation fails.
Returns attr data to load the default error_pages into new sites.
Deletes an error page.
Returns the error page for a given site and status code, or nil
if no matching error page exists.
Lists all error pages for a given site.
Lists all error pages for a given site, filtered by clauses
.
Updates an error page.
Functions: Live Data
Returns an %Ecto.Changeset{}
for tracking LiveDataAssign changes.
Returns an %Ecto.Changeset{}
for tracking LiveData :path
changes.
Creates a new LiveDataAssign.
Creates a new LiveData for scoping live data to pages.
Creates a new LiveData for scoping live data to pages, raising an error if unsuccessful.
Deletes LiveData.
Deletes LiveDataAssign.
Gets a single live data by clauses
.
Returns a list of all existing LiveDataAssign formats.
Query LiveData for a given site.
Updates LiveDataAssign.
Updates LiveDataPath.
Functions: Info Handlers
Returns an %Ecto.Changeset{}
for tracking info handler changes.
Creates a new info handler for creating shared handle_info callbacks.
Creates a info handler, raising an error if unsuccessful.
Deletes info handler.
Gets a single info handler by id
.
Same as get_info_handler/2
but raises an error if no result is found.
Lists all info handlers for a given site.
Updates a info handler.
Functions
Lists all event handlers for a given Beacon site.
Functions: Layouts
@spec change_layout(Beacon.Content.Layout.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking layout changes.
Example
iex> change_layout(layout, %{title: "New Home"})
%Ecto.Changeset{data: %Layout{}}
@spec count_layouts( Beacon.Types.Site.t(), keyword() ) :: non_neg_integer()
Counts the total number of layouts based on the amount of pages.
Options
:query
- filter rows count by query. Defaults tonil
, doesn't filter query.
@spec create_layout(map()) :: {:ok, Beacon.Content.Layout.t()} | {:error, Ecto.Changeset.t()}
Creates a layout.
Example
iex> create_layout(%{title: "Home"})
{:ok, %Layout{}}
@spec create_layout!(map()) :: Beacon.Content.Layout.t()
Creates a layout.
@spec default_layout() :: map()
Returns a map of attrs to load the default layout into new sites.
@spec get_latest_layout_event(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.LayoutEvent.t() | nil
Returns the latest layout event.
Useful to find the status of a layout.
Example
iex> get_latest_layout_event(:my_site, layout_id)
%LayoutEvent{event: :published}
@spec get_layout(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.Layout.t() | nil
Gets a single layout by id
.
Example
iex> get_layout(:my_site, "fd70e5fe-9bd8-41ed-94eb-5459c9bb05fc")
%Layout{}
@spec get_layout!(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.Layout.t()
Same as get_layout/2
but raises an error if no result is found.
@spec get_layout_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.Layout.t() | nil
Gets a single layout by clauses
.
Example
iex> get_layout_by(site, title: "blog")
%Layout{}
@spec get_published_layout(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.Layout.t() | nil
Get latest published layout.
This operation is cached.
@spec list_layout_events(Beacon.Types.Site.t(), Ecto.UUID.t()) :: [ Beacon.Content.LayoutEvent.t() ]
Returns all layout events with associated snapshot if available.
Example
iex> list_layout_events(:my_site, layout_id)
[
%LayoutEvent{event: :created, snapshot: nil},
%LayoutEvent{event: :published, snapshot: %LayoutSnapshot{}}
]
@spec list_layouts( Beacon.Types.Site.t(), keyword() ) :: [Beacon.Content.Layout.t()]
List layouts.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records. Defaults to 20.:page
- returns records from a specfic page. Defaults to 1.:query
- search layouts by title. Defaults tonil
, doesn't filter query.:preloads
- a list of preloads to load.:sort
- column in which the result will be ordered by. Defaults to:title
. Allowed values::title
,:template
,:meta_tags
,:resource_links
,:inserted_at
,:updated_at
.
@spec list_published_layouts(Beacon.Types.Site.t()) :: [Beacon.Content.Layout.t()]
Returns all published layouts for site
.
Layouts are extracted from the latest published Beacon.Content.LayoutSnapshot
.
@spec publish_layout(Beacon.Content.Layout.t()) :: {:ok, Beacon.Content.Layout.t()} | {:error, Ecto.Changeset.t() | term()}
Publishes layout
and reload resources to render the updated layout and pages.
Event + snapshot
This operation is serialized.
@spec publish_layout(Beacon.Types.Site.t(), Ecto.UUID.t()) :: {:ok, Beacon.Content.Layout.t()} | any()
Same as publish_layout/2
but accepts a site
and layout_id
with which to lookup the layout.
@spec update_layout(Beacon.Content.Layout.t(), map()) :: {:ok, Beacon.Content.Layout.t()} | {:error, Ecto.Changeset.t()}
Updates a layout.
Example
iex> update_layout(layout, %{title: "New Home"})
{:ok, %Layout{}}
Functions: Pages
@spec change_page(Beacon.Content.Page.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking page changes.
Example
iex> change_page(page, %{title: "My Campaign"})
%Ecto.Changeset{data: %Page{}}
@spec count_pages( Beacon.Types.Site.t(), keyword() ) :: integer()
Counts the total number of pages based on the amount of pages.
Options
:query
- filter rows count by query
@spec create_page(map()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Creates a new page that's not published.
Example
iex> create_page(%{"title" => "My New Page"})
{:ok, %Page{}}
attrs
may contain the following keys:
path
- String.t()title
- String.t()description
- String.t()template
- String.t()meta_tags
- list(map()) eg:[%{"property" => "og:title", "content" => "My New Site"}]
See Beacon.Content.Page
for more info.
The created page is not published automatically,
you can make as much changes you need and when the page
is ready to be published you can call publish_page/1
It will insert a created
event into the page timeline,
and no snapshot is created.
@spec create_page!(map()) :: Beacon.Content.Page.t()
Creates a page.
Raises an error if unsuccessful.
@spec default_site_meta_tags() :: [map()]
Returns the list of meta tags that are applied to all pages by default.
These meta tags can be overwritten or extended on a Layout or Page level.
@spec get_latest_page_event(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.PageEvent.t() | nil
Returns the latest page event.
Useful to find the status of a page.
Example
iex> get_latest_page_event(:my_site, page_id)
%PageEvent{event: :published}
@spec get_page(Beacon.Types.Site.t(), Ecto.UUID.t(), keyword()) :: Beacon.Content.Page.t() | nil
Gets a single page by id
.
Options
:preloads
- a list of preloads to load.
Examples
iex> get_page(:my_site, "dba8a99e-311a-4806-af04-dd968c7e5dae")
%Page{}
iex> get_page(:my_site, "dba8a99e-311a-4806-af04-dd968c7e5dae", preloads: [:layout])
%Page{layout: %Layout{}}
@spec get_page!(Beacon.Types.Site.t(), Ecto.UUID.t(), keyword()) :: Beacon.Content.Page.t()
Same as get_page/3
but raises an error if no result is found.
@spec get_page_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.Page.t() | nil
Gets a single page by clauses
.
Example
iex> get_page_by(site, path: "/contact")
%Page{}
@spec get_published_page(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.Page.t() | nil
Get latest published page.
This operation is cached.
@spec list_page_events(Beacon.Types.Site.t(), Ecto.UUID.t()) :: [ Beacon.Content.PageEvent.t() ]
Returns all page events with associated snapshot if available.
Example
iex> list_page_events(:my_site, page_id)
[
%PageEvent{event: :created, snapshot: nil},
%PageEvent{event: :published, snapshot: %PageSnapshot{}}
]
@spec list_pages( Beacon.Types.Site.t(), keyword() ) :: [Beacon.Content.Page.t()]
List pages.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records. Defaults to 20.:page
- returns records from a specfic page. Defaults to 1.:query
- search pages by path or title.:preloads
- a list of preloads to load.:sort
- column in which the result will be ordered by. Defaults to:path
. Allowed values::path
,:title
,:description
,:template
,:meta_tags
,:raw_schema
,:format
,:inserted_at
,:updated_at
.
@spec list_published_pages( Beacon.Types.Site.t(), keyword() ) :: [Beacon.Content.Page.t()]
Lists and search all published pages for site
.
Note that unpublished pages are not returned even if it was once published before, only the latest snapshot is considered.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records. Defaults to 20.:page
- returns records from a specfic page. Defaults to 1.:search
- search by either one or more fields or dynamic query function.Available fields: `path`, `title`, `format`, `extra`. Defaults to `nil` (do not apply search filter).
:sort
- column in which the result will be ordered by. Defaults to:title
.
Examples
iex> list_published_pages(:my_site, search: %{path: "/home", title: "Home Page"})
[%Page{}]
iex> list_published_pages(:my_site, search: %{extra: %{"tags" => "press"}})
[%Page{}]
iex> list_published_pages(:my_site, search: fn -> dynamic([q], fragment("extra->>'tags' ilike 'year-20%'")) end)
[%Page{}]
@spec publish_page(Beacon.Content.Page.t()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t() | term()}
Publish page
.
A new snapshot is automatically created to store the page data, which is used whenever the site or the page is reloaded. So you can keep editing the page as needed without impacting the published page.
This operation is serialized.
@spec publish_page(Beacon.Types.Site.t(), Ecto.UUID.t()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Same as publish_page/1
but accepts a site
and page_id
with which to lookup the page.
@spec publish_pages([Beacon.Content.Page.t()]) :: {:ok, [Beacon.Content.Page.t()]}
Publish multiple pages
.
Similar to publish_page/1
but defers loading dependent resources
as late as possible making the process faster.
@spec put_page_extra(Beacon.Content.Page.t(), map()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Given a map of fields, stores this map as :extra
fields in a Page
.
Any existing :extra
data for that Page will be overwritten!
@spec unpublish_page(Beacon.Content.Page.t()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Unpublish page
.
Note that page will be removed from your site and it will return error 404 for new requests.
@spec update_page(Beacon.Content.Page.t(), map()) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Updates a page.
Example
iex> update_page(page, %{title: "New Home"})
{:ok, %Page{}}
@spec validate_page(Beacon.Types.Site.t(), Beacon.Content.Page.t(), map()) :: Ecto.Changeset.t()
Validate page
with the given params
.
All Beacon.Content.PageField
are validated
Functions: Page Variants
@spec change_page_variant(Beacon.Content.PageVariant.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking variant changes.
Example
iex> change_page_variant(page_variant, %{name: "Variant A"})
%Ecto.Changeset{data: %PageVariant{}}
@spec create_variant_for_page(Beacon.Content.Page.t(), %{ name: binary(), template: binary(), weight: integer() }) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Creates a new page variant and returns the page with updated :variants
association.
@spec delete_variant_from_page( Beacon.Content.Page.t(), Beacon.Content.PageVariant.t() ) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Deletes a page variant and returns the page with updated :variants
association.
@spec update_variant_for_page( Beacon.Content.Page.t(), Beacon.Content.PageVariant.t(), map() ) :: {:ok, Beacon.Content.Page.t()} | {:error, Ecto.Changeset.t()}
Updates a page variant and returns the page with updated :variants
association.
Functions: Stylesheets
@spec create_stylesheet(map()) :: {:ok, Beacon.Content.Stylesheet.t()} | {:error, Ecto.Changeset.t()}
Creates a stylesheet.
Returns {:ok, stylesheet}
if successful, otherwise {:error, changeset}
.
Example
iex >create_stylesheet(%{
site: :my_site,
name: "override",
content: ~S|
@media (min-width: 768px) {
.md:text-red-400 {
color: red;
}
}
|
})
{:ok, %Stylesheet{}}
Note that escape characters must be preserved, so you should use ~S
to avoid issues.
@spec create_stylesheet!(map()) :: Beacon.Content.Stylesheet.t()
Creates a stylesheet, raising an error if unsuccessful.
Returns the new stylesheet if successful, otherwise raises a RuntimeError
.
Example
iex >create_stylesheet!(%{
site: :my_site,
name: "override",
content: ~S|
@media (min-width: 768px) {
.md:text-red-400 {
color: red;
}
}
|
})
%Stylesheet{}
Note that escape characters must be preserved, so you should use ~S
to avoid issues.
@spec get_stylesheet_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.Stylesheet.t() | nil
Gets a single stylesheet by clauses
.
Example
iex> get_stylesheet_by(site, name: "main")
%Stylesheet{}
@spec list_stylesheets(Beacon.Types.Site.t()) :: [Beacon.Content.Stylesheet.t()]
Returns the list of stylesheets for site
.
Example
iex> list_stylesheets()
[%Stylesheet{}, ...]
@spec update_stylesheet(Beacon.Content.Stylesheet.t(), map()) :: {:ok, Beacon.Content.Stylesheet.t()} | {:error, Ecto.Changeset.t()}
Updates a stylesheet.
Example
iex> update_stylesheet(stylesheet, %{name: new_value})
{:ok, %Stylesheet{}}
Functions: Components
@spec change_component(Beacon.Content.Component.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking component changes.
Example
iex> change_component(component, %{name: "Header"})
%Ecto.Changeset{data: %Component{}}
change_component_attr(component_attr, attrs, component_attr_names)
View Source@spec change_component_attr(Beacon.Content.ComponentAttr.t(), map(), [String.t()]) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking component_attr changes.
Example
iex> change_component_attr(component_attr, %{name: "Header"})
%Ecto.Changeset{data: %ComponentAttr{}}
iex> change_component_attr(component_attr, %{name: "Header"}, ["sites", ["pages"]])
%Ecto.Changeset{data: %ComponentAttr{}}
@spec change_component_slot(Beacon.Content.ComponentSlot.t(), map(), [String.t()]) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking slot changes.
Example
iex> change_component_slot(component_slot, %{name: "slot_a"}, ["slot_name_1])
%Ecto.Changeset{data: %ComponentSlot{}}
@spec change_slot_attr(Beacon.Content.ComponentSlotAttr.t(), map(), [String.t()]) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking slot_attr changes.
Example
iex> change_slot_attr(slot_attr, %{name: "Header"}, [])
%Ecto.Changeset{data: %ComponentSlotAttr{}}
@spec component_categories() :: [atom()]
Returns a list of all existing component categories.
@spec count_components( Beacon.Types.Site.t(), keyword() ) :: non_neg_integer()
Counts the total number of components based on the amount of pages.
Options
:query
- filter rows count by query. Defaults tonil
, doesn't filter query.
@spec create_component(map()) :: {:ok, Beacon.Content.Component.t()} | {:error, Ecto.Changeset.t()}
Creates a component.
Returns {:ok, component}
if successful, otherwise {:error, changeset}
.
Example
iex> create_component(attrs)
{:ok, %Component{}}
@spec create_component!(map()) :: Beacon.Content.Component.t()
Creates a component, raising an error if unsuccessful.
Returns the new component if successful, otherwise raises a RuntimeError
.
@spec create_slot_attr(Beacon.Types.Site.t(), map(), [String.t()]) :: {:ok, Beacon.Content.ComponentSlotAttr.t()} | {:error, Ecto.Changeset.t()}
Creates a slot attr.
Example
iex> create_slot_attr(site, attrs)
{:ok, %ComponentSlotAttr{}}
@spec create_slot_for_component(Beacon.Content.Component.t(), %{name: binary()}) :: {:ok, Beacon.Content.Component.t()} | {:error, Ecto.Changeset.t()}
Creates a new component slot and returns the component with updated :slots
association.
@spec delete_slot_attr(Beacon.Types.Site.t(), Beacon.Content.ComponentSlotAttr.t()) :: {:ok, Beacon.Content.ComponentSlotAttr.t()} | {:error, Ecto.Changeset.t()}
Deletes a slot attr.
@spec delete_slot_from_component( Beacon.Content.Component.t(), Beacon.Content.ComponentSlot.t() ) :: {:ok, Beacon.Content.Component.t()} | {:error, Ecto.Changeset.t()}
Deletes a component slot and returns the component with updated slots association.
@spec get_component_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.Component.t() | nil
Gets a single component by clauses
.
Example
iex> get_component_by(site, name: "header")
%Component{}
@spec list_components( Beacon.Types.Site.t(), keyword() ) :: [Beacon.Content.Component.t()]
List components.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records. Defaults to 20.:page
- returns records from a specfic page. Defaults to 1.:query
- search components by title. Defaults tonil
, doesn't filter query.:preloads
- a list of preloads to load.:sort
- column in which the result will be ordered by. Defaults to:name
.
@spec list_components_by_name(Beacon.Types.Site.t(), String.t()) :: [ Beacon.Content.Component.t() ]
List components by name
.
Example
iex> list_components_by_name(site, "header")
[%Component{name: "header"}]
@spec update_component(Beacon.Content.Component.t(), map()) :: {:ok, Beacon.Content.Component.t()} | {:error, Ecto.Changeset.t()}
Updates a component.
iex> update_component(component, %{name: "new_component"})
{:ok, %Component{}}
@spec update_slot_attr( Beacon.Types.Site.t(), Beacon.Content.ComponentSlotAttr.t(), map(), [String.t()] ) :: {:ok, Beacon.Content.ComponentAttr.t()} | {:error, Ecto.Changeset.t()}
Updates a slot attr.
iex> update_slot(slot_attr, %{name: "new_slot"})
{:ok, %ComponentSlotAttr{}}
update_slot_for_component(component, slot, attrs, component_slots_names)
View Source@spec update_slot_for_component( Beacon.Content.Component.t(), Beacon.Content.ComponentSlot.t(), map(), [ String.t() ] ) :: {:ok, Beacon.Content.Component.t()} | {:error, Ecto.Changeset.t()}
Updates a component slot and returns the component with updated :slots
association.
Functions: Snippets
@spec create_snippet_helper(map()) :: {:ok, Beacon.Content.Snippets.Helper.t()} | {:error, Ecto.Changeset.t()}
Creates a snippet helper.
Returns {:ok, helper}
if successful, otherwise {:error, changeset}
@spec create_snippet_helper!(map()) :: Beacon.Content.Snippets.Helper.t()
Creates a snippet helper, raising an error if unsuccessful.
Returns the new helper if successful, otherwise raises a RuntimeError
.
@spec list_snippet_helpers(Beacon.Types.Site.t()) :: [ Beacon.Content.Snippets.Helper.t() ]
Returns the list of snippet helpers for a site
.
Example
iex> list_snippet_helpers()
[%SnippetHelper{}, ...]
@spec render_snippet(String.t(), %{ page: %{ site: Beacon.Types.Site.t(), path: String.t(), title: String.t(), description: String.t(), meta_tags: [map()], raw_schema: Beacon.Types.JsonArrayMap.t(), order: integer(), format: atom(), extra: map() }, live_data: map() }) :: {:ok, String.t()} | {:error, Beacon.SnippetError.t()}
Renders a snippet template
with the given assigns
.
Snippets are small pieces of string with interpolated assigns.
Think of it as small templates.
Examples
iex> Beacon.Content.render_snippet("title is {{ page.title }}", %{page: %{title: "home"}})
{:ok, "title is home"}
Snippets use the Liquid template under the hood, which means that all filters are available for use, eg:
iex> Beacon.Content.render_snippet("{{ 'title' | capitalize }}", assigns)
{:ok, "Title"}
In situations where the Liquid filters are not enough, you can create helpers to process the template using regular Elixir.
In the next example a author_name
is created to simulate a query to fetch the author's name:
iex> page = Beacon.Content.create_page(%{site: "my_site", extra: %{"author_id": 1}})
iex> Beacon.Content.create_snippet_helper(%{site: "my_site", name: "author_name", body: ~S"""
...> author_id = get_in(assigns, ["page", "extra", "author_id"])
...> MyApp.fetch_author_name(author_id)
...> """
iex> Beacon.Snippet.render("Author is {{ helper 'author_name' }}", %{page: page})
{:ok, "Author is Anon"}
Note that the :page
assigns is made available as assigns["page"]
(String.t) due to how Solid works.
Snippets can be used in:
- Meta Tag value
- Page Schema (structured Schema.org tags)
- Page Title
Allowed assigns:
- :page (map)
- :live_data (map)
Functions: Event Handlers
@spec change_event_handler(Beacon.Content.EventHandler.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking event handler changes.
Example
iex> change_event_handler(event_handler, %{name: "form-submit"})
%Ecto.Changeset{data: %EventHandler{}}
@spec create_event_handler(%{ name: binary(), code: binary(), site: Beacon.Types.Site.t() }) :: {:ok, Beacon.Content.EventHandler.t()} | {:error, Ecto.Changeset.t()}
Creates a new event handler.
@spec create_event_handler!(map()) :: Beacon.Content.EventHandler.t()
Creates an event handler, raising an error if unsuccessful.
@spec delete_event_handler(Beacon.Content.EventHandler.t()) :: {:ok, Beacon.Content.EventHandler.t()} | {:error, Ecto.Changeset.t()}
Deletes an event handler.
@spec update_event_handler(Beacon.Content.EventHandler.t(), map()) :: {:ok, Beacon.Content.EventHandler.t()} | {:error, Ecto.Changeset.t()}
Updates an event handler with the given attrs.
Functions: Error Pages
@spec change_error_page(Beacon.Content.ErrorPage.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking error page changes.
Example
iex> change_error_page(error_page, %{status: 404})
%Ecto.Changeset{data: %ErrorPage{}}
@spec create_error_page(%{ site: Beacon.Types.Site.t(), status: Beacon.Content.ErrorPage.error_status(), template: binary(), layout_id: Ecto.UUID.t() }) :: {:ok, Beacon.Content.ErrorPage.t()} | {:error, Ecto.Changeset.t()}
Creates a new error page.
@spec create_error_page!(%{ site: Beacon.Types.Site.t(), status: Beacon.Content.ErrorPage.error_status(), template: binary(), layout_id: Ecto.UUID.t() }) :: Beacon.Content.ErrorPage.t()
Creates a new error page, raising if the operation fails.
@spec default_error_pages() :: [map()]
Returns attr data to load the default error_pages into new sites.
@spec delete_error_page(Beacon.Content.ErrorPage.t()) :: {:ok, Beacon.Content.ErrorPage.t()} | {:error, Ecto.Changeset.t()}
Deletes an error page.
@spec get_error_page(Beacon.Types.Site.t(), Beacon.Content.ErrorPage.error_status()) :: Beacon.Content.ErrorPage.t() | nil
Returns the error page for a given site and status code, or nil
if no matching error page exists.
@spec list_error_pages( Beacon.Types.Site.t(), keyword() ) :: [Beacon.Content.ErrorPage.t()]
Lists all error pages for a given site.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records.:preloads
- a list of preloads to load.
@spec list_error_pages_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.Layout.t() | nil
Lists all error pages for a given site, filtered by clauses
.
Currently the only acceptable clause is :layout_id
.
See list_error_pages/2
for a list of acceptable opts
.
@spec update_error_page(Beacon.Content.ErrorPage.t(), map()) :: {:ok, Beacon.Content.ErrorPage.t()} | {:error, Ecto.Changeset.t()}
Updates an error page.
Functions: Live Data
@spec change_live_data_assign(Beacon.Content.LiveDataAssign.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking LiveDataAssign changes.
Example
iex> change_live_data_assign(live_data_assign, %{format: :elixir, value: "Enum.random(1..100)"})
%Ecto.Changeset{data: %LiveDataAssign{}}
@spec change_live_data_path(Beacon.Content.LiveData.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking LiveData :path
changes.
Example
iex> change_live_data(live_data, %{path: "/foo/:bar_id"})
%Ecto.Changeset{data: %LiveData{}}
@spec create_assign_for_live_data(Beacon.Content.LiveData.t(), map()) :: {:ok, Beacon.Content.LiveData.t()} | {:error, Ecto.Changeset.t()}
Creates a new LiveDataAssign.
@spec create_live_data(map()) :: {:ok, Beacon.Content.LiveData.t()} | {:error, Ecto.Changeset.t()}
Creates a new LiveData for scoping live data to pages.
Returns {:ok, live_data}
if successful, otherwise {:error, changeset}
@spec create_live_data!(map()) :: Beacon.Content.LiveData.t()
Creates a new LiveData for scoping live data to pages, raising an error if unsuccessful.
Returns the new LiveData if successful, otherwise raises a RuntimeError
.
@spec delete_live_data(Beacon.Content.LiveData.t()) :: {:ok, Beacon.Content.LiveData.t()} | {:error, Ecto.Changeset.t()}
Deletes LiveData.
@spec delete_live_data_assign( Beacon.Content.LiveDataAssign.t(), Beacon.Types.Site.t() ) :: {:ok, Beacon.Content.LiveDataAssign.t()} | {:error, Ecto.Changeset.t()}
Deletes LiveDataAssign.
@spec get_live_data_by(Beacon.Types.Site.t(), keyword(), keyword()) :: Beacon.Content.LiveData.t() | nil
Gets a single live data by clauses
.
Example
iex> get_live_data_by(site, id: "cba9ee2e-d40e-48af-9704-1237e4c23bde")
%LiveData{}
iex> get_live_data_by(site, path: "/blog")
%LiveData{}
@spec live_data_assign_formats() :: [atom()]
Returns a list of all existing LiveDataAssign formats.
@spec live_data_for_site(Beacon.Types.Site.t(), Keyword.t()) :: [String.t()]
Query LiveData for a given site.
Options
:per_page
- limit how many records are returned, or pass:infinity
to return all records.:query
- search records by path.:select
- returns only the given field(s):preload
- include given association(s) (defaults to:assigns
)
@spec update_live_data_assign( Beacon.Content.LiveDataAssign.t(), Beacon.Types.Site.t(), map() ) :: {:ok, Beacon.Content.LiveDataAssign.t()} | {:error, Ecto.Changeset.t()}
Updates LiveDataAssign.
iex> update_live_data_assign(live_data_assign, :my_site, %{code: "true"})
{:ok, %LiveDataAssign{}}
@spec update_live_data_path(Beacon.Content.LiveData.t(), String.t()) :: {:ok, Beacon.Content.LiveData.t()} | {:error, Ecto.Changeset.t()}
Updates LiveDataPath.
iex> update_live_data_path(live_data, "/foo/bar/:baz_id")
{:ok, %LiveData{}}
Functions: Info Handlers
@spec change_info_handler(Beacon.Content.InfoHandler.t(), map()) :: Ecto.Changeset.t()
Returns an %Ecto.Changeset{}
for tracking info handler changes.
Example
iex> change_info_handler(info_handler, %{code: {:noreply, socket}})
%Ecto.Changeset{data: %InfoHandler{}}
@spec create_info_handler(map()) :: {:ok, Beacon.Content.InfoHandler.t()} | {:error, Ecto.Changeset.t()}
Creates a new info handler for creating shared handle_info callbacks.
Example
iex> create_info_handler(%{site: "my_site", msg: "{:new_msg, arg}", code: "{:noreply, socket}"})
{:ok, %InfoHandler{}}
@spec create_info_handler!(map()) :: Beacon.Content.InfoHandler.t()
Creates a info handler, raising an error if unsuccessful.
Returns the new info handler if successful, otherwise raises a RuntimeError
.
Example
iex> create_info_handler!(%{site: "my_site", msg: "{:new_msg, arg}", code: "{:noreply, socket}"})
%InfoHandler{}
@spec delete_info_handler(Beacon.Content.InfoHandler.t()) :: {:ok, Beacon.Content.InfoHandler.t()} | {:error, Ecto.Changeset.t()}
Deletes info handler.
@spec get_info_handler(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.InfoHandler.t() | nil
Gets a single info handler by id
.
Example
iex> get_single_info_handler(:my_site, "fefebbfe-f732-4119-9116-d031d04f5a2c")
%InfoHandler{}
@spec get_info_handler!(Beacon.Types.Site.t(), Ecto.UUID.t()) :: Beacon.Content.InfoHandler.t()
Same as get_info_handler/2
but raises an error if no result is found.
@spec list_info_handlers(Beacon.Types.Site.t()) :: [Beacon.Content.InfoHandler.t()]
Lists all info handlers for a given site.
Example
iex> list_info_handlers()
@spec update_info_handler(Beacon.Content.InfoHandler.t(), map()) :: {:ok, Beacon.Content.InfoHandler.t()}
Updates a info handler.
Example
iex> update_info_handler(info_handler, %{msg: "{:new_msg, arg}"})
{:ok, %InfoHandler{}}
Functions
@spec list_event_handlers(Beacon.Types.Site.t()) :: [Beacon.Content.EventHandler.t()]
Lists all event handlers for a given Beacon site.