init
This commit is contained in:
commit
5db9429bd8
22 changed files with 657 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/tpp
|
||||||
|
/exe
|
||||||
|
Session.vim
|
4
build.sh
Executable file
4
build.sh
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
go build -o ./exe/ ./cmd/tht
|
||||||
|
|
10
cmd/tht/main.go
Normal file
10
cmd/tht/main.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"surdeus.su/util/tht/server"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
server.Tool.Run(os.Args[1:])
|
||||||
|
}
|
11
go.mod
Normal file
11
go.mod
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module surdeus.su/util/tht
|
||||||
|
|
||||||
|
go 1.22.3
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/d5/tengo/v2 v2.17.0
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2
|
||||||
|
surdeus.su/core/cli v0.1.2
|
||||||
|
surdeus.su/core/xgo v0.5.0
|
||||||
|
surdeus.su/util/tpp v0.2.0
|
||||||
|
)
|
10
go.sum
Normal file
10
go.sum
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
github.com/d5/tengo/v2 v2.17.0 h1:BWUN9NoJzw48jZKiYDXDIF3QrIVZRm1uV1gTzeZ2lqM=
|
||||||
|
github.com/d5/tengo/v2 v2.17.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 h1:yEt5djSYb4iNtmV9iJGVday+i4e9u6Mrn5iP64HH5QM=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||||
|
surdeus.su/core/cli v0.1.2 h1:qPzjawqPyZsO4Z5SaA1u141recVE65yioA83Qs7Jecs=
|
||||||
|
surdeus.su/core/cli v0.1.2/go.mod h1:r9JtQz3aEJzpYzMaNUNQHJoYkoWKNPi047qhd5uGlmA=
|
||||||
|
surdeus.su/core/xgo v0.5.0 h1:/Rk3scfFkoSb0qjHRlkUNOp9sr/fd7wAvCiT4fBRo+U=
|
||||||
|
surdeus.su/core/xgo v0.5.0/go.mod h1:6C/AHbjfvAMvt3TOzLB4eIZ40eU3ahJXtdY+kr4yXoc=
|
||||||
|
surdeus.su/util/tpp v0.2.0 h1:9N78JPEUovDWdKnrdfrf05Jkz5xMA5hcBEWCIh4RWW0=
|
||||||
|
surdeus.su/util/tpp v0.2.0/go.mod h1:3bcSjGNd3vAevr6gPMI1/qJofxL7x53v0yB+Dr18CRM=
|
3
install.sh
Executable file
3
install.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
go install ./cmd/tht/
|
83
mdx/main.go
Normal file
83
mdx/main.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package mdx
|
||||||
|
import "github.com/gomarkdown/markdown"
|
||||||
|
import "github.com/gomarkdown/markdown/html"
|
||||||
|
import "github.com/gomarkdown/markdown/parser"
|
||||||
|
import "github.com/d5/tengo/v2"
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
|
type Markdown struct {
|
||||||
|
tengo.ObjectImpl
|
||||||
|
MakeParser func() *parser.Parser
|
||||||
|
MakeRenderer func() *html.Renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeDefaultMarkdown() *Markdown {
|
||||||
|
return &Markdown{
|
||||||
|
MakeParser: MakeDefaultParser,
|
||||||
|
MakeRenderer: MakeDefaultRenderer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *Markdown) TypeName() string {
|
||||||
|
return "*Markdown"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *Markdown) String() string {
|
||||||
|
if md == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
return "&Markdown{...}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *Markdown) Render(
|
||||||
|
data []byte,
|
||||||
|
) ([]byte, error) {
|
||||||
|
doc := md.MakeParser().Parse(data)
|
||||||
|
rendered := markdown.Render(doc, md.MakeRenderer())
|
||||||
|
return rendered, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *Markdown) CanCall() bool {
|
||||||
|
return md != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *Markdown) Call(
|
||||||
|
args ...tengo.Object,
|
||||||
|
) (tengo.Object, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
for _, arg := range args {
|
||||||
|
str, ok := tengo.ToString(arg)
|
||||||
|
if !ok {
|
||||||
|
return nil, tengo.ErrInvalidArgumentType{
|
||||||
|
Name: "v",
|
||||||
|
Expected: "stringer",
|
||||||
|
Found: arg.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.Write([]byte(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered, err := md.Render(b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tengo.FromInterface(rendered)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeDefaultParser() *parser.Parser {
|
||||||
|
return parser.NewWithExtensions(
|
||||||
|
parser.CommonExtensions | parser.AutoHeadingIDs |
|
||||||
|
parser.NoEmptyLineBeforeBlock | parser.Attributes |
|
||||||
|
parser.Tables,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeDefaultRenderer() *html.Renderer {
|
||||||
|
return html.NewRenderer(
|
||||||
|
html.RendererOptions{
|
||||||
|
Flags: html.CommonFlags | html.HrefTargetBlank,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
26
mod/post.tengo
Normal file
26
mod/post.tengo
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
paths := import("paths")
|
||||||
|
htmExt := func(c){
|
||||||
|
if c.is_compo {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.pp.print(`</body></html>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
exts := {
|
||||||
|
".htm": htmExt,
|
||||||
|
".html": htmExt
|
||||||
|
}
|
||||||
|
|
||||||
|
export func(c){
|
||||||
|
ext := paths.ext(c.pp.filepath)
|
||||||
|
ext = paths.ext(
|
||||||
|
c.pp.filepath[:len(c.pp.filepath) - len(ext)]
|
||||||
|
)
|
||||||
|
|
||||||
|
cl := exts[ext]
|
||||||
|
if !is_undefined(cl) {
|
||||||
|
cl(c)
|
||||||
|
}
|
||||||
|
}
|
40
mod/pre.tengo
Normal file
40
mod/pre.tengo
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
paths := import("paths")
|
||||||
|
html := import("html").new_render()
|
||||||
|
|
||||||
|
htmExt := func(c){
|
||||||
|
if c.is_compo {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.pp.print(`<!doctype html><html>`)
|
||||||
|
|
||||||
|
c.pp.print(html.head().body(
|
||||||
|
func(){
|
||||||
|
if c.title {
|
||||||
|
return html.title().body(c.title)
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
html.script({
|
||||||
|
src: `https://unpkg.com/htmx.org@1.9.2`
|
||||||
|
})
|
||||||
|
))
|
||||||
|
|
||||||
|
c.pp.print(`<body>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
exts := {
|
||||||
|
".htm": htmExt,
|
||||||
|
".html": htmExt
|
||||||
|
}
|
||||||
|
|
||||||
|
export func(c){
|
||||||
|
ext := paths.ext(c.pp.filepath)
|
||||||
|
ext = paths.ext(
|
||||||
|
c.pp.filepath[:len(c.pp.filepath) - len(ext)]
|
||||||
|
)
|
||||||
|
|
||||||
|
cl := exts[ext]
|
||||||
|
if cl {
|
||||||
|
cl(c)
|
||||||
|
}
|
||||||
|
}
|
189
server/handler.go
Normal file
189
server/handler.go
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"github.com/d5/tengo/v2"
|
||||||
|
"surdeus.su/util/tpp/mdx"
|
||||||
|
//"surdeus.su/core/xgo/xmodules/htmlx"
|
||||||
|
"surdeus.su/core/xgo/xmodules/httpx"
|
||||||
|
"surdeus.su/core/xgo/xmodules"
|
||||||
|
"surdeus.su/util/tpp"
|
||||||
|
"path/filepath"
|
||||||
|
"net/http"
|
||||||
|
"context"
|
||||||
|
"path"
|
||||||
|
"mime"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = http.Handler(&Handler{})
|
||||||
|
|
||||||
|
// The type describes behaviour
|
||||||
|
// of handling stuff like in PHP.
|
||||||
|
type Handler struct {
|
||||||
|
// THe field represents
|
||||||
|
// where we store site's
|
||||||
|
// source files and request handlers.
|
||||||
|
sourcePath string
|
||||||
|
// Preprocessor must be set by user
|
||||||
|
// to be able to bring custom features in.
|
||||||
|
pp *tpp.Preprocessor
|
||||||
|
// Aditional extension. ".tpp" by default.
|
||||||
|
// For example "file.html.tpp" will be
|
||||||
|
// first preprocessed TPP and sent back as simple HTML.
|
||||||
|
ext string
|
||||||
|
|
||||||
|
// The global map accessable from all the
|
||||||
|
// request so you can keep the states
|
||||||
|
// between requests.
|
||||||
|
global any
|
||||||
|
md *mdx.Markdown
|
||||||
|
indexSuffix string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the new Handler with
|
||||||
|
// specified preprocessor, source path,
|
||||||
|
// preprocessor extension and the global value.
|
||||||
|
func NewHandler(
|
||||||
|
pp *tpp.Preprocessor,
|
||||||
|
src, ext, index string,
|
||||||
|
global any,
|
||||||
|
) *Handler {
|
||||||
|
ret := &Handler{}
|
||||||
|
ret.sourcePath = src
|
||||||
|
ret.ext = ext
|
||||||
|
ret.pp = pp
|
||||||
|
ret.global = global
|
||||||
|
ret.indexSuffix = index
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the default tpp.Preprocessor suitable for
|
||||||
|
// the most needs.
|
||||||
|
func DefaultPP(mod string) *tpp.Preprocessor {
|
||||||
|
t := tpp.NewTengo().SetPreCompile(func(
|
||||||
|
ctx context.Context,
|
||||||
|
s *tpp.Script,
|
||||||
|
) {
|
||||||
|
s.SetImportDir(mod)
|
||||||
|
s.SetImports(xmodules.Modules)
|
||||||
|
s.EnableFileImport(true)
|
||||||
|
|
||||||
|
s.Add("__http_request__", ctx.Value(KeyRequest))
|
||||||
|
s.Add("__global__", ctx.Value(KeyGlobal))
|
||||||
|
s.Add("__markdown__", ctx.Value(KeyMarkdown))
|
||||||
|
}).SetPreCode(func(ctx context.Context) []byte {
|
||||||
|
return []byte(`
|
||||||
|
markdown := func(...args) {
|
||||||
|
pp.write_raw(__markdown__(args...))
|
||||||
|
}
|
||||||
|
__http__ := immutable({
|
||||||
|
request : __http_request__
|
||||||
|
})
|
||||||
|
context.http = __http__
|
||||||
|
context.pp = pp
|
||||||
|
context.global = __global__
|
||||||
|
import("./pre")(context)
|
||||||
|
`)
|
||||||
|
}).SetPostCode(func(ctx context.Context) []byte {
|
||||||
|
return []byte(`
|
||||||
|
import("./post")(context)
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
return tpp.New(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) SetMD(md *mdx.Markdown) *Handler {
|
||||||
|
h.md = md
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) ServeHTTP(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
|
shouldProcess := true
|
||||||
|
urlPath := r.URL.Path
|
||||||
|
// Cleaning URL path to prevent injections.
|
||||||
|
urlPath = path.Clean(urlPath)
|
||||||
|
urlExt := path.Ext(urlPath)
|
||||||
|
|
||||||
|
filePath := filepath.Join(
|
||||||
|
filepath.FromSlash(h.sourcePath),
|
||||||
|
filepath.FromSlash(urlPath),
|
||||||
|
)
|
||||||
|
fileStat, err := os.Stat(filePath)
|
||||||
|
if err == nil {
|
||||||
|
if fileStat.IsDir() {
|
||||||
|
filePath = filepath.Join(
|
||||||
|
filePath,
|
||||||
|
h.indexSuffix,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filePathTpp := filePath + h.ext
|
||||||
|
//log.Println("pth:", urlPath, filePathTpp)
|
||||||
|
file, err := os.Open(filePathTpp)
|
||||||
|
if err != nil {
|
||||||
|
shouldProcess = false
|
||||||
|
file, err = os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//process := true
|
||||||
|
fileData, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.WithValue(
|
||||||
|
r.Context(),
|
||||||
|
KeyRequest,
|
||||||
|
&httpx.Request{
|
||||||
|
Request: r,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx = context.WithValue(
|
||||||
|
ctx,
|
||||||
|
KeyGlobal,
|
||||||
|
h.global,
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx = context.WithValue(
|
||||||
|
ctx,
|
||||||
|
KeyMarkdown,
|
||||||
|
h.md,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setting before the code to let it change own
|
||||||
|
// content type?
|
||||||
|
contentType := mime.TypeByExtension(urlExt)
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
processedData := fileData
|
||||||
|
if shouldProcess {
|
||||||
|
processedData, err = h.pp.Process(
|
||||||
|
ctx,
|
||||||
|
true,
|
||||||
|
filePathTpp,
|
||||||
|
fileData,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
log.Printf(
|
||||||
|
"Error: pp.Process(...): %s\n",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(processedData)
|
||||||
|
}
|
53
server/tool.go
Normal file
53
server/tool.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
"github.com/d5/tengo/v2"
|
||||||
|
//"github.com/d5/tengo/v2/stdlib"
|
||||||
|
"surdeus.su/util/tpp/mdx"
|
||||||
|
"surdeus.su/core/cli/mtool"
|
||||||
|
"net/http"
|
||||||
|
"log"
|
||||||
|
//"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Context key type for internal usage.
|
||||||
|
type CKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
KeyRequest CKey = "http-request"
|
||||||
|
KeyGlobal = "global"
|
||||||
|
KeyMarkdown = "markdown"
|
||||||
|
KeyHTML = "html"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Simple PHP-like server implementation.
|
||||||
|
var Tool = mtool.T("tht").Func(func(flags *mtool.Flags) {
|
||||||
|
var (
|
||||||
|
addr, ext, src, mod, index string
|
||||||
|
)
|
||||||
|
|
||||||
|
flags.StringVar(&addr, "addr", ":3000", "address to serve at")
|
||||||
|
flags.StringVar(&mod, "mod", "./mod", "path to store Tengo modules")
|
||||||
|
flags.StringVar(&src, "src", "./src", "directory with source files")
|
||||||
|
flags.StringVar(&ext, "ext", ".tpp", "extension for TPP files")
|
||||||
|
flags.StringVar(&index, "index", "index.htm", "index file name")
|
||||||
|
|
||||||
|
flags.Parse()
|
||||||
|
|
||||||
|
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
Handler: NewHandler(
|
||||||
|
DefaultPP(mod),
|
||||||
|
src, ext, index,
|
||||||
|
map[string] tengo.Object{},
|
||||||
|
).SetMD(mdx.MakeDefaultMarkdown()),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Listening on %q\n", addr)
|
||||||
|
err := srv.ListenAndServe()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: srv.ListenAndServe(...): %s\n", err)
|
||||||
|
}
|
||||||
|
})
|
5
src/check.htm.tpp
Normal file
5
src/check.htm.tpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<main>shit</main>
|
||||||
|
{{
|
||||||
|
pp.print("cock")
|
||||||
|
}}
|
||||||
|
<main>later</main>
|
12
src/check/index.htm.tpp
Normal file
12
src/check/index.htm.tpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{{#
|
||||||
|
html := import("html").new_render()
|
||||||
|
}}
|
||||||
|
{{
|
||||||
|
h := html.main().body(
|
||||||
|
html.p().body(
|
||||||
|
"some paragraph shit"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
pp.print(h)
|
||||||
|
}}
|
20
src/contact/edit.htm.tpp
Normal file
20
src/contact/edit.htm.tpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{{#
|
||||||
|
context.is_compo = true
|
||||||
|
}}
|
||||||
|
|
||||||
|
<form hx-put="/contact/1" hx-target="this" hx-swap="outerHTML">
|
||||||
|
<div>
|
||||||
|
<label>First Name</label>
|
||||||
|
<input type="text" name="firstName" value="Joe">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Last Name</label>
|
||||||
|
<input type="text" name="lastName" value="Blow">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Email Address</label>
|
||||||
|
<input type="email" name="email" value="joe@blow.com">
|
||||||
|
</div>
|
||||||
|
<button class="btn">Submit</button>
|
||||||
|
<button class="btn" hx-get="/contact/view.htm">Cancel</button>
|
||||||
|
</form>
|
13
src/contact/view.htm.tpp
Normal file
13
src/contact/view.htm.tpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{{#
|
||||||
|
//context.is_compo = true
|
||||||
|
}}
|
||||||
|
|
||||||
|
<div hx-target="this" hx-swap="outerHTML">
|
||||||
|
<div><label>First Name</label>: Joe</div>
|
||||||
|
<div><label>Last Name</label>: Blow</div>
|
||||||
|
<div><label>Email</label>: joe@blow.com</div>
|
||||||
|
<button hx-get="/contact/edit.htm" class="btn btn-primary">
|
||||||
|
Click To Edit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
11
src/incorrect.htm.tpp
Normal file
11
src/incorrect.htm.tpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
html := import("html").new_render()
|
||||||
|
|
||||||
|
pp.print(html.html().body(
|
||||||
|
html.head().body(
|
||||||
|
html.title().body(
|
||||||
|
"some title"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
html.body().body(
|
||||||
|
)
|
||||||
|
))
|
78
src/index.htm.tpp
Normal file
78
src/index.htm.tpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{{#
|
||||||
|
context.title = "The example.site main page"
|
||||||
|
|
||||||
|
fmt := import("fmt")
|
||||||
|
html := import("html").new_render()
|
||||||
|
}}
|
||||||
|
|
||||||
|
<h1>This is the example page for the THT</h1>
|
||||||
|
{{
|
||||||
|
/*if !context.global.int {
|
||||||
|
context.global.int = 0
|
||||||
|
} else {
|
||||||
|
context.global.int++
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if !context.global.val {
|
||||||
|
context.global.val = 1
|
||||||
|
} else {
|
||||||
|
context.global.val += 1
|
||||||
|
}
|
||||||
|
fmt.println("global: ", context.global)
|
||||||
|
req := context.http.request
|
||||||
|
q := req.url.query
|
||||||
|
// List checking.
|
||||||
|
list := []
|
||||||
|
rng := int(q.range[0])
|
||||||
|
fmt.println("range:", q.range)
|
||||||
|
if rng {
|
||||||
|
pp.print(`<ul name="range">`)
|
||||||
|
for i:=0 ; i < rng ; i++ {
|
||||||
|
pp.printf("<li>%d</li>", i)
|
||||||
|
}
|
||||||
|
pp.print("</ul>")
|
||||||
|
}
|
||||||
|
if q.name {
|
||||||
|
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
<div name="counter">
|
||||||
|
{{ pp.print(context.global.val) }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Hello, Cock!
|
||||||
|
</div>
|
||||||
|
<div check>
|
||||||
|
{{
|
||||||
|
pp.print(req.url.path)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<ul>{{
|
||||||
|
for v in list {
|
||||||
|
pp.print("<li>", v, "</li>")
|
||||||
|
}
|
||||||
|
}}</ul>
|
||||||
|
|
||||||
|
{{
|
||||||
|
vals := ["die", "with", "them", "as", "you", 1, "could", "do"]
|
||||||
|
pp.print(html.div({
|
||||||
|
id: "the-uniq-shit"
|
||||||
|
}).body(
|
||||||
|
html.ul(
|
||||||
|
).body(
|
||||||
|
func(){
|
||||||
|
ret := []
|
||||||
|
for i:=0 ; i<len(vals) ; i++{
|
||||||
|
ret += [html.li({
|
||||||
|
class: "someclass"
|
||||||
|
}).body(i, ": ", vals[i])]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}()...
|
||||||
|
)
|
||||||
|
))
|
||||||
|
}}
|
||||||
|
|
||||||
|
<script src="/script.js" ></script>
|
||||||
|
|
||||||
|
<div></div>
|
37
src/main.htm.tpp
Normal file
37
src/main.htm.tpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{{#
|
||||||
|
context.title = "The example.site main page"
|
||||||
|
|
||||||
|
fmt := import("fmt")
|
||||||
|
html := import("html").new_render()
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{
|
||||||
|
pp.print(
|
||||||
|
html.h1().body("This is the example page for THT")
|
||||||
|
)
|
||||||
|
|
||||||
|
if !context.global.val {
|
||||||
|
context.global.val = 1
|
||||||
|
} else {
|
||||||
|
context.global.val += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{
|
||||||
|
req := context.http.request
|
||||||
|
q := req.url.query
|
||||||
|
// List checking.
|
||||||
|
rng := int(q.range[0])
|
||||||
|
fmt.println("range:", q.range)
|
||||||
|
if rng {
|
||||||
|
pp.print(`<ul name="range">`)
|
||||||
|
for i:=0 ; i < rng ; i++ {
|
||||||
|
pp.printf("<li>%d</li>", i)
|
||||||
|
}
|
||||||
|
pp.print("</ul>")
|
||||||
|
}
|
||||||
|
if q.name {
|
||||||
|
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||||
|
}
|
||||||
|
}}
|
35
src/page.htm.tpp
Normal file
35
src/page.htm.tpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{{#
|
||||||
|
context.title = "Let's celebrate and suck, SOME DICK"
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{markdown(`
|
||||||
|
|
||||||
|
# Hello, World!
|
||||||
|
|
||||||
|
This is the markdown example shit.
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
print("Fuck you")
|
||||||
|
}
|
||||||
|
|
||||||
|
## Yet another level of header
|
||||||
|
|
||||||
|
And even more text
|
||||||
|
|
||||||
|
> Cheap is talk, show me the code.
|
||||||
|
|
||||||
|
(c) Linus Torvalds
|
||||||
|
|
||||||
|
`)}}
|
||||||
|
|
||||||
|
<div id="uniq">
|
||||||
|
Even <strong>more</strong> HTML
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{markdown(`
|
||||||
|
### Third level header
|
||||||
|
|
||||||
|
Some shit
|
||||||
|
|
||||||
|
#### `, 135, `
|
||||||
|
`)}}
|
8
src/req.json.tpp
Normal file
8
src/req.json.tpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"error": null,
|
||||||
|
"data": {
|
||||||
|
"name": "Andrey",
|
||||||
|
"surname": "Parhomenko",
|
||||||
|
"age": 22
|
||||||
|
}
|
||||||
|
}
|
3
src/request.json
Normal file
3
src/request.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name":"Andrew"
|
||||||
|
}
|
3
src/script.js
Normal file
3
src/script.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
console.log("Hello, World!")
|
||||||
|
|
Loading…
Reference in a new issue