mirror of
https://git.sakamoto.pl/laudom/http.sh.git
synced 2025-08-19 19:51:04 +02:00
Compare commits
No commits in common. "c6311cf4c11c32b884fae18e66f4fdd3c23d3377" and "93271da824951a6f4969ef2828d83030102ac36d" have entirely different histories.
c6311cf4c1
...
93271da824
5 changed files with 18 additions and 123 deletions
|
@ -10,7 +10,7 @@ declare -A str
|
||||||
str[title]="Hello, world!"
|
str[title]="Hello, world!"
|
||||||
str[test]="meow"
|
str[test]="meow"
|
||||||
|
|
||||||
render str "templates/main.htm"
|
render str "${cfg[namespace]}/templates/main.htm"
|
||||||
```
|
```
|
||||||
|
|
||||||
`render` is the core of the templating engine; it takes an assoc array, iterates over it, applies
|
`render` is the core of the templating engine; it takes an assoc array, iterates over it, applies
|
||||||
|
@ -18,10 +18,7 @@ additional magic and outputs the response directly to stdout. It is likely the f
|
||||||
to run in your script.
|
to run in your script.
|
||||||
|
|
||||||
The script above has referenced an HTML file; For this example, we put it under
|
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
|
`app/templates/main.htm`, but you're free to use any directory structure for this.
|
||||||
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>
|
<!DOCTYPE html>
|
||||||
|
@ -103,7 +100,7 @@ done
|
||||||
# once we have a full list of elements, assign it to the array passed to render
|
# once we have a full list of elements, assign it to the array passed to render
|
||||||
str[_list]=list
|
str[_list]=list
|
||||||
|
|
||||||
render str "templates/main.htm"
|
render str "${cfg[namespace]}/templates/main.htm"
|
||||||
```
|
```
|
||||||
|
|
||||||
And the template...
|
And the template...
|
||||||
|
@ -185,7 +182,7 @@ declare -A str
|
||||||
str[title]="time pretty-print"
|
str[title]="time pretty-print"
|
||||||
str[+time]="$EPOCHSECONDS"
|
str[+time]="$EPOCHSECONDS"
|
||||||
|
|
||||||
render str "templates/main.htm"
|
render str "${cfg[namespace]}/templates/main.htm"
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -23,34 +23,8 @@ For practical examples, see the [template examples](template-examples.md) page.
|
||||||
`render <assoc_array> <file> [recurse]`
|
`render <assoc_array> <file> [recurse]`
|
||||||
|
|
||||||
The first param points to an associative array containing the replacement data. Second one points
|
The first param points to an associative array containing the replacement data. Second one points
|
||||||
to a file containing the template itself (see section below for special usage). Third is optional,
|
to a file containing the template itself. Third is optional, and controls whether `render` will
|
||||||
and controls whether `render` will recurse or not (this is mostly used internally, you likely
|
recurse or not. This is mostly used internally, you likely won't ever need to set it.
|
||||||
won't ever need to set it).
|
|
||||||
|
|
||||||
### File paths
|
|
||||||
|
|
||||||
Starting with HTTP.sh 0.97.1 (2025-05-18), paths in calls to `render` and include tags are
|
|
||||||
relative to the namespace directory (usually `app/`). This behavior can be changed by defining
|
|
||||||
an array called `template_relative_paths`:
|
|
||||||
|
|
||||||
```
|
|
||||||
template_relative_paths=(
|
|
||||||
"${cfg[namespace]}/templates/neue_theme/"
|
|
||||||
"${cfg[namespace]}/templates/default/"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
The templating engine will check all the files in order and pick the first one that exists. This
|
|
||||||
can be used to implement basic inheritance.
|
|
||||||
|
|
||||||
Before 0.97.1, paths were relative to the main HTTP.sh directory. Take care when upgrading, either
|
|
||||||
fix the paths, or set `template_relative_paths="./"` to emulate the previous behavior.
|
|
||||||
|
|
||||||
### Inline templates
|
|
||||||
|
|
||||||
For some purposes, it may be beneficial to store the template within the script file itself.
|
|
||||||
This can be done either through passing `/dev/stdin` as a file name, or through inlining
|
|
||||||
a file substitution, such as `<(echo ...)`.
|
|
||||||
|
|
||||||
## Simple replace
|
## Simple replace
|
||||||
|
|
||||||
|
@ -84,8 +58,9 @@ output (for filling out hidden form values, etc.)
|
||||||
Template includes are special, in that you don't have to define them in the array.
|
Template includes are special, in that you don't have to define them in the array.
|
||||||
They get processed first to "glue together" one singular template.
|
They get processed first to "glue together" one singular template.
|
||||||
|
|
||||||
The path starts at the root of your namespace (usually `app/`). This behavior can be changed,
|
Currently, the path starts at the root of HTTPsh's directory. We don't support expanding variables
|
||||||
see section "File paths" above.
|
inside the include tag, so for now you'll need to hardcode `{{#app/templates/...}}`. This will
|
||||||
|
likely get changed in a future release, starting the path in your namespace.
|
||||||
|
|
||||||
**Warning**: No recursion is supported within included templates; This means that you can't have
|
**Warning**: No recursion is supported within included templates; This means that you can't have
|
||||||
an "include chain". Furthermore, some interactions between included templates and loops/ifs are
|
an "include chain". Furthermore, some interactions between included templates and loops/ifs are
|
||||||
|
|
|
@ -6,18 +6,11 @@
|
||||||
function render() {
|
function render() {
|
||||||
local _tpl_newline=$'\01'
|
local _tpl_newline=$'\01'
|
||||||
local _tpl_ctrl=$'\02'
|
local _tpl_ctrl=$'\02'
|
||||||
local tplfile
|
|
||||||
|
|
||||||
_template_find_absolute_path "$2"
|
|
||||||
|
|
||||||
if [[ ! "$tplfile" ]]; then
|
|
||||||
exit 1 # fail hard
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$3" != true ]]; then
|
if [[ "$3" != true ]]; then
|
||||||
local template="$(tr -d "${_tpl_newline}${_tpl_ctrl}" < "$tplfile" | sed 's/\&/<2F>UwU<77>/g')"
|
local template="$(tr -d "${_tpl_newline}${_tpl_ctrl}" < "$2" | sed 's/\&/<2F>UwU<77>/g')"
|
||||||
else
|
else
|
||||||
local template="$(tr -d "${_tpl_ctrl}" < "$tplfile" | sed -E 's/\\/\\\\/g')"
|
local template="$(tr -d "${_tpl_ctrl}" < "$2" | sed -E 's/\\/\\\\/g')"
|
||||||
fi
|
fi
|
||||||
local buf=
|
local buf=
|
||||||
local garbage="$template"$'\n'
|
local garbage="$template"$'\n'
|
||||||
|
@ -31,19 +24,14 @@ function render() {
|
||||||
# below check prevents the loop loading itself as a template.
|
# below check prevents the loop loading itself as a template.
|
||||||
# this is possibly not enough to prevent all recursions, but
|
# this is possibly not enough to prevent all recursions, but
|
||||||
# i see it as a last-ditch measure. so it'll do here.
|
# i see it as a last-ditch measure. so it'll do here.
|
||||||
if [[ "$file" == "$tplfile" ]]; then
|
if [[ "$file" == "$2" ]]; then
|
||||||
subtemplate+="s${_tpl_ctrl}\{\{\#$key\}\}${_tpl_ctrl}I cowardly refuse to endlessly recurse\!${_tpl_ctrl}g;"
|
subtemplate+="s${_tpl_ctrl}\{\{\#$key\}\}${_tpl_ctrl}I cowardly refuse to endlessly recurse\!${_tpl_ctrl}g;"
|
||||||
# elif [[ -f "$key" ]]; then
|
elif [[ -f "$key" ]]; then
|
||||||
else
|
local input="$(tr -d "${_tpl_ctrl}${_tpl_newline}" < "$key" | sed 's/\&/<2F>UwU<77>/g')"
|
||||||
local i
|
|
||||||
local IFS=''
|
|
||||||
|
|
||||||
_template_find_absolute_path "$key"
|
|
||||||
local input="$(tr -d "${_tpl_ctrl}${_tpl_newline}" < "$tplfile" | sed 's/\&/<2F>UwU<77>/g')"
|
|
||||||
garbage+="$input"$'\n'
|
garbage+="$input"$'\n'
|
||||||
input="$(tr $'\n' "${_tpl_newline}" <<< "$input")" # for another hack
|
input="$(tr $'\n' "${_tpl_newline}" <<< "$input")" # for another hack
|
||||||
subtemplate+="s${_tpl_ctrl}\{\{\#$key\}\}${_tpl_ctrl}${input}${_tpl_ctrl};"
|
subtemplate+="s${_tpl_ctrl}\{\{\#$key\}\}${_tpl_ctrl}${input}${_tpl_ctrl};"
|
||||||
_template_find_special_uri "$(cat "$tplfile")"
|
_template_find_special_uri "$(cat "$key")"
|
||||||
fi
|
fi
|
||||||
done <<< "$(grep -Poh '{{#\K(.*?)(?=}})' <<< "$template")"
|
done <<< "$(grep -Poh '{{#\K(.*?)(?=}})' <<< "$template")"
|
||||||
|
|
||||||
|
@ -130,27 +118,6 @@ function render() {
|
||||||
[[ "$3" != true ]] && _template_uri_list=()
|
[[ "$3" != true ]] && _template_uri_list=()
|
||||||
}
|
}
|
||||||
|
|
||||||
# internal function that looks for the current template. uses path relative to
|
|
||||||
# the namespace, unless overriden with ${template_relative_paths[@]}
|
|
||||||
#
|
|
||||||
# - /dev/stdin is a special value, which gets passed literally.
|
|
||||||
# - /dev/fd/* allows file substitutions `<(echo ...)` to be used.
|
|
||||||
#
|
|
||||||
# _template_find_absolute_path(name) -> $tplfile
|
|
||||||
_template_find_absolute_path() {
|
|
||||||
if [[ ! "${template_relative_paths}" || "$1" == /dev/stdin || "$1" == "/dev/fd/"* ]]; then
|
|
||||||
tplfile="$1"
|
|
||||||
else
|
|
||||||
for (( i=0; i<${#template_relative_paths[@]}; i++ )); do
|
|
||||||
if [[ -f "${template_relative_paths[i]}/$1" ]]; then
|
|
||||||
tplfile="${template_relative_paths[i]}/$1"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_template_uri_list=()
|
_template_uri_list=()
|
||||||
# internal function that finds all occurences of the special `{{-uri-N}}` tag.
|
# internal function that finds all occurences of the special `{{-uri-N}}` tag.
|
||||||
# here to also make it run on subtemplates
|
# here to also make it run on subtemplates
|
||||||
|
@ -201,9 +168,8 @@ function nested_add() {
|
||||||
ref+=("$nested_id")
|
ref+=("$nested_id")
|
||||||
}
|
}
|
||||||
|
|
||||||
# nested_get(ref, i, [res])
|
# nested_get(ref, i)
|
||||||
function nested_get() {
|
function nested_get() {
|
||||||
local -n ref=$1
|
local -n ref=$1
|
||||||
local name=${3:-res}
|
declare -g -n res=_${ref["$2"]}
|
||||||
declare -g -n $name=_${ref["$2"]}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
HTTPSH_VERSION=0.97.1
|
HTTPSH_VERSION=0.97
|
||||||
|
|
|
@ -51,45 +51,6 @@ tpl_date_invalid() {
|
||||||
match="value: 1970-01-01 01:00:00"
|
match="value: 1970-01-01 01:00:00"
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl_path_custom() {
|
|
||||||
prepare() {
|
|
||||||
declare -ga template_relative_paths=("/tmp/")
|
|
||||||
|
|
||||||
tempfile="$(mktemp)" || return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
tst() {
|
|
||||||
declare -A meow
|
|
||||||
render meow "$(basename "$tempfile")"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tpl_path_inheritance() {
|
|
||||||
prepare() {
|
|
||||||
tempdir="$(mktemp -d)" || return 1
|
|
||||||
declare -ga template_relative_paths=(
|
|
||||||
"$tempdir"
|
|
||||||
"/tmp/"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tpl_path_include() {
|
|
||||||
prepare() {
|
|
||||||
another_tempfile="$(mktemp)"
|
|
||||||
echo "meow?" > "$another_tempfile"
|
|
||||||
echo "{{#$(basename "$another_tempfile")}}" > "$tempfile"
|
|
||||||
}
|
|
||||||
|
|
||||||
match="meow?"
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
rm -R "$tempdir"
|
|
||||||
rm "$tempfile" "$another_tempfile"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
subtest_list=(
|
subtest_list=(
|
||||||
tpl_basic
|
tpl_basic
|
||||||
tpl_basic_specialchars
|
tpl_basic_specialchars
|
||||||
|
@ -98,8 +59,4 @@ subtest_list=(
|
||||||
tpl_date
|
tpl_date
|
||||||
tpl_date_empty
|
tpl_date_empty
|
||||||
tpl_date_invalid
|
tpl_date_invalid
|
||||||
|
|
||||||
tpl_path_custom
|
|
||||||
tpl_path_inheritance
|
|
||||||
tpl_path_include
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue