├── .gitignore
├── LICENSE
├── README.md
├── attributes
└── attributes.go
├── elements.go
├── examples
└── server
│ └── main.go
└── htmlgogen
├── attr.go
├── main.go
├── tags.go
└── templates
├── attributes
└── attributes.go
└── elements.go
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Julian Vossen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # htmlgo
2 | A library for writing type-safe HTML in Go
3 |
4 | [This blog post](https://julianvossen.de/posts/2019-03-17-htmlgo) provides a short introduction.
5 |
6 | ## Why?
7 | As much as I like the simplicity and the contextual escaping of `html/template`, it doesn't provide much type safety.
8 | Pipelines (e.g. `{{.DoesNotExist.Value}}`) can produce errors at runtime, which should be caught during compilation.
9 | Using nested templates with `html/template` can become hard to maintain, as a template user has to inspect the pipelines within a templates to infer the data format to be passed into the template.
10 | As a bonus, using Go functions to produce HTML elements prevents malformed HTML.
11 |
12 | This library is inspired by [Haskell's blaze-html](http://hackage.haskell.org/package/blaze-html).
13 |
14 | ## Status
15 | * Support for all HTML5 tags and attributes
16 | * Secure, contextual escaping (based on `html/template`)
17 | * Not optimised for performance, expect it to be significantly slower than `html/template`
18 |
19 | ## API
20 | ### Tags
21 | Functions for all HTML tags are part of the top-level package `htmlgo`. The
22 | function signatures are `Tagname(attrs []attributes.Attribute, children ...HTML) HTML`
23 | To omit the first argument, i.e. to create an element without attributes, there
24 | are functions with an underscore suffix `Tagname_(children ...HTML) HTML` to
25 | reduce verbosity.
26 |
27 | ### Attributes
28 | Functions to create attributes are located in the package `htmlgo/attributes`.
29 | Use `Attr(attrs ...attributes.Attribute)` from `htmlgo` as a less verbose way to
30 | create a slice of attributes. The function signatures are `Attributename(data
31 | interface{}, templates ...string) Attribute`. The `data` will be placed into the
32 | given `templates` using `html/template` and, therefore, follows the same syntax.
33 | Note, as `templates` is a variadic argument, it can be omitted entirely, in
34 | which case a `{{.}}` template is used. Data provided as `data` will be escaped,
35 | whereas the `templates` itself can be used to provide values which shall not be
36 | escaped. Again, there are convenience functions with an underscore suffix to omit the first argument,
37 | which is `data` in this case `Attributename_(templates ...string) Attribute`.
38 | Use the underscore-suffixed attribute functions wisely, as they will not escape
39 | their arguments. A good rule of thumb is that you should never pass a variable
40 | into the suffixed functions, only string literals.
41 |
42 | The dataset attributes `data-*` can be added using `Dataset(key, value string)`.
43 |
44 | ## Example
45 |
46 | ```golang
47 | package main
48 |
49 | import (
50 | "fmt"
51 |
52 | . "github.com/julvo/htmlgo"
53 | a "github.com/julvo/htmlgo/attributes"
54 | )
55 |
56 | func main() {
57 | var numberDivs HTML
58 | for i := 0; i < 3; i++ {
59 | numberDivs += Div(Attr(a.Style_("font-family:monospace;")),
60 | Text(i))
61 | }
62 |
63 | page :=
64 | Html5_(
65 | Head_(),
66 | Body_(
67 | H1_(Text("Welcome
102 |
105 |