]> git.llucax.com Git - software/bife/fast.git/blob - include/fast/basic_template.h
Se version inicial del nona (solo tiene fast, sistema de templates implementado con...
[software/bife/fast.git] / include / fast / basic_template.h
1 // vim: set expandtab tabstop=4 shiftwidth=4:
2 //----------------------------------------------------------------------------
3 //                                    fast
4 //----------------------------------------------------------------------------
5 // This file is part of fast.
6 //
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
10 // version.
11 //
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
15 // details.
16 //
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 //----------------------------------------------------------------------------
24 //
25 // $Id$
26 //
27
28 #ifndef FAST_BASIC_TEMPLATE_H
29 #define FAST_BASIC_TEMPLATE_H
30
31 //#include "fast/string.h"
32 //#include "fast/string_map.h"
33 //#include <map>
34 #include <stack>
35
36 namespace fast {
37
38 /**
39  * bate - BAse Template Engine.
40  *
41  * bate is the base template engine implemented in faste.
42  */
43 template < class F, class S, class M >
44 class basic_template {
45
46     // Types.
47     public:
48         /// Cache traits type.
49         typedef F file_content_type;
50         /// String type.
51         typedef S string_type;
52         /// Map type.
53         typedef M< string_type, string_type > map_type;
54
55     // Attributes.
56     private:
57         /// Root directory where to search for templates.
58         string_type _root;
59         /// Postfix added to the blockname to convert it to a filename.
60         string_type _postfix;
61         /// Function object to get the contents of a "file".
62         file_content_type _file_content;
63         /// Group stack.
64         std::stack< string_type > _group;
65
66     // Methods.
67     protected:
68         /**
69          * Gets a filename based on the block.
70          *
71          * @param  block Name of the block to get the filename.
72          *
73          * @return Block's filename.
74          */
75         string_type build_filename(const string_type& block) const
76         {
77             string_type group = _group.top();
78             if (group.length()) group += '/';
79             return _root + '/' + group + block + _postfix;
80         }
81
82     public:
83         /**
84          * Constructor.
85          *
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".
90          */
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); }
96
97         /// Gets templates root directory.
98         string_type root(void) const
99         { return _root; }
100
101         /// Sets templates root directory.
102         void root(const string_type& root)
103         { _root = root; }
104
105         /// Gets templates postfix.
106         string_type postfix(void) const
107         { return _postfix; }
108
109         /// Sets templates postfix.
110         void postfix(const string_type& postfix)
111         { _postfix = postfix; }
112
113         /**
114          * Gets the current working group.
115          *
116          * @return Current template's group.
117          */
118         string_type group(void) const
119         { return _group.top(); }
120
121         /**
122          * Starts working with a new group of templates.
123          *
124          * @param group Group of templates to work with.
125          */
126         void push_group(const string_type& group)
127         { _group.push(group); }
128
129         /**
130          * Stops working with a group of templates.
131          *
132          * @return Last template's group used.
133          */
134         string_type pop_group(void)
135         {
136             string_type group = _group.top();
137             _group.pop();
138             return group;
139         }
140
141         /**
142          * Parses a block replacing keys with values in the hash.
143          *
144          * @param  block Name of the block to parse.
145          * @param  vars  Hash containing the variable names and their values.
146          *
147          * @return Parsed block with variables replaced.
148          */
149         string_type parse(const string_type& block, const map_type& vars) const
150         {
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);
165                 }
166             }
167             return content;
168         }
169
170 }; // class basic_template
171
172 } // namespace fast
173
174 #endif // FAST_BASIC_TEMPLATE_H