hemplate

Simple XML template engine
git clone git://git.dimitrijedobrota.com/hemplate.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 7b79f6bda1d93c11b4e581d375b585cb9bbe9c63
parent cb6446371e20af7b6f6b6637da005fa73ebbe589
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Sat, 3 May 2025 09:41:56 +0200

Add shorthands for commonly used tags, with tests

Diffstat:
M include/hemplate/atom.hpp | ++++++++++++++++++++++++++++++++++++++++ --
M include/hemplate/html.hpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ---
M test/source/atom_test.cpp | ++++++++++++++++++++++++
M test/source/html_test.cpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

4 files changed, 227 insertions(+), 4 deletions(-)


diff --git a/ include/hemplate/atom.hpp b/ include/hemplate/atom.hpp

@@ -51,7 +51,6 @@ using generator = element_boolean<"generator">; using icon = element_boolean<"icon">; using id = element_boolean<"id">; using intervalBlock = element_boolean<"intervalBlock">;
using link = element_boolean<"link">;
using logo = element_boolean<"logo">; using meterReading = element_boolean<"meterReading">; using name = element_boolean<"name">;

@@ -65,7 +64,46 @@ using title = element_boolean<"title">; using updated = element_boolean<"updated">; using uri = element_boolean<"uri">; using usagePoint = element_boolean<"usagePoint">;
// NOLINTEND(*naming*)
using link = element_atomic<"link">;
// clang-format on
class HEMPLATE_EXPORT linkHref : public link
{
public:
explicit linkHref(std::string_view href)
: link(attribute_list {
{"href", href},
})
{
}
};
class HEMPLATE_EXPORT linkSelf : public link
{
public:
explicit linkSelf(std::string_view href)
: link(attribute_list {
{"rel", "self"},
{"href", href},
})
{
}
};
class HEMPLATE_EXPORT linkAlternate : public link
{
public:
explicit linkAlternate(std::string_view href)
: link(attribute_list {
{"rel", "alternate"},
{"type", "text/html"},
{"href", href},
})
{
}
};
// NOLINTEND(*naming*)
} // namespace hemplate::atom

diff --git a/ include/hemplate/html.hpp b/ include/hemplate/html.hpp

@@ -10,7 +10,7 @@ using hemplate::element; using hemplate::transform; using hemplate::xml;
class doctype : public element
class HEMPLATE_EXPORT doctype : public element
{ public: explicit doctype()

@@ -134,7 +134,97 @@ using param = element_atomic<"param">; using source = element_atomic<"source">; using track = element_atomic<"track">; using wbr = element_atomic<"wbr">;
// NOLINTEND(*naming*)
// clang-format on
class HEMPLATE_EXPORT aHref : public a
{
public:
template<typename... Args>
requires(!std::same_as<attribute_list, std::remove_cvref_t<Args>> && ...)
explicit aHref(std::string_view href, Args&&... args)
: a(attribute_list {{"href", href}}, std::forward<Args>(args)...)
{
}
};
class HEMPLATE_EXPORT metaUTF8 : public meta
{
public:
metaUTF8()
: meta(attribute_list {
{"charset", "UTF8"},
})
{
}
};
class HEMPLATE_EXPORT metaName : public meta
{
public:
metaName(std::string_view name, std::string_view content)
: meta(attribute_list {
{"name", name},
{"content", content},
})
{
}
};
class HEMPLATE_EXPORT linkStylesheet : public link
{
public:
explicit linkStylesheet(std::string_view href)
: link(attribute_list {
{"rel", "stylesheet"},
{"type", "text/css"},
{"href", href},
})
{
}
};
class HEMPLATE_EXPORT linkRss : public link
{
public:
linkRss(std::string_view ttl, std::string_view href)
: link(attribute_list {
{"rel", "alternate"},
{"type", "application/atom+xml"},
{"title", ttl},
{"href", href},
})
{
}
};
class HEMPLATE_EXPORT linkAtom : public link
{
public:
linkAtom(std::string_view ttl, std::string_view href)
: link(attribute_list {
{"rel", "alternate"},
{"type", "application/atom+xml"},
{"title", ttl},
{"href", href},
})
{
}
};
class HEMPLATE_EXPORT linkIcon : public link
{
public:
linkIcon(std::string_view sizes, std::string_view href)
: link(attribute_list {
{"rel", "icon"},
{"type", "image/png"},
{"sizes", sizes},
{"href", href},
})
{
}
};
// NOLINTEND(*naming*)
} // namespace hemplate::html

diff --git a/ test/source/atom_test.cpp b/ test/source/atom_test.cpp

@@ -23,3 +23,27 @@ TEST_CASE("feed", "[atom/feed]") REQUIRE(std::string(feed) == "<feed hello=\"world\">\n</feed>\n"); } }
TEST_CASE("linkHref", "[atom/linkHref]")
{
const atom::linkHref link {"url"};
REQUIRE(std::string(link) == "<link href=\"url\" />\n");
}
TEST_CASE("linkSelf", "[atom/linkSelf]")
{
const atom::linkSelf link {"url"};
REQUIRE(std::string(link) == "<link rel=\"self\" href=\"url\" />\n");
}
TEST_CASE("linkAlternate", "[atom/linkAlternate]")
{
const atom::linkAlternate link {"url"};
REQUIRE(
std::string(link)
== "<link rel=\"alternate\" type=\"text/html\" href=\"url\" />\n"
);
}

diff --git a/ test/source/html_test.cpp b/ test/source/html_test.cpp

@@ -10,3 +10,74 @@ TEST_CASE("doctype", "[html/doctype]") REQUIRE(std::string(doctype) == "<!DOCTYPE html>\n"); }
TEST_CASE("aHref", "[html/aHref]")
{
SECTION("empty")
{
const html::aHref a {"url"};
REQUIRE(std::string(a) == "<a href=\"url\">\n</a>\n");
}
SECTION("child")
{
const html::aHref a {"url", html::br{}};
REQUIRE(std::string(a) == "<a href=\"url\"><br /></a>\n");
}
}
TEST_CASE("metaUTF8", "[html/metaUTF8]")
{
const html::metaUTF8 meta;
REQUIRE(std::string(meta) == "<meta charset=\"UTF8\" />\n");
}
TEST_CASE("metaName", "[html/metaName]")
{
const html::metaName meta {"author", "Kenobi"};
REQUIRE(std::string(meta) == "<meta name=\"author\" content=\"Kenobi\" />\n");
}
TEST_CASE("linkStylesheet", "[html/linkStylesheet]")
{
const html::linkStylesheet link {"url"};
REQUIRE(
std::string(link)
== "<link rel=\"stylesheet\" type=\"text/css\" href=\"url\" />\n"
);
}
TEST_CASE("linkRss", "[html/linkRss]")
{
const html::linkRss link {"hi", "url"};
REQUIRE(
std::string(link)
== "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"hi\" href=\"url\" />\n"
);
}
TEST_CASE("linkAtom", "[html/linkAtom]")
{
const html::linkAtom link {"hi", "url"};
REQUIRE(
std::string(link)
== "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"hi\" href=\"url\" />\n"
);
}
TEST_CASE("linkIcon", "[html/linkIcon]")
{
const html::linkIcon link {"16x16", "url"};
REQUIRE(
std::string(link)
== "<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"url\" />\n"
);
}