Compiles HTML to Elixir. Who says HTML is not a programming language?
This module is just another templating engine.
With elixir, we can leverage its ability to call individual functions in iex
mode.
Elixir can quickly build templates on the fly.
Notice: This Project Is Still In Beta.
# install the go module
go get github.com/tkdeng/htmlc
# or install the binary
git clone https://github.com/tkdeng/htmlc.git &&\
cd htmlc &&\
make install &&\
cd ../ && rm -r htmlc
# install into /usr/bin
make install
# install locally (with dependencies)
make local
# build without dependency installation
make build
# install dependencies
make deps
# uninstall htmlc
make clean
import (
"github.com/tkdeng/htmlc"
)
func main(){
htmlc.Compile("./src", "./output.exs")
engine, err := htmlc.Engine("./output.exs")
// on page request
buf, err := engine.Render("index", htmlc.Map{"args": "my args"}, "layout")
}
import (
"github.com/gofiber/fiber/v3"
htmlcfiber "github.com/tkdeng/htmlc/gofiber"
)
func main(){
engine, err := htmlcfiber.New("./src")
if err != nil {
panic(err)
}
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/", func(c fiber.Ctx) error {
return c.Render("index", fiber.Map{"title": "Test"}, "layout")
})
app.Listen(":3000")
}
htmlc ./src --out="./output.exs"
You can also specify a port number, to automatically start a static-like http server.
htmlc ./src --port="3000"
Note: by default, "--out" is set to the same directory, with the file name set to the base folder name.
# compile
htmlc ./src
# start template engine
elixir ./html.exs
# render page
> render, mypage/home, mylayout/layout, eyJqc29uIjogImFyZ3MifQ==
# base64({"json": "args"})
# render widget (optional)
> widget, mywidget/app, eyJqc29uIjogImFyZ3MifQ==
# base64({"json": "args"})
# render layout (optional)
> layout, mylayout/layout, eyJqc29uIjogImFyZ3MifQ==, eyJqc29uIjogImh0bWwgY29udGVudCJ9
# base64({"json": "args"}), base64({"json": "html content"})
# stop template engine
stop
# compile
htmlc --iex ./src
# start template engine
iex ./html.exs
# render page
iex> App.render "mypage/home", "mylayout/layout", %{args: "myarg"}
# render widget (optional)
iex> App.widget "mywidget/app", %{args: "myarg"}
# render layout (optional)
iex> App.layout "mylayout/layout", %{args: "myarg"}, %{body: "page embed"}
# stop template engine
iex> System.halt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0"/>
<meta name="description" content="{desc}"/>
<title>{title}<!-- {variable} --></title>
{@head} <!-- embed page head -->
</head>
<body>
{@body} <!-- embed page body -->
</body>
</html>
<_@head> <!-- embed into layout {@head} reference -->
<link rel="stylesheet" href="/style.css">
</_@head>
<_@body> <!-- embed into {@body} -->
<h1>Hello, World</h1>
<!-- use `<_#name>` to embed widgets -->
<_#app n="2">
widget body
</_#app>
<main>
{&main} <!-- {&variable} use `&` to allow raw HTML -->
</main>
</_@body>
<div class="widget">
<!-- use <% scripts %> to run elixir (feature not yet implemented) -->
{n} * 2 = <%
args.n * 2
%>
</div>
<!-- markdown not yet implemented -->
<md>
Markdown
</md>
<markdown>
Markdown
</markdown>