We already do something similar to that. Currently, the solid templates gets parsed and held inside ecto schemas (these schemas don’t map to a DB, just purely used for holding parsed configuration in memory/cache), and this occurs at compile time.
That compiler would first compile and evaluate the solid snippets, then inject them into your heex views. Then the regular EEx compiler would take over and still be able to detect any malformed html at compile time.
This is where I struggle to understand. Since the solid templates get parsed into a syntax specific to Solid and its renderer; any HTML therein would not have its full structure known until it’s fully rendered which is dependent on assigns available only at run time.
I don’t believe that’s necessarily a stopper, since the same issue exists with Heex, hence why you can’t do something like this (very) contrived example:
<%= if true do %>
<div class="some-class-true">
<% else %>
<div class="some-class-false">
<% end %>
....
</div>
I can already achieve this by simply doing something like:
template_string = Solid.parse("<h1>Hello {{ name }}</h1> <.my_component />")
# Parsed string above (done at compile time, held in configuration)
result =
template_string
|> Solid.render(%{"name" => "John"})
|> to_string()
|> EEx.eval_string(
[assigns: %{}],
functions: [{Components.Helpers, Components.Helpers.__info__(:functions)}],
engine: Phoenix.LiveView.HTMLEngine
)
# Heex template
assigns = %{result_example: result}
~H|<%= @result_example %>|
This works. The issue then becomes if there’s any invalid HTML in that solid template, it’s going to raise an error when it’s eval’d.
I’m just trying to think through any cases where that could potentially be avoided / surfaced at compile time. And I fear the answer is no, at least not without getting into the potential of writing our own parser.