Hi, just accidentally found this thread, and also this one here: Todo-MVP: Or ‘Why You Shouldn’t Use A Web Framework’ - The Revenge – a nice read for web-dev interested folks, make sure to also read the original, first post. That made me try out some stuff in Julia to generate HTML (i.e. “define views”) on the fly, as you called it; just for fun
First approach was using the type system to actually build up something similar to a DOM and then traverse it to generate the overall string. Takes some microseconds to render a tiny snippet, so not a good idea.
The next idea was a macro. It’s actually only 30 LOCs, with a 2-LOC helper function. It can be used like this:
name = "Joe"
text = "This is a paragraph."
rep = "Repeat. "
htmlstr = @html begin
@h1 "Hello, $(name)!"
@div begin
@p text
@p rep^5
end
end
This results in the following string:
<h1>Hello, Joe!</h1>
<div>
<p>This is a paragraph.</p>
<p>Repeat. Repeat. Repeat. Repeat. Repeat. </p>
</div>
It took me quite some iterations on the macro to have it generate this string in a single call to String
(don’t recursively build it up by string concatenation, but collect all sub-strings, then have a single Expr(:call, :*, strings...)
). With that, it’s (almost*) as fast as typing it out by hand using string interpolation. The above example renders in 81 ns on my laptop.
*In this specific example, one intermediate string is formed by explicitly evaluating the interpolation "Hello, $(name)!"
.
One could use plain Julia to build (partial) views etc., for example:
function messages_view(messages)
foldl(messages, init="") do html, (name, greeting, message)
html * @html begin
@h1 "$(greeting), $((name))!"
@p message
end
end
end
println(messages_view([
(name = "Joe", greeting = "Hi", message = "You should really shave tomorrow!"),
(name = "Nora", greeting = "Cheerio", message = "How's life?"),
(name = "Chica Bonita", greeting = "Olà", message = "Wanna have a drink or two?")]))
(Actually was quite impressed to find out this destructuring capability of Julia; combined with the do
syntax that’s pretty awesome!)
What do you think? Any use for this? Possibly there are already other solutions around which I didn’t find… I feel like it does help with readability and cleanness quite a bit, since IDE’s do highlight the tags and the begin ... end
blocks visualising the structure. Next steps would be to add attributes (possibly class(es) and ID’s explicitly…?) and generally work on a cleaner and more complete implementation.
Edit: Was a bit too quick with my euphoria for NamedTuple
unpacking, cf. this Issue; seems the above is just positional unpacking in the accidentally correct order…