@@ -52,6 +52,50 @@ namespace vix::template_
5252 */
5353 using NodeList = std::vector<NodePtr>;
5454
55+ /* *
56+ * @brief Filter node attached to a variable interpolation.
57+ *
58+ * Example:
59+ * {{ name | upper | length }}
60+ *
61+ * In this example:
62+ * - upper is one FilterNode
63+ * - length is another FilterNode
64+ *
65+ * V2 keeps filters simple:
66+ * - filter name only
67+ * - no arguments yet
68+ */
69+ class FilterNode
70+ {
71+ public:
72+ /* *
73+ * @brief Construct a filter node.
74+ *
75+ * @param name Filter name.
76+ */
77+ explicit FilterNode (std::string name)
78+ : name_(std::move(name))
79+ {
80+ }
81+
82+ /* *
83+ * @brief Get the filter name.
84+ *
85+ * @return Filter name.
86+ */
87+ [[nodiscard]] const std::string &name () const noexcept
88+ {
89+ return name_;
90+ }
91+
92+ private:
93+ /* *
94+ * @brief Filter name.
95+ */
96+ std::string name_;
97+ };
98+
5599 /* *
56100 * @brief Base class for all AST nodes.
57101 */
@@ -190,14 +234,16 @@ namespace vix::template_
190234 /* *
191235 * @brief Variable interpolation node.
192236 *
193- * Example :
237+ * Examples :
194238 * {{ user }}
239+ * {{ user | upper }}
240+ * {{ items | length }}
195241 */
196242 class VariableNode final : public Node
197243 {
198244 public:
199245 /* *
200- * @brief Construct a variable node.
246+ * @brief Construct a variable node without filters .
201247 *
202248 * @param name Variable name.
203249 */
@@ -206,6 +252,18 @@ namespace vix::template_
206252 {
207253 }
208254
255+ /* *
256+ * @brief Construct a variable node with filters.
257+ *
258+ * @param name Variable name.
259+ * @param filters Filter pipeline.
260+ */
261+ VariableNode (std::string name, std::vector<FilterNode> filters)
262+ : name_(std::move(name)),
263+ filters_ (std::move(filters))
264+ {
265+ }
266+
209267 /* *
210268 * @brief Get the node type.
211269 *
@@ -226,11 +284,36 @@ namespace vix::template_
226284 return name_;
227285 }
228286
287+ /* *
288+ * @brief Get the filter pipeline.
289+ *
290+ * @return Ordered list of filters to apply.
291+ */
292+ [[nodiscard]] const std::vector<FilterNode> &filters () const noexcept
293+ {
294+ return filters_;
295+ }
296+
297+ /* *
298+ * @brief Check whether the variable has filters.
299+ *
300+ * @return True if one or more filters are attached.
301+ */
302+ [[nodiscard]] bool has_filters () const noexcept
303+ {
304+ return !filters_.empty ();
305+ }
306+
229307 private:
230308 /* *
231309 * @brief Variable name to resolve from the rendering context.
232310 */
233311 std::string name_;
312+
313+ /* *
314+ * @brief Ordered filter pipeline.
315+ */
316+ std::vector<FilterNode> filters_;
234317 };
235318
236319 /* *
0 commit comments