View Source Beacon.Config (Beacon v0.2.1)
Configuration for sites.
Each site is started with this configuration and its values are stored in a registry that can be fetched at runtime
or updated with update_value/3
.
See new/1
for available options and examples.
Summary
Types
Register specific media types allowed for upload. Catchalls are not allowed.
A module that implements Beacon.RuntimeCSS
.
Default meta tags added to new pages.
Host application Endpoint module.
Add extra fields to pages.
Add extra fields to pages.
Add extra fields to pages.
Attach steps into Beacon's internal life-cycle stages to inject custom functionality.
Life-cycle stages.
Path of a LiveView socket where Beacon should connect to.
Individual media type configs
Register providers and validations for media types. Catchalls are allowed.
Defines the mode which the site will operate.
Host application Repo module.
Host application Router module.
Check safety of Elixir code using https://github.com/TheFirstAvenger/safe_code
Path to a custom Tailwind config.
Path to a custom Tailwind CSS
Register formats to handle templates, eg: [{:heex, "HEEx (HTML)"}]
.
Functions
From a Beacon.Config
, fetch the asset config for a given media type, raising when unsuccessful.
Returns the Beacon.Config
for site
.
Searches a config option for the given media type.
Build a new %Beacon.Config{}
instance to hold the entire configuration for each site.
Updates key
with value
for the site
configuration, at runtime.
Types
@type allowed_media_accept_types() :: [media_type :: String.t()]
Register specific media types allowed for upload. Catchalls are not allowed.
@type css_compiler() :: module()
A module that implements Beacon.RuntimeCSS
.
Default meta tags added to new pages.
@type endpoint() :: module()
Host application Endpoint module.
Add extra fields to pages.
@type extra_asset_fields() :: [extra_asset_field()]
Add extra fields to pages.
@type extra_page_fields() :: [module()]
Add extra fields to pages.
@type lifecycle() :: [lifecycle_stage()]
Attach steps into Beacon's internal life-cycle stages to inject custom functionality.
@type lifecycle_stage() :: {:load_template, [ {format :: String.t(), [ {identifier :: atom(), fun :: (template :: String.t(), Beacon.Template.LoadMetadata.t() -> {:cont, String.t()} | {:halt, String.t()} | {:halt, Exception.t()})} ]} ]} | {:render_template, [ {format :: String.t(), [ {identifier :: atom(), fun :: (Beacon.Template.t(), Beacon.Template.RenderMetadata.t() -> {:cont, Beacon.Template.t()} | {:halt, Beacon.Template.t()} | {:halt, Exception.t()})} ]} ]} | {:after_create_page, [ {identifier :: atom(), fun :: (Beacon.Content.Page.t() -> {:cont, Beacon.Content.Page.t()} | {:halt, Exception.t()})} ]} | {:after_update_page, [ {identifier :: atom(), fun :: (Beacon.Content.Page.t() -> {:cont, Beacon.Content.Page.t()} | {:halt, Exception.t()})} ]} | {:after_publish_page, [ {identifier :: atom(), fun :: (Beacon.Content.Page.t() -> {:cont, Beacon.Content.Page.t()} | {:halt, Exception.t()})} ]} | {:upload_asset, [ {identifier :: atom(), fun :: (Ecto.Schema.t(), Beacon.MediaLibrary.UploadMetadata.t() -> {:cont, any()} | {:halt, Exception.t()})} ]}
Life-cycle stages.
@type live_socket_path() :: String.t()
Path of a LiveView socket where Beacon should connect to.
@type media_type_config() :: [ processor: processor_fun :: (Beacon.MediaLibrary.UploadMetadata.t() -> Beacon.MediaLibrary.UploadMetadata.t()), validations: [ validation_fun :: (Ecto.Changeset.t(), Beacon.MediaLibrary.UploadMetadata.t() -> Ecto.Changeset.t()) | {validation_fun :: (Ecto.Changeset.t(), Beacon.MediaLibrary.UploadMetadata.t() -> Ecto.Changeset.t()), validation_config :: term()} ], providers: [ provider :: module() | {provider :: module(), provider_config :: term()} ] ]
Individual media type configs
@type media_type_configs() :: [{media_type :: String.t(), media_type_config()}]
Register providers and validations for media types. Catchalls are allowed.
@type mode() :: :live | :testing | :manual
Defines the mode which the site will operate.
Default is :live
which will load resources during boot, broadcast events on content change,
and execute operations asyncly. That's the normal mode for production.
The :testing
mode is suited for testing environments,
you should always use it when running tests that involve Beacon resources.
And the :manual
mode is similar to :testing
but it won't boot load any resource,
it's useful to seed data.
You can always change to :live
mode at runtime by calling Beacon.boot/1
.
@type option() :: {:site, Beacon.Types.Site.t()} | {:endpoint, endpoint()} | {:router, router()} | {:repo, repo()} | {:mode, mode()} | {:css_compiler, css_compiler()} | {:tailwind_config, tailwind_config()} | {:tailwind_css, tailwind_css()} | {:live_socket_path, live_socket_path()} | {:safe_code_check, safe_code_check()} | {:template_formats, template_formats()} | {:assets, media_type_configs()} | {:allowed_media_accept_types, allowed_media_accept_types()} | {:lifecycle, lifecycle()} | {:extra_page_fields, extra_page_fields()} | {:extra_asset_fields, extra_asset_fields()} | {:default_meta_tags, default_meta_tags()}
@type repo() :: module()
Host application Repo module.
@type router() :: module()
Host application Router module.
@type safe_code_check() :: boolean()
Check safety of Elixir code using https://github.com/TheFirstAvenger/safe_code
@type t() :: %Beacon.Config{ allowed_media_accept_types: allowed_media_accept_types(), assets: media_type_configs(), css_compiler: css_compiler(), default_meta_tags: default_meta_tags(), endpoint: endpoint(), extra_asset_fields: extra_asset_fields(), extra_page_fields: extra_page_fields(), lifecycle: lifecycle(), live_socket_path: live_socket_path(), mode: mode(), repo: repo(), router: router(), safe_code_check: safe_code_check(), site: Beacon.Types.Site.t(), tailwind_config: tailwind_config(), tailwind_css: tailwind_css(), template_formats: template_formats() }
@type tailwind_config() :: Path.t()
Path to a custom Tailwind config.
Example
# use the config file `priv/tailwind.config.js` from your app named `my_app`
Path.join(Application.app_dir(:my_app, "priv"), "tailwind.config.js")
See Beacon.RuntimeCSS.TailwindCompiler
for more info.
@type tailwind_css() :: Path.t()
Path to a custom Tailwind CSS
Note that Tailwind base, components, and utilities must be imported in this file.
Example
# use the file `assets/css/app.css` from your app named `my_app`
Path.join([Application.app_dir(:my_app, "assets"), "css", "app.css"])
See Beacon.RuntimeCSS.TailwindCompiler
for more info.
Register formats to handle templates, eg: [{:heex, "HEEx (HTML)"}]
.
Beacon provides two formats built-in, HEEx and Markdown, but you can register your own
as long as you also implement the life-cycle stages :load_template
and :render_template
.
The description is used on user interfaces as Beacon Admin.
Functions
@spec config_for_media_type(t(), String.t()) :: media_type_config()
From a Beacon.Config
, fetch the asset config for a given media type, raising when unsuccessful.
Example
iex> beacon_config = Beacon.Config.fetch!(:some_site)
iex> jpeg_config = config_for_media_type(beacon_config, "image/jpeg")
@spec fetch!(Beacon.Types.Site.t()) :: t()
Returns the Beacon.Config
for site
.
@spec get_media_type_config(media_type_configs(), String.t()) :: media_type_config() | nil
@spec get_media_type_config(extra_asset_fields(), String.t()) :: extra_asset_field() | nil
Searches a config option for the given media type.
For config options based on media type, such as :assets
and :extra_asset_fields
,
this function will check for the presence of media_type
, returning the config for
that specific type, or nil
if the type is not present.
Examples
iex> beacon_config = Beacon.Config.fetch!(:some_site)
iex> jpeg_config = config_for_media_type(beacon_config.assets, "image/jpeg")
iex> beacon_config = Beacon.Config.fetch!(:some_site)
iex> webp_config = config_for_media_type(beacon_config.extra_asset_fields, "image/webp")
iex> beacon_config = Beacon.Config.fetch!(:some_site)
iex> nil = config_for_media_type(beacon_config.assets, "invalid/foo")
Build a new %Beacon.Config{}
instance to hold the entire configuration for each site.
Options
:site
-Beacon.Types.Site.t/0
(required):endpoint
-endpoint/0
(required):router
-router/0
(required):repo
-repo/0
(required):mode
-mode/0
(optional). Defaults to:live
.css_compiler
-css_compiler/0
(optional). Defaults toBeacon.RuntimeCSS.TailwindCompiler
.:tailwind_config
-tailwind_config/0
(optional). Defaults toPath.join(Application.app_dir(:beacon, "priv"), "tailwind.config.bundle.js")
.:tailwind_css
-tailwind_css/0
(optional). Defaults toPath.join(Application.app_dir(:beacon, "priv"), "tailwind.css")
.:live_socket_path
-live_socket_path/0
(optional). Defaults to"/live"
.:safe_code_check
-safe_code_check/0
(optional). Defaults tofalse
.:template_formats
-template_formats/0
(optional).Defaults to:
[ {:heex, "HEEx (HTML)"}, {:markdown, "Markdown (GitHub Flavored version)"} ]
Note that the default config is merged with your config.
lifecycle
-lifecycle/0
(optional).
Note that the default config is merged with your config.
:extra_page_fields
-extra_page_fields/0
(optional). Defaults to[]
.:extra_asset_fields
-extra_asset_fields/0
(optional). Defaults to[]
.:default_meta_tags
-default_meta_tags/0
(optional). Defaults to%{}
.
Example
iex> Beacon.Config.new(
site: :my_site,
endpoint: MyAppWeb.Endpoint,
router: MyAppWeb.Router,
repo: MyApp.Repo,
tailwind_config: Path.join(Application.app_dir(:my_app, "priv"), "tailwind.config.js"),
tailwind_css: Path.join([Application.app_dir(:my_app, "assets"), "css", "app.css"]),
template_formats: [
{:custom_format, "My Custom Format"}
],
lifecycle: [
load_template: [
{:custom_format,
[
validate: fn template, _metadata -> MyEngine.validate(template) end
]}
],
render_template: [
{:custom_format,
[
assigns: fn %Phoenix.LiveView.Rendered{static: template} , %{assigns: assigns} -> MyEngine.parse_to_html(template, assigns) end
]}
],
after_publish_page: [
notify_admin: fn page -> {:cont, MyApp.Admin.send_email(page)} end
]
]
)
%Beacon.Config{
site: :my_site,
endpoint: MyAppWeb.Endpoint,
router: MyAppWeb.Router,
repo: MyApp.Repo,
mode: :live,
css_compiler: Beacon.RuntimeCSS.TailwindCompiler,
tailwind_config: "/my_app/priv/tailwind.config.js",
tailwind_css: "/my_app/assets/css/app.css",
live_socket_path: "/live",
safe_code_check: false,
template_formats: [
heex: "HEEx (HTML)",
markdown: "Markdown (GitHub Flavored version)",
custom_format: "My Custom Format"
],
media_types: ["image/jpeg", "image/gif", "image/png", "image/webp"],
assets:[
{"image/*", [providers: [Beacon.MediaLibrary.Provider.Repo], validations: [&SomeModule.some_function/2]]},
],
lifecycle: [
load_template: [
heex: [],
markdown: [
convert_to_html: &Beacon.Template.Markdown.convert_to_html/2,
],
custom_format: [
validate: #Function<41.3316493/2 in :erl_eval.expr/6>
]
],
render_template: [
heex: [],
markdown: [],
custom_format: [
assigns: #Function<41.3316493/2 in :erl_eval.expr/6>
]
],
after_create_page: [],
after_update_page: [],
after_publish_page: [
notify_admin: #Function<42.3316493/1 in :erl_eval.expr/6>
],
upload_asset: [],
],
extra_page_fields: [],
extra_asset_fields: [],
default_meta_tags: []
}
@spec update_value(Beacon.Types.Site.t(), atom(), any()) :: t() | :error
Updates key
with value
for the site
configuration, at runtime.