hemplateSimple 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
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"
);
}