add

Undocumented in source.
alias add = elemi.html.add

Examples

1 // Compile-time empty type detection
2 assert(elem!"input" == "<input/>");
3 assert(elem!"hr" == "<hr/>");
4 assert(elem!"p" == "<p></p>");
5 
6 // Content
7 assert(elem!"p"("Hello, World!") == "<p>Hello, World!</p>");
8 
9 // Compile-time attributes — variant A
10 assert(
11 
12     elem!("a", [ "href": "about:blank", "title": "Destroy this page" ])("Hello, World!")
13 
14     == `<a href="about:blank" title="Destroy this page">Hello, World!</a>`
15 
16 );
17 
18 // Compile-time attributes — variant B
19 assert(
20 
21     elem!("a", q{
22         href="about:blank"
23         title="Destroy this page" })(
24         "Hello, World!"
25     )
26     == `<a href="about:blank" title="Destroy this page">Hello, World!</a>`
27 
28 );
29 
30 // Nesting and input sanitization
31 assert(
32 
33     elem!"div"(
34         elem!"p"("Hello, World!"),
35         "-> Sanitized"
36     )
37 
38     == "<div><p>Hello, World!</p>-&gt; Sanitized</div>"
39 
40 );
41 
42 // Sanitized user input in attributes
43 assert(
44     elem!"input"(
45         attr("type") = "text",
46         attr("value") = `"XSS!"`
47     ) == `<input type="text" value="&quot;XSS!&quot;"/>`
48 );
49 
50 assert(
51 
52     elem!"input"(["type": "text", "value": `"XSS!"`])
53     == `<input type="text" value="&quot;XSS!&quot;"/>`
54 
55 );
56 assert(
57     elem!("input", q{ type="text" })(["value": `"XSS!"`])
58     == `<input type="text" value="&quot;XSS!&quot;"/>`
59 );
60 
61 // Alternative method of nesting
62 assert(
63 
64     elem!("div", q{ style="background:#500" })
65         .add!"p"("Hello, World!")
66         .add("-> Sanitized")
67         .add(
68             " and",
69             " clear"
70         )
71 
72     == `<div style="background:#500"><p>Hello, World!</p>-&gt; Sanitized and clear</div>`
73 
74 );
75 
76 import std.range : repeat;
77 
78 // Adding elements by ranges
79 assert(
80     elem!"ul"(
81         "element".elem!"li".repeat(3)
82     )
83     == "<ul><li>element</li><li>element</li><li>element</li></ul>"
84 
85 );
86 
87 // Significant whitespace
88 assert(elem!"span"(" Foo ") == "<span> Foo </span>");
89 
90 // Also with tilde
91 auto myElem = elem!"div";
92 myElem ~= elem!"span"("Sample");
93 myElem ~= " ";
94 myElem ~= elem!"span"("Text");
95 myElem ~= attr("class") = "test";
96 
97 assert(
98     myElem == `<div class="test"><span>Sample</span> <span>Text</span></div>`
99 );

A general example page

1 import std.stdio : writeln;
2 import std.base64 : Base64;
3 import std.array : split, join;
4 import std.algorithm : map, filter;
5 
6 enum page = Element.HTMLDoctype ~ elem!"html"(
7 
8     elem!"head"(
9 
10         elem!("title")("An example document"),
11 
12         // Metadata
13         Element.MobileViewport,
14         Element.EncodingUTF8,
15 
16         elem!("style")(`
17 
18             html, body {
19                 height: 100%;
20                font-family: sans-serif;
21                 padding: 0;
22                 margin: 0;
23             }
24             .header {
25                 background: #f7a;
26                 font-size: 1.5em;
27                 margin: 0;
28                 padding: 5px;
29             }
30             .article {
31                 padding-left: 2em;
32             }
33 
34         `.split("\n").map!"a.strip".filter!"a.length".join),
35 
36     ),
37 
38     elem!"body"(
39 
40         elem!("header", q{ class="header" })(
41             elem!"h1"("Example website")
42         ),
43 
44         elem!"h1"("Welcome to my website!"),
45         elem!"p"("Hello there,", elem!"br", "may you want to read some of my articles?"),
46 
47         elem!("div", q{ class="article" })(
48             elem!"h2"("Stuff"),
49             elem!"p"("Description")
50         )
51 
52     )
53 
54 );
55 
56 enum target = cast(string) Base64.decode([
57     `PCFET0NUWVBFIGh0bWw+PGh0bWw+PGhlYWQ+PHRpdGxlPkFuIGV4YW1wbGUgZG9jdW1lbnQ8L3Rp`,
58     `dGxlPjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGlu`,
59     `aXRpYWwtc2NhbGU9MSIvPjxtZXRhIGNoYXJzZXQ9InV0Zi04Ii8+PHN0eWxlPmh0bWwsIGJvZHkg`,
60     `e2hlaWdodDogMTAwJTtmb250LWZhbWlseTogc2Fucy1zZXJpZjtwYWRkaW5nOiAwO21hcmdpbjog`,
61     `MDt9LmhlYWRlciB7YmFja2dyb3VuZDogI2Y3YTtmb250LXNpemU6IDEuNWVtO21hcmdpbjogMDtw`,
62     `YWRkaW5nOiA1cHg7fS5hcnRpY2xlIHtwYWRkaW5nLWxlZnQ6IDJlbTt9PC9zdHlsZT48L2hlYWQ+`,
63     `PGJvZHk+PGhlYWRlciBjbGFzcz0iaGVhZGVyIj48aDE+RXhhbXBsZSB3ZWJzaXRlPC9oMT48L2hl`,
64     `YWRlcj48aDE+V2VsY29tZSB0byBteSB3ZWJzaXRlITwvaDE+PHA+SGVsbG8gdGhlcmUsPGJyLz5t`,
65     `YXkgeW91IHdhbnQgdG8gcmVhZCBzb21lIG9mIG15IGFydGljbGVzPzwvcD48ZGl2IGNsYXNzPSJh`,
66     `cnRpY2xlIj48aDI+U3R1ZmY8L2gyPjxwPkRlc2NyaXB0aW9uPC9wPjwvZGl2PjwvYm9keT48L2h0`,
67     `bWw+`,
68 ].join);
69 
70 assert(page == target);

Meta