Components and Pages: User-defined function components
We want to allow users to define their own function components. That will ~deprecate~ remove the existing my_component feature, see https://github.com/BeaconCMS/beacon/issues/84#issuecomment-1363221968
The first step is to define such function components:
Similar to the CoreComponents provided by Phoenix, Beacon will provide a UserComponents to hold user-defined components that can be created as:
Beacon.Components.create_component!(%{
site: "my_site",
name: "greet",
attrs: [
%{name: "name", type: "string", required: true}
],
body: """
<p>Hello, <%= @name %>!</p>
"""
})
Which internally compiles to:
defmodule BeaconWeb.LiveRenderer.UserComponents{site_hash} do
use Phoenix.Component
attr :name, :string, required: true
def greet(assigns) do
~H"""
<p>Hello, <%= @name %>!</p>
"""
end
end
And then one can use it in layouts and pages:
Beacon.Pages.create_page!(%{
path: "home",
site: "my_site",
layout_id: layout_id,
template: """
<main>
<BeaconWeb.Components.dynamic component={"greet"} name="Jane" />
</main>
"""
})
Notes:
- Name collision may happen by sharing the same module to hold all components. We could explore custom namespaces but keeping it simple for now.
@TheFirstAvenger thoughts?
@AZholtkevych this issue is a proposal to support Phoenix.Component, a way to reuse pieces of templates. That would be the building block of layouts and pages.
@leandrocp if you would like to take care of it in the future, you can provide time estimations later on)))
Thanks a lot
@leandrocp looks good. This is the natural evolution of what Beacon.Components.Component was intended to be, so I think we should morph that module/context into this feature. I wouldn't be opposed to just wiping out the my_component support in the same PR, forcing any users updating to make the swap. Supporting both at this point in the development process doesn't feel necessary.
I wouldn't be opposed to just wiping out the my_component support in the same PR
@TheFirstAvenger sounds good 👍🏻
Have the templates string not use ~H and a bare string means that editors or language support tools will need specialized support to highlight the template as HEEx after detecting the outer call.
Have the templates string not use
~Hand a bare string means that editors or language support tools will need specialized support to highlight the template as HEEx after detecting the outer call.
We have the same issue with page_helper and page_event which are Elixir code, but my understanding is that those functions are a low-level API which eventually will be consumed by Page Builder https://github.com/BeaconCMS/page_builder/issues/1#issue-1501449524 and we could even add a feature where users write .heex/.exs template files that are converted to those strings. For that reason I'd rather keep a string for now while we explore such options. Wdyt?
For that reason I'd rather keep a string for now while we explore such options. Wdyt?
Agreed. The target audience here for generating page content is not engineers, it is non-tech users. Asking users to add ~H to the data also locks us in if we need to pivot and use the code in a different way.
Closed by https://github.com/BeaconCMS/beacon/pull/423, https://github.com/BeaconCMS/beacon/pull/535, and https://github.com/BeaconCMS/beacon_live_admin/pull/160