larslr

larslr

HEEX parsing breaks on (some) mjml

We are using MJML to template our emails within a Phoenix application. This has worked very well until now, when we started upgrading from Phoenix 1.6 to 1.7. Suddenly, the HEEX parser started caring a lot more about the contents of our mjml-heex, and specifically the tag.

This tag lets us define css elements analogously to the tag in regular HTML, which means that the HEEX parser will complain about the syntax. Digging a bit, I can see that the tokenizer has special handling for tags, but I can find no way of telling it to parse tags in the same way.

We’ve tried falling back to using the old ~L sigil for the section containing , but that is only a stopgap solution, as that sigil is deprecated.

Are there any other sigils that could be used? Or some other way to tell the parser not to care so much about certain segments?

Marked As Solved

chrismccord

chrismccord

Creator of Phoenix

<mj-style phx-no-curly-interpolation>

10
Post #7

Also Liked

jswanner

jswanner

I too use MJML in a phoenix app, but I parse the files with EEx instead of HEEX. Are you willing to go that route?

harmon25

harmon25

That helped me this week solving the same issue - but I also bumped up against debug notation causing some issues in dev without the ability to selectively disable it - mjml parser did not really like the html comments that were injected.

I was not using the annotations much - so I just disabled them

Last Post!

larslr

larslr

I’m not sure what you’re asking for, but here is a sketch of the situation I was asking about. We have a module which defines layouts for emails, e.g.:

 def basic_layout(assigns) do
    ~H"""
    <mjml>
      <mj-head>
        <mj-preview>{@preview}</mj-preview>
        <XXX.Email.Components.head />
      </mj-head>
      <mj-body ...>
        <mj-wrapper css-class="wrapper">
          <mj-section>
            <mj-column>
              {render_slot(@inner_block)}
            </mj-column>
          </mj-section>
        </mj-wrapper>
      ...
      </mj-body>
    </mjml>
    """
  end

The header component, with the previously troublesome <mj-style> tag:

  def head(assigns) do
    ~H"""
    <mj-font ... />

    <mj-attributes>
      <mj-all ... />
      <mj-button ... />
      ...
    </mj-attributes>

    <mj-style inline="inline" phx-no-curly-interpolation>
      .wrapper {
      border-radius: 14px;
      background-color: #FFF;
      border: 1px solid rgba(0,0,0,0.1);
      overflow: hidden;
      text-align: left;
      }
      .op3{
      opacity: 0.3;
      }
    </mj-style>
    """
  end

We can then use the layout in templates:

def render(assigns) do
    ~H"""
    <XXX.Email.Layouts.basic_layout preview=@preview>
      ... email body ...
    </XXX.Email.Layouts.basic_layout>
    """
  end

Rendering the template, both for previews and actual email bodies:

def render_heex_mjml(module, template, assigns) do
  {:ok, html_body} =
    Phoenix.Template.render(module, template, "html", assigns)
    |> Phoenix.HTML.Safe.to_iodata()
    |> Enum.join()
    |> Mjml.to_html()

  html_body
end

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36654 110
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

We're in Beta

About us Mission Statement