diff --git a/src/elements.gleam b/src/elements.gleam index d03b6f7..1b7f064 100644 --- a/src/elements.gleam +++ b/src/elements.gleam @@ -4,6 +4,7 @@ pub type Attribute { pub type Element { Element(tag: String, attrs: List(Attribute), children: List(Element)) + EscapeText(String) Text(String) CData(String) } @@ -28,6 +29,10 @@ pub fn text(value: String) -> Element { Text(value) } +pub fn escape_text(value: String) -> Element { + EscapeText(value) +} + pub fn cdata(value: String) -> Element { CData(value) } diff --git a/src/html.gleam b/src/html.gleam index 5441ef6..aba0d18 100644 --- a/src/html.gleam +++ b/src/html.gleam @@ -17,7 +17,7 @@ pub fn document( } pub fn title(title: String) -> Element { - elements.element("title", [], [elements.text(title)]) + elements.element("title", [], [elements.escape_text(title)]) } pub fn meta(attrs: List(Attribute)) -> Element { diff --git a/src/render.gleam b/src/render.gleam index d66db9f..8083538 100644 --- a/src/render.gleam +++ b/src/render.gleam @@ -55,9 +55,12 @@ pub fn element(el: elements.Element) -> String { } } } - elements.Text(value) -> { + elements.EscapeText(value) -> { escape(value) } + elements.Text(value) -> { + value + } elements.CData(value) -> { " string.append(value) diff --git a/src/xml.gleam b/src/xml.gleam new file mode 100644 index 0000000..6d96119 --- /dev/null +++ b/src/xml.gleam @@ -0,0 +1,19 @@ +import elements +import gleam/list + +pub type Sitemap { + SitemapUrl(loc: String, lastmod: String) +} + +pub fn sitemap(items: List(Sitemap)) -> elements.Element { + elements.element( + "urlset", + [elements.attr("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9")], + list.map(items, fn(item) { + elements.element("url", [], [ + elements.element("loc", [], [elements.text(item.loc)]), + elements.element("lastmod", [], [elements.text(item.lastmod)]), + ]) + }), + ) +} diff --git a/test/render_test.gleam b/test/render_test.gleam index d22cf04..355cf20 100644 --- a/test/render_test.gleam +++ b/test/render_test.gleam @@ -3,9 +3,10 @@ import gleam/list import gleeunit/should import html import render +import xml fn paragraph(text: String) { - html.p([], [elements.text(text)]) + html.p([], [elements.escape_text(text)]) } fn meta() { @@ -68,9 +69,9 @@ pub fn render_nested_html_test() { html.html([elements.attr("lang", "en")], [ html.head([], [html.title("Nested")]), html.body([], [ - html.h1([], [elements.text("Hello")]), + html.h1([], [elements.escape_text("Hello")]), html.div([elements.attr("class", "text-2xl")], [ - html.p([], [elements.text("What a nice library")]), + html.p([], [elements.escape_text("What a nice library")]), ]), ]), ]) @@ -85,8 +86,8 @@ pub fn render_nested_html_test() { pub fn render_simple_xml_test() { let book_element = fn(id: String, author: String, title: String) { elements.element("book", [elements.attr("id", id)], [ - elements.element("author", [], [elements.text(author)]), - elements.element("title", [], [elements.text(title)]), + elements.element("author", [], [elements.escape_text(author)]), + elements.element("title", [], [elements.escape_text(title)]), ]) } @@ -121,3 +122,18 @@ pub fn render_xml_cdata_test() { render.xml(input) |> should.equal(expected) } + +pub fn render_sitemap_test() { + let input = [ + xml.SitemapUrl(loc: "https://www.example.com/foo", lastmod: "2022-06-04"), + xml.SitemapUrl(loc: "https://www.example.com/bar", lastmod: "2022-06-05"), + xml.SitemapUrl(loc: "https://www.example.com/hello", lastmod: "2022-06-10"), + ] + let sitemap = xml.sitemap(input) + + let expected = + "https://www.example.com/foo2022-06-04https://www.example.com/bar2022-06-05https://www.example.com/hello2022-06-10" + + render.xml(sitemap) + |> should.equal(expected) +}