How to handle generated html attributes in heex?

Hi, I’m working through an upgrade of live view, gone from 15 step by step up to 17, fab.
Currently working through all our legacy ~E references scattered in various helpers.

I’ve come upon one I’m a bit stuck on.

Here is the code snippet, its not within a component ( at the moment )

assigns =
      %{}
      |> Map.put(:video_tag_transformations, video_tag_transformations)
      |> Map.put(:video_poster_attribute, video_poster_attribute)
      |> Map.put(:transformed_url, transformed_url)
      |> Map.put(:classes, classes)
      |> Map.put(:should_autoplay_class, should_autoplay_class)

    ~H"""
    <video
      class={"#{@classes} #{@should_autoplay_class}"}
      {@video_tag_transformations}
      {@video_poster_attribute}
    >
      <source src={@transformed_url} /> Your browser does not support HTML5 video tags
    </video>
    """

Assigns holds values, the key ones are the video_tag_transformations and video_poster_attribute, these are built based on options passed.

video_poster_attribute: "",
video_tag_transformations: "loop controls muted preload=\"none\" playsinline controlsList=\"nodownload\"

The error I’m getting is:

** (Protocol.UndefinedError) protocol Enumerable not implemented for "loop controls muted preload=\"none\" playsinline controlsList=\"nodownload\"" of type BitString.

Which makes sense…

Under the old ~E this of course worked. I’ve been looking at the build_attrs(1) source to see a patten that would fit these video tag attrs, single words etc…

Anyone have any ideas or links to guides to aid me?

1.phoenix_html/phoenix_html.ex at master · phoenixframework/phoenix_html · GitHub

the <tag {@attrs} variables are expected to be maps or keyword lists. Boolean attributes are simply %{loop: boolean}, where the boolean will make the attribute be added if true and not added if false.

Brilliant. Thanks. I’d not thought to switch the input of strings into a map element list like that. Makes sense now I see it.

Thank you.