SparkPost / heml

HEML is an open source markup language for building responsive email.
https://heml.io
MIT License
4.33k stars 157 forks source link

Using with Blade templates #32

Closed davidbarker closed 6 years ago

davidbarker commented 6 years ago

Hello. HEML looks super useful! I'd like to use it to build our Blade templates (for use with Laravel), however, I'm wondering how to get around the following issue.

For example, in my Blade file, I use

<a href="http://{{ $domain }}/auth/verify/{{ $user['confirmation'] }}">@lang('email.confirm_button')</a>

I want the contents inside the {{ }} tags to effectively be ignored by HEML. It mostly works, but there's a problem with the quotation marks. Using the online editor, the above gives

<a href="http://{{ $domain }}/auth/verify/{{ $user[&#39;confirmation&#39;] }}" class="a"><span class="a__text">@lang('email.confirm_button')</span></a>

which is almost perfect, but the ' is replaced by &#39;.

If I include heml-ignore on the tag then the template parts work, but then I lose the HEML specific additions for a link.

<a href="http://{{ $domain }}/auth/verify/{{ $user['confirmation'] }}" heml-ignore="">@lang('email.confirm_button')</a>

Any ideas? Thanks!

avigoldman commented 6 years ago

Hey David 👋

Thanks so much for all the detail on this! I'm going dig into this one, and I'll post an update as soon as I have more info!

davidbarker commented 6 years ago

You're welcome — thanks for a great tool!

outcassed commented 6 years ago

I'm also using HEML with a template engine (ERB, which uses <% %> ). I had to choose some characters and then substitute them after heml building.

It would be great if there was some HEML tag for surrounding text that you'd like to be inserted into the HTML without any transformations. Like <t><%='Hello, World%></t>

edit hm. that idea wouldn't help davidbarker with using templates inside of HEML tag attributes. Maybe if you could configure the opening/closing tags that will surround things that should be left alone?

brunah commented 6 years ago

issue

brunah commented 6 years ago

Issue

LinusU commented 6 years ago

Hmm, isn't a better workflow to first process with the template engine, and then put it into HEML?

I think it could be very nice if the heml cli tool would allow to plug and play template engines into it, sort of like express does...

This approach will only work if you do invoke heml when rendering the final email though...

davidbarker commented 6 years ago

Well the values in the template will be replaced at runtime. So, before each email is sent it would have to run HEML on every email. Unless I'm misunderstanding you?

LinusU commented 6 years ago

Yeah, I didn't think of the use case of compiling the templates before, I'm currently rendering with heml directly when I make the email call and thus have no problem templating before. It's just a bit inconvenient when previewing the emails...

I didn't consider that you can also compile the heml first and then use it multiple times, my bad...

davidbarker commented 6 years ago

No problem! It's possible both ways, I suppose. I just like to generate the template once and know exactly what I'm sending out (minus the variables).

LinusU commented 6 years ago

Yeah, that's actually quite smart. Do you check in the compiled templates into source control?

davidbarker commented 6 years ago

I've not actually done it yet, but that's my plan. I'd have the HEML templates stored somewhere, run a Gulp command to generate the Blade files, and then probably check in both the HEML and the Blade. That way someone could recompile them if they change the HEML.

LinusU commented 6 years ago

I actually got quite lucky here, I'm using SES to send my emails and they actually support templating out of the box. My workflow ended up going (build time) HEML -> HTML -> SES Template.

I'm now convinced though that the the best way is to do HEML compilation first, and then templating. Since this avoids wasting a ton of cpu to do basically the same work over and over again.

So, could a solution to this problem be something like this:

We add some new configuration options, maybe { templateStartDelimiter: '{{', templateStopDelimiter: '}}' }

When these are set, heml will recognise the {{ and simply pass everything thru as is, without any extra quoting, until the }} is found. That way it will work when passing it to the template engine.

avigoldman commented 6 years ago

I like that idea @LinusU. Thought it would be nice to have this handled correctly by default. I don't imagine any situation where someone would want <a href="http://{{ $domain }}/auth/verify/{{ $user['confirmation'] }}"> to be encoded to <a href="http://{{ $domain }}/auth/verify/{{ $user[&#39;confirmation&#39;] }}" class="a">

Am I missing a use case where the current functionality is desired?

avigoldman commented 6 years ago

Digging into it, the problem is stemming from the stringify-attributes library. Its a fairly simple function, so I think the best solution is to pull the functionality in, without the escaping. Thoughts?

Edit: See #37 for the implemented solution

LinusU commented 6 years ago

Sounds good 👍

The only problem I can think of is that there are many different template systems out there. Ejs is quite common in the Node.js community and uses <% and %>. Some moustache flavours uses only a single { and }.

edit: didn't read the last message, seems good 👍

avigoldman commented 6 years ago

37 was merged in and released in 1.1.2!

davidbarker commented 6 years ago

Fantastic! I’m excited to try it out. Thank you so much, @avigoldman.