mirror of
https://git.sakamoto.pl/laudom/http.sh.git
synced 2025-09-20 16:53:45 +02:00
214 lines
4.7 KiB
Markdown
214 lines
4.7 KiB
Markdown
# HTTP.sh: template usage examples
|
|
|
|
## Basic example
|
|
|
|
Create a new .shs file with the following contents:
|
|
|
|
```
|
|
#!/usr/bin/env bash
|
|
declare -A str
|
|
str[title]="Hello, world!"
|
|
str[test]="meow"
|
|
|
|
render str "templates/main.htm"
|
|
```
|
|
|
|
`render` is the core of the templating engine; it takes an assoc array, iterates over it, applies
|
|
additional magic and outputs the response directly to stdout. It is likely the final thing you want
|
|
to run in your script.
|
|
|
|
The script above has referenced an HTML file; For this example, we put it under
|
|
`app/templates/main.htm`, but you're free to use any directory structure for this. An observant
|
|
reader might have noticed the relative path; All paths are treated as relative to the namespace's
|
|
directory. This behavior can be modified by setting `template_relative_paths`, which is described
|
|
in greater detail by the [main template documentation](./template.md).
|
|
|
|
```
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{.title}}</title>
|
|
</head>
|
|
<body>
|
|
{{.test}}
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|

|
|
|
|
## Boolean if statements
|
|
|
|
Following is an example script which simulates a coin toss:
|
|
|
|
```
|
|
#!/usr/bin/env bash
|
|
declare -A str
|
|
str[title]="Coin flip!"
|
|
|
|
if (( RANDOM%2 == 0 )); then
|
|
str[?random]=_
|
|
fi
|
|
|
|
render str "${cfg[namespace]}/templates/main.htm"
|
|
```
|
|
|
|
And the corresponding template:
|
|
|
|
```
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{.title}}</title>
|
|
</head>
|
|
<body>
|
|
{{start ?random}}
|
|
It's heads!
|
|
{{else ?random}}
|
|
It's tails!
|
|
{{end ?random}}
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|

|
|
|
|
50% of the time the variable will be set, 50% it won't. Hence, it will display either heads or tails :)
|
|
|
|
Of note: if you hate repeating yourself, this template can be done inline:
|
|
|
|
```
|
|
It's {{start ?random}}heads{{else ?random}}tails{{end ?random}}!
|
|
```
|
|
|
|
The effect is exactly the same. This is quite useful for adding CSS classes.
|
|
|
|
## Loop example
|
|
|
|
This API is pending a rewrite due to how convoluted it is.
|
|
|
|
```
|
|
#!/usr/bin/env bash
|
|
declare -A str
|
|
str[title]="foreach example"
|
|
|
|
nested_declare list # "array of arrays"
|
|
declare -A elem # temporary element
|
|
for i in {1..32}; do
|
|
elem[item]="$i" # assign $i to the temporary element
|
|
nested_add list elem # add elem to list; this creates a copy you can't modify
|
|
done
|
|
# once we have a full list of elements, assign it to the array passed to render
|
|
str[_list]=list
|
|
|
|
render str "templates/main.htm"
|
|
```
|
|
|
|
And the template...
|
|
|
|
```
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{.title}}</title>
|
|
</head>
|
|
<body>
|
|
{{start _list}}
|
|
{{.item}}<br>
|
|
{{end _list}}
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
The result repeats the whole "subtemplate" between list start and end:
|
|
|
|

|
|
|
|
This is very useful for rendering data in tables:
|
|
|
|
```
|
|
<table>
|
|
<tr>
|
|
<th>number</th>
|
|
</tr>
|
|
{{start _list}}
|
|
<tr>
|
|
<td>{{.item}}</td>
|
|
<td>whatever...</td>
|
|
</tr>
|
|
{{end _list}}
|
|
</table>
|
|
```
|
|
|
|

|
|
|
|
In this specific example the loop index is readily available; However, if your code iterates over
|
|
a list of strings and you'd need to keep track of an additional index variable, the template
|
|
engine can do it for you with `{{-index}}`:
|
|
|
|
```
|
|
<table>
|
|
<tr>
|
|
<th>number</th>
|
|
</tr>
|
|
{{start _list}}
|
|
<tr>
|
|
<td>{{-index}}</td>
|
|
<td>meow</td>
|
|
</tr>
|
|
{{end _list}}
|
|
</table>
|
|
```
|
|
|
|
### integration with notORM
|
|
|
|
notORM's `data_iter` function works great with nested_add; Body of a callback function can be
|
|
treated as equal to a for loop:
|
|
|
|
```
|
|
declare -A elem
|
|
nested_declare list
|
|
x() {
|
|
elem[ns]="${data[2]}"
|
|
elem[domain]="${data[1]}"
|
|
nested_add list elem
|
|
}
|
|
data_iter storage/zones.dat "$username" x
|
|
|
|
str[title]="SERVFAIL :: zone list"
|
|
str[_list]=list
|
|
```
|
|
|
|
## date pretty-printing
|
|
|
|
```
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{.title}}</title>
|
|
</head>
|
|
<body>
|
|
Current time is {{+time}}
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
```
|
|
#!/usr/bin/env bash
|
|
declare -A str
|
|
str[title]="time pretty-print"
|
|
str[+time]="$EPOCHSECONDS"
|
|
|
|
render str "templates/main.htm"
|
|
```
|
|
|
|

|
|
|
|
If you get quirky with the `<meta http-equiv="refresh" content="1">`, you can even make it
|
|
auto update! (don't)
|
|
|
|

|