Text Templates in Erlang

Erlang offers built-in support for creating dynamic content or showing customized output to the user with its string formatting and IO functions. In this example, we’ll demonstrate how to create and use string templates in Erlang.

-module(text_templates).
-export([main/0]).

main() ->
    % We can create a new template as a string with placeholders.
    % In Erlang, we use ~p as a generic placeholder for any term.
    T1 = "Value is ~p~n",

    % By "executing" the template we generate its text with
    % specific values for its placeholders. We use io:format/2
    % to print the formatted string.
    io:format(T1, ["some text"]),
    io:format(T1, [5]),
    io:format(T1, [["Go", "Rust", "C++", "C#"]]),

    % If the data is a tuple or map we can use pattern matching
    % to access its fields.
    T2 = "Name: ~s~n",
    io:format(T2, ["Jane Doe"]),

    % The same applies to maps
    io:format(T2, [maps:get(name, #{name => "Mickey Mouse"})]),

    % Conditional execution in Erlang is typically done with 
    % pattern matching and multiple function clauses.
    % Here's a simple example:
    print_conditional(""),
    print_conditional("not empty"),

    % To loop through lists in Erlang, we can use list comprehension
    % or recursion. Here's an example using list comprehension:
    Languages = ["Go", "Rust", "C++", "C#"],
    io:format("Range: ~s~n", [string:join(Languages, " ")]).

% Helper function for conditional printing
print_conditional("") ->
    io:format("no~n");
print_conditional(_) ->
    io:format("yes~n").

To run the program, save it as text_templates.erl and use the Erlang shell:

$ erl
1> c(text_templates).
{ok,text_templates}
2> text_templates:main().
Value is "some text"
Value is 5
Value is ["Go","Rust","C++","C#"]
Name: Jane Doe
Name: Mickey Mouse
no
yes
Range: Go Rust C++ C#
ok

In this Erlang version:

  1. We use io:format/2 for string formatting and output, which is similar to the text/template package in the original example.

  2. Erlang doesn’t have a direct equivalent to Go’s struct, so we demonstrate accessing map values instead.

  3. Conditional execution is typically done with pattern matching in Erlang, so we use a separate function print_conditional/1 to demonstrate this.

  4. For looping through lists, we use Erlang’s string:join/2 function along with list comprehension, which is a common idiom in Erlang for working with lists.

This example demonstrates how to work with string templates and basic control structures in Erlang, providing similar functionality to the original Go example.