Wiki

Clone wiki

cpptemplate / Home

cpptempl

This is a template engine for C++.

Why would I want to use this?

If you have to generate text from C++ (such as HTML files), doing so in code can be very brittle, and hard to maintain (every tweak to the page layout requires a recompile). This library is inspired by the approach of web frameworks like django and rails, which keep document templates and code (mostly) separate.

Syntax

  • Variables: {$variable_name}
  • Loops: {% for person in people %}Name: {$person.name}{% endfor %}
  • If: {% for person.name == "Bob" %}Full name: Robert{% endif %}

API

  • cpptempl::data_map - The data dictionary you pass to the parser
  • cpptempl::data_list - A list of elements (implemented as vector)
  • cpptempl::make_data() - Create a data element for your data dictionary (data[L"name"] = cpptempl::make_data(L"Homer") ;) You can pass a wstring, data_list, or data_map.
  • cpptempl::parse(wstring, data_map&) - Pass in your template text and data dictioanry to generate the document.

Usage

Simple usage demonstrating the if syntax

	wstring text = L"{% if item %}{$item}{% endif %}\n"
		L"{% if thing %}{$thing}{% endif %}" ;
	cpptempl::data_map data ;
	data[L"item"] = cpptempl::make_data(L"aaa") ;
	data[L"thing"] = cpptempl::make_data(L"bbb") ;

	wstring result = cpptempl::parse(text, data) ;

The output will be:

aaa
bbb

Here's a slightly more involved example

wstring text = L"{% for friend in person.friends %}"
	L"{$loop}. {$friend.name}\n"
	L"{% endfor %}" ;

data_map bob ;
bob[L"name"] = make_data(L"Bob") ;
data_map betty ;
betty[L"name"] = make_data(L"Betty") ;
data_list friends ;
friends.push_back(make_data(bob)) ;
friends.push_back(make_data(betty)) ;
data_map person ;
person[L"friends"] = make_data(friends) ;
data_map data ;
data[L"person"] = make_data(person) ;

wstring result = cpptempl::parse(text, data) ;

The output will be:

1. Bob 
2. Betty

And here's another example, for generating an HTML unordered list.

wstring text = L"<h3>Locations</h3><ul>"
	L"{% for place in places %}"
	L"<li>{$place}</li>"
	L"{% endfor %}"
	L"</ul>" ;

// Create the list of items
cpptempl::data_list places;
places.push_back(cpptempl::make_data(L"Okinawa"));
places.push_back(cpptempl::make_data(L"San Francisco"));
// Now set this in the data map
cpptempl::data_map data ;
data[L"places"] = cpptempl::make_data(places);
// parse the template with the supplied data dictionary
wstring result = cpptempl::parse(text, data) ;

The output will be (newlines added for clarity):

<h3>Locations</h3>
<ul>
<li>Okinawa</li>
<li>San Francisco</li>
</ul>

make_data() is a handy function: Feed it a string, data_map, or data_list to create a data entry. Example:

data_map person ;
person[L"name"] = make_data(L"Bob") ;
person[L"occupation"] = make_data(L"Plumber") ;
data_map data ;
data[L"person"] = make_data(person) ;
wstring result = parse(templ_text, data) ;

Note that this allows arbitrary nesting: you can have data_list's of data_map's, which in turn map to more data_list's or data_map's, and so on. for and if statements can also be nested arbitrarily.

Updated