Combo.Template.CEExEngine.Assigns (combo v0.9.0)

View Source

Provides assigns related helpers.

Summary

Functions

Adds key-value pairs to assigns.

Adds a key-value pair to assigns.

Adds the given key with value from fun into assigns if one does not yet exist.

Filters assigns as a list of keywords for use as tag attributes.

Functions

assign(conn, keyword_or_map_or_fun)

Adds key-value pairs to assigns.

Accepts a keyword list, a map, or a single-argument function.

When a keyword list or map is given as the second argument, it merges into the existing assigns.

When a function is given as the second argument, it takes the current assigns as an argument and merges its return value into the existing assigns.

Examples

iex> assign(assigns, name: "Combo", lang: "Elixir")
iex> assign(assigns, %{name: "Combo", lang: "Elixir"})
iex> assign(assigns, fn %{name: name, lang: lang} ->
...>   %{title: Enum.join([name, lang], " | ")}
...> end)

assign(assigns, key, value)

Adds a key-value pair to assigns.

Examples

iex> assign(assigns, :name, "Combo")

assign_new(assigns, key, fun)

Adds the given key with value from fun into assigns if one does not yet exist.

This function is useful for lazily assigning values.

Examples

iex> assign_new(assigns, :name, fn -> "Combo" end)
iex> assign_new(assigns, :new_name, fn assigns -> "new" <> assigns[:name] end)

Use cases - lazy assigns

Imagine a card component:

<.card bg_color="red" />

The bg_color is optional, so you can skip it:

<.card />

In such case, the implementation can use assign_new/1 to lazily assign a color if none is given.

def card(assigns) do
  assigns = assign_new(assigns, :bg_color, fn -> "green" end)

  ~CE"""
  <div class={@bg_color}>
    Example Card
  </div>
  """
end

assigns_to_attrs(assigns, exclude \\ [])

Filters assigns as a list of keywords for use as tag attributes.

The second argument is optional, and it is a list of keys to exclude. It typically includes reserved keys by the component itself, which either do not belong in the markup, or are already handled explicitly by the component.

It is recommended to use attr macro of :global type provided by Combo.Template.CEExEngine.DeclarativeAssigns rather than this function.

Examples

Imagine the following link component which allows a caller to pass a new_window assign, along with any other attributes they would like to add to the element, such as class, data attributes, etc:

<.link to="/" new_window={true} id="sku-1" class="underline">Home</.link>

We could support the dynamic attributes with the following component:

def link(assigns) do
  target = if assigns[:new_window], do: "_blank", else: false
  rest = assigns_to_attrs(assigns, [:new_window, :to])

  assigns =
    assigns
    |> assign(:target, target)
    |> assign(:rest, rest)

  ~CE"""
  <a href={@to} target={@target} {@rest}>
    {render_slot(@inner_block)}
  </a>
  """
end

The above would result in the following rendered HTML:

<a href="/" target="_blank" id="sku-1" class="underline">Home</a>