-
-
Notifications
You must be signed in to change notification settings - Fork 27
Writing HTML inside V
The limitation of the V language and the prominence of front-end frameworks on the Web gave rise to the declarative way of creating user interfaces. With the html
submodule, you can build a discrete user interface and generate HTML inside V!
The html.Tag
struct is the important part of the html
submodule. It has the following properties that allows us to define the HTML tag we want to use.
// Simple tag
img_tag := html.Tag{name: 'h1', props: {'src': 'bird.jpg'}}
// Tag with children
p_tag := html.Tag{name: 'p', children: [
html.Tag{name: 'text', text: 'This is a '},
html.Tag{name: 'b', text: 'bold text.'}
]}
It is important to explicitly state the fields when creating a new tag since there are some struct fields such as children
, props
, and text
that are optional to use.
Vex has a dedicated Resp
response function named send_html
which converts the passed array of tags into an HTML representation and sets the content type to text/html
.
content := [html.Tag{name: 'text', text: 'Hello!'}]
res.send_html(layout(content), 200)
// <h1>Hello!</h1>
There are some parts that can be reused for other pages or you want to be able to generate the markup based on the data provided and it is possible by creating a function that returns the html.Tag
. In this example, we created a layout
and h1
components.
fn layout(body []html.Tag) html.Tag {
template := html.Tag{name: 'html', children: [
html.Tag{name: 'head', children: [
html.Tag{name: 'meta', props: { 'http-equiv': 'Content-Type', 'content': 'text/html;charset=UTF-8' }},
html.Tag{name: 'meta', props: { 'name': 'referrer', 'content': 'origin-when-cross-origin'}},
html.Tag{name: 'title', text: 'Vex SQLite Test'}
]},
html.Tag{name: 'body', children: body}
]}
return template
}
fn h1(props map[string]string, children []html.Tag) html.Tag {
return html.Tag{name: 'h1', props: props, children: children}
}
fn main() {
mut s := server.new()
s.get('/test', fn (req ctx.Req, res mut ctx.Resp) {
text := h1({}, [html.Tag{name: 'text', text: 'hello'}])
content := [text]
res.send_html(layout(content), 200)
})
s.serve(8000)
}
Deciding whether to use the text
tag or the text
field can be confusing. Here are some pointers for you to instill to your mind:
- The
text
tag must be used in conjunction with thetext
field. - The
text
field can be used if you don't want to nest thetext
tag which can be a hassle and just directly use a simple text as the children of the tag. - Nesting the
text
tag is recommended if you have incorporated other formatting elements such as theb
(bold) andi
(italic) tags. - The
text
field is recommended forstyle
andscript
tags.