Here, I need some fast (rather simple) template system that gives me some data to send later to an SMTP server (the body of the mail).
First the code:
get(Template, Args) ->You'll find some unknown notation: '?engine' and $.
NewArgs = list_to_shell(Args),
Cmd = lists:flatten([ ?engine, $ , "conf/template/", Template, $ , NewArgs ]),
Port = open_port({spawn, Cmd}, [ {cd, code:lib_dir(mmailer)}, stream, binary]),
process_flag(trap_exit, true),
loop(Port).
- ?engine is a macro, defined like this -define(engine, "templater").
- $ is the character notation, the character that follows the dollar sign is the character I want. Actually I need the space character...
list_to_shell(Args) ->This function add a space after after element of the array passed as parameter. I construct the shell command this way.
L = lists:map(fun(X) -> [X, $ ] end, Args),
lists:flatten(L).
The call to open_port is the main part of the code:
Port = open_port({spawn, Cmd}, [ {cd, code:lib_dir(mmailer)}, stream, binary]),The following describe what the above line does:
- spawn the command 'Cmd'
- in the directory code:lib_dir(mmailer),
- this command will write data as a stream
- and I want erlang to give me a binary stream.
More about my engine... My engine takes as firts arguments the template file to parse and every other parameter is saved as $1, or $2, or $3 etc.
Example of a template 'test.template'
Hello $1 $2 !
We have a good news for you, join us at url/$3
So calling:
templater test.template Mister John connect?JohnWill compute the following:
Hello Mister John !
We have a good news for you, join us at url/connect?John
Conclusion, you can use whatever template system efficiently with the open_port function, since you can dynamically build the command line.
NB: I've not secure the line generated by list_to_shell, any '; rm -rf *' in the command line will do nasty things with your stuff :)