1 | // |
2 | // Template.h |
3 | // |
4 | // Library: JSON |
5 | // Package: JSON |
6 | // Module: Template |
7 | // |
8 | // Definition of the Template class. |
9 | // |
10 | // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef JSON_JSONTemplate_INCLUDED |
18 | #define JSON_JSONTemplate_INCLUDED |
19 | |
20 | |
21 | #include "Poco/JSON/JSON.h" |
22 | #include "Poco/Dynamic/Var.h" |
23 | #include "Poco/SharedPtr.h" |
24 | #include "Poco/Path.h" |
25 | #include "Poco/Timestamp.h" |
26 | #include <sstream> |
27 | #include <stack> |
28 | |
29 | |
30 | namespace Poco { |
31 | namespace JSON { |
32 | |
33 | |
34 | class MultiPart; |
35 | |
36 | |
37 | POCO_DECLARE_EXCEPTION(JSON_API, JSONTemplateException, Poco::Exception) |
38 | |
39 | |
40 | class JSON_API Template |
41 | /// Template is a template engine which uses JSON as input |
42 | /// for generating output. There are commands for |
43 | /// looping over JSON arrays, include other templates, |
44 | /// conditional output, etc. |
45 | /// |
46 | /// All text is send to the outputstream. A command is placed |
47 | /// between |
48 | /// <? |
49 | /// and |
50 | /// ?> |
51 | /// ---- |
52 | /// |
53 | /// These are the available commands: |
54 | /// |
55 | /// <? echo query ?> |
56 | /// ---- |
57 | /// The result of the query is send to the output stream |
58 | /// This command can also be written as <?= query ?> |
59 | /// |
60 | /// <? if query ?> <? else ?> <? endif ?> |
61 | /// ---- |
62 | /// When the result of query is true, all the text between |
63 | /// if and else (or endif when there is no else) is send to the |
64 | /// output stream. When the result of query is false, all the text |
65 | /// between else and endif is send to the output stream. An empty |
66 | /// object, an empty array or a null value is considered as a false value. |
67 | /// For numbers a zero is false. An empty String is also false. |
68 | /// |
69 | /// <? ifexist query ?> <? else ?> <? endif ?> |
70 | /// ---- |
71 | /// This can be used to check the existence of the value. |
72 | /// Use this for example when a zero value is ok (which returns false for <? if ?>. |
73 | /// |
74 | /// <? for variable query ?> <? endfor ?> |
75 | /// ---- |
76 | /// The result of the query must be an array. For each element |
77 | /// in the array the text between for and endfor is send to the |
78 | /// output stream. The active element is stored in the variable. |
79 | /// |
80 | /// <? include "filename" ?> |
81 | /// ---- |
82 | /// Includes a template. When the filename is relative it will try |
83 | /// to resolve the filename against the active template. When this |
84 | /// file doesn't exist, it can still be found when the JSONTemplateCache |
85 | /// is used. |
86 | /// |
87 | /// A query is passed to Poco::JSON::Query to get the value. |
88 | { |
89 | public: |
90 | typedef SharedPtr<Template> Ptr; |
91 | |
92 | Template(); |
93 | /// Creates a Template. |
94 | |
95 | Template(const Path& templatePath); |
96 | /// Creates a Template from the file with the given templatePath. |
97 | |
98 | virtual ~Template(); |
99 | /// Destroys the Template. |
100 | |
101 | void parse(); |
102 | /// Parse a template from a file. |
103 | |
104 | void parse(const std::string& source); |
105 | /// Parse a template from a string. |
106 | |
107 | void parse(std::istream& in); |
108 | /// Parse a template from an input stream. |
109 | |
110 | Timestamp parseTime() const; |
111 | /// Returns the time when the template was parsed. |
112 | |
113 | void render(const Dynamic::Var& data, std::ostream& out) const; |
114 | /// Renders the template and send the output to the stream. |
115 | |
116 | private: |
117 | std::string readText(std::istream& in); |
118 | std::string readWord(std::istream& in); |
119 | std::string readQuery(std::istream& in); |
120 | std::string readTemplateCommand(std::istream& in); |
121 | std::string readString(std::istream& in); |
122 | void readWhiteSpace(std::istream& in); |
123 | |
124 | MultiPart* _parts; |
125 | std::stack<MultiPart*> _partStack; |
126 | MultiPart* _currentPart; |
127 | Path _templatePath; |
128 | Timestamp _parseTime; |
129 | }; |
130 | |
131 | |
132 | // |
133 | // inlines |
134 | // |
135 | inline void Template::parse(const std::string& source) |
136 | { |
137 | std::istringstream is(source); |
138 | parse(is); |
139 | } |
140 | |
141 | |
142 | inline Timestamp Template::parseTime() const |
143 | { |
144 | return _parseTime; |
145 | } |
146 | |
147 | |
148 | } } // namespace Poco::JSON |
149 | |
150 | |
151 | #endif // JSON_JSONTemplate_INCLUDED |
152 | |