Best practice for streaming a template file with replaced strings

question

#1

I have a template file with a few placeholders. I want to replace the placeholders with actual values and pipe the result forward.
Currently I read the whole file, find all occurrences of the placeholders and replace them with their respective (pre-calculated) values, and then push that into some pipe (see example bellow).

Is there some better way of doing this (like connecting the pipe with some filter/switch in between)?

Example

open("file.txt", "w") do o
    txt = readstring("template_file.txt")
    for (k, v) in Dict("PLACEHOLDER1" => 3, "PLACEHOLDER2" => "this")
        txt = replace(txt, k, v)
    end
    print(o, txt)
end

where template_file.txt is:

apples: PLACEHOLDER1
and then: PLACEHOLDER2

This results in text.txt:

apples: 3
and then: this

Thanks!


#2

Perhaps you may be able to find matches with a regex that has alternation (“or”), and then replace the right one. But it may be more trouble than it is worth, and you have to think about placeholders that contain each other if that is relevant, so the order may matter.

If you have control over the placeholder format, choosing something like <id> may be feasible (or the zillion other syntaxes, eg {{ id }}), you just match the delimiters, extract id, and emit the output as concatenation or streaming into an IOBuffer(). This may be significantly faster.


#3

I like the Python solution to the template problem where you can use the format method of a string to replace fields with values in the correct format:

"""
Some long string with {value} in it.
""".format(value=2.3)

Your Julia solution is already pretty close, but we could do better and get inspiration from the Python interface.


#4

I’d like that.

I guess many templates are existing files. It would therefore make sense to be able to do this kind of “formating” on streams of text. Aside from @Tamas_Papp’s inception-style placeholders (i.e. placeholders within placeholders), maybe something simple would be feasible?


#5

I’ve used mustache before for similar purposes:

// mustache is what some javascript frameworks use to render pages ( i.e. if you’ve ever seen {{ user.name }} )


some example code that uses it:


#6

Wow !!! That’s great! I’ll use this instead. From my quick check it seems to satisfy everything we want (even IO streams).


#7

Mustache.jl is good. You also might look at Formatting.jl, which does
python-style formatting.

Cheers, Kevin