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
30namespace Poco {
31namespace JSON {
32
33
34class MultiPart;
35
36
37POCO_DECLARE_EXCEPTION(JSON_API, JSONTemplateException, Poco::Exception)
38
39
40class 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{
89public:
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
116private:
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//
135inline void Template::parse(const std::string& source)
136{
137 std::istringstream is(source);
138 parse(is);
139}
140
141
142inline Timestamp Template::parseTime() const
143{
144 return _parseTime;
145}
146
147
148} } // namespace Poco::JSON
149
150
151#endif // JSON_JSONTemplate_INCLUDED
152