View Source Beacon.Config (Beacon v0.1.0-rc.0)

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.

Host application Repo module.

Host application Router module.

Disables site booting.

t()

Path to a custom tailwind config.

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

Link to this type

allowed_media_accept_types()

View Source
@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.

@type default_meta_tags() :: [%{required(binary()) => binary()}]

Default meta tags added to new pages.

@type endpoint() :: module()

Host application Endpoint module.

@type extra_asset_field() :: {media_type :: String.t(), [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 option() ::
  {:site, Beacon.Types.Site.t()}
  | {:endpoint, endpoint()}
  | {:router, router()}
  | {:repo, repo()}
  | {:skip_boot?, skip_boot?()}
  | {:css_compiler, css_compiler()}
  | {:tailwind_config, tailwind_config()}
  | {: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 skip_boot?() :: boolean()

Disables site booting.

Disables inserting default content data and routes, loading modules, and broadcasting events that trigger actions in Beacon lifecycle.

See Beacon.boot/1 for more info.

@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(),
  repo: repo(),
  router: router(),
  safe_code_check: safe_code_check(),
  site: Beacon.Types.Site.t(),
  skip_boot?: skip_boot?(),
  tailwind_config: tailwind_config(),
  template_formats: template_formats()
}
@type tailwind_config() :: Path.t()

Path to a custom tailwind config.

Example

# use the config file `priv/tailwind.config.js` in your app named `my_app`
Path.join(Application.app_dir(:my_app, "priv"), "tailwind.config.js")

See Beacon.RuntimeCSS.TailwindCompiler for more info.

@type template_formats() :: [{format :: atom(), description :: String.t()}]

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

Link to this function

config_for_media_type(beacon_config, media_type)

View Source
@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.

Link to this function

get_media_type_config(configs, media_type)

View Source
@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")
@spec new([option()]) :: t()

Build a new %Beacon.Config{} instance to hold the entire configuration for each site.

Options

Note that the default config is merged with your config.

Note that the default config is merged with your config.

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"),
  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,
  skip_boot?: false,
  css_compiler: Beacon.RuntimeCSS.TailwindCompiler,
  tailwind_config: "/my_app/priv/tailwind.config.js",
  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: []
}
Link to this function

update_value(site, key, value)

View Source
@spec update_value(Beacon.Types.Site.t(), atom(), any()) :: t() | :error

Updates key with value for the site configuration, at runtime.