1 // vim: set expandtab tabstop=4 shiftwidth=4:
2 //----------------------------------------------------------------------------
4 //----------------------------------------------------------------------------
5 // This file is part of fast.
7 // fast is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the Free Software
9 // Foundation; either version 2 of the License, or (at your option) any later
12 // fast is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 // You should have received a copy of the GNU General Public License along
18 // with fast; if not, write to the Free Software Foundation, Inc., 59 Temple
19 // Place, Suite 330, Boston, MA 02111-1307 USA
20 //----------------------------------------------------------------------------
21 // Creado: sáb feb 7 20:04:43 ART 2004
22 // Autores: Leandro Lucarella <luca@lugmen.org.ar>
23 //----------------------------------------------------------------------------
28 #ifndef FAST_BASIC_TEMPLATE_H
29 #define FAST_BASIC_TEMPLATE_H
31 //#include "fast/string.h"
32 //#include "fast/string_map.h"
39 * bate - BAse Template Engine.
41 * bate is the base template engine implemented in faste.
43 template < class F, class S, class M >
44 class basic_template {
48 /// Cache traits type.
49 typedef F file_content_type;
51 typedef S string_type;
53 typedef M< string_type, string_type > map_type;
57 /// Root directory where to search for templates.
59 /// Postfix added to the blockname to convert it to a filename.
61 /// Function object to get the contents of a "file".
62 file_content_type _file_content;
64 std::stack< string_type > _group;
69 * Gets a filename based on the block.
71 * @param block Name of the block to get the filename.
73 * @return Block's filename.
75 string_type build_filename(const string_type& block) const
77 string_type group = _group.top();
78 if (group.length()) group += '/';
79 return _root + '/' + group + block + _postfix;
86 * @param root Root directory from where to get the templates.
87 * @param postfix Postfix of the template files.
88 * @param group Starting group.
89 * @param file_content Function object to get the contents of a "file".
91 basic_template(const string_type& root = ".",
92 const string_type& postfix = ".tpl", const string_type& group = "",
93 const file_content_type& file_content = file_content_type())
94 : _root(root), _postfix(postfix), _file_content(file_content)
95 { _group.push(group); }
97 /// Gets templates root directory.
98 string_type root(void) const
101 /// Sets templates root directory.
102 void root(const string_type& root)
105 /// Gets templates postfix.
106 string_type postfix(void) const
109 /// Sets templates postfix.
110 void postfix(const string_type& postfix)
111 { _postfix = postfix; }
114 * Gets the current working group.
116 * @return Current template's group.
118 string_type group(void) const
119 { return _group.top(); }
122 * Starts working with a new group of templates.
124 * @param group Group of templates to work with.
126 void push_group(const string_type& group)
127 { _group.push(group); }
130 * Stops working with a group of templates.
132 * @return Last template's group used.
134 string_type pop_group(void)
136 string_type group = _group.top();
142 * Parses a block replacing keys with values in the hash.
144 * @param block Name of the block to parse.
145 * @param vars Hash containing the variable names and their values.
147 * @return Parsed block with variables replaced.
149 string_type parse(const string_type& block, const map_type& vars) const
151 // TODO - el build_filename() debería ser parte de la política
152 // de reemplazo? o del file_contents?
153 // TODO: capturar excepción (pensar política para reportar errores)
154 string_type content = _file_content(build_filename(block));
155 for (map_type::const_iterator i = vars.begin();
156 i != vars.end(); ++i) {
157 // TODO - Parametrizar los 'separadores' y toda la política
158 // de search & replace en un template para hacerlo más
159 // flexible e implementar cosas como funciones de
160 // transformación, por ej. {upper(KEYWORD)}
161 string_type key = string("{") + i->first + "}";
162 string_type::size_type pos;
163 while ((pos = content.find(key)) != string_type::npos) {
164 content.replace(pos, key.length(), i->second);
170 }; // class basic_template
174 #endif // FAST_BASIC_TEMPLATE_H