File: tag-processor.hpp

package info (click to toggle)
libzeep 7.3.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,372 kB
  • sloc: cpp: 17,430; javascript: 180; makefile: 12; sh: 11
file content (143 lines) | stat: -rw-r--r-- 7,175 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//       Copyright Maarten L. Hekkelman, 2019-2026
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#pragma once

/// \file
/// definition of the zeep::http::tag_processor classes. These classes take care of processing HTML templates

#include "zeep/el/processing.hpp"
#include "zeep/http/scope.hpp"

#include <zeem.hpp>

#include <filesystem>
#include <functional>
#include <map>
#include <string>
#include <string_view>
#include <utility>

namespace zeep::http
{

class basic_template_processor;

// --------------------------------------------------------------------
//

/// \brief Abstract base class for tag_processor.
///
/// Note that this class should be light in construction, we create it every time a page is rendered.

class tag_processor_base
{
  public:
	tag_processor_base(const tag_processor_base &) = delete;
	tag_processor_base &operator=(const tag_processor_base &) = delete;

	virtual ~tag_processor_base() = default;

	/// \brief process xml parses the XHTML and fills in the special tags and evaluates the el constructs
	///
	/// This function is called to modify the xml tree in \a node
	///
	/// \param node		The XML zeem::node (element) to manipulate
	/// \param scope	The zeep::http::scope containing the variables and request
	/// \param dir		The path to the docroot, the directory containing the XHTML templates
	/// \param loader	The template processor to use to load resources
	virtual void process_xml(zeem::node *node, const scope &scope, const std::filesystem::path &dir, basic_template_processor &loader) = 0;

  protected:
	/// \brief constructor
	///
	/// \param ns	Then XML namespace for the tags and attributes that are processed by this tag_processor
	tag_processor_base(std::string ns)
		: m_ns(std::move(ns))
	{
	}

	std::string m_ns;
};

// --------------------------------------------------------------------

/// \brief version two of the tag_processor in libzeep
///
/// This is the new tag_processor. It is designed to look a bit like
/// Thymeleaf (https://www.thymeleaf.org/)
/// This processor works on attributes mostly, but can process inline
/// el constructs as well.
///
/// The documentention contains a section describing all the
/// xml tags and attributes this processor handles.

class tag_processor : public tag_processor_base
{
  public:
	/// \brief default namespace for this processor
	static constexpr const char *ns() { return "http://www.hekkelman.com/libzeep/m2"; }

	/// \brief each handler returns a code telling the processor what to do with the node
	enum class AttributeAction
	{
		none,
		remove,
		replace
	};

	using attr_handler = std::function<AttributeAction(zeem::element *, zeem::attribute &, scope &, const std::filesystem::path &, basic_template_processor &loader)>;

	/// \brief constructor with default namespace
	tag_processor(const char *ns = tag_processor::ns());

	/// \brief process xml parses the XHTML and fills in the special tags and evaluates the el constructs
	void process_xml(zeem::node *node, const scope &scope, const std::filesystem::path &dir, basic_template_processor &loader) override;

	/// \brief It is possible to extend this processor with custom handlers
	void register_attr_handler(std::string attr, attr_handler &&handler)
	{
		m_attr_handlers.emplace(std::move(attr), std::move(handler));
	}

  protected:
	void process_node(zeem::node *node, const scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	void process_text(zeem::node_with_text &t, const scope &scope);
	void post_process(zeem::element *e, const scope &parentScope, const std::filesystem::path &dir, basic_template_processor &loader);

	// zeem::element resolve_fragment_spec(zeem::element* node, const std::filesystem::path &dir, basic_html_controller& controller, const std::string& spec, const scope& scope);
	zeem::element resolve_fragment_spec(zeem::element *node, const std::filesystem::path &dir, basic_template_processor &loader, const el::object &spec, const scope &scope);
	zeem::element resolve_fragment_spec(zeem::element *node, const std::filesystem::path &dir, basic_template_processor &loader, const std::string &file, std::string_view selector, bool byID);

	// virtual void process_node_attr(zeem::node* node, const scope& scope, std::filesystem::path dir);
	AttributeAction process_attr_if(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader, bool unless);
	AttributeAction process_attr_assert(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_text(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader, bool escaped);
	AttributeAction process_attr_switch(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_each(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_attr(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_with(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_generic(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_boolean_value(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_inline(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_append(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader, std::string dest, bool prepend);
	AttributeAction process_attr_classappend(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_styleappend(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);
	AttributeAction process_attr_remove(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader);

	enum class TemplateIncludeAction
	{
		include,
		insert,
		replace
	};

	AttributeAction process_attr_include(zeem::element *node, zeem::attribute &attr, scope &scope, const std::filesystem::path &dir, basic_template_processor &loader, TemplateIncludeAction tia);

	std::map<std::string, attr_handler> m_attr_handlers;
	zeem::document m_template; // copy of the entire document...
};

} // namespace zeep::http