xyproto / algernon

Small self-contained pure-Go web server with Lua, Teal, Markdown, Ollama, HTTP/2, QUIC, Redis, SQLite and PostgreSQL support ++
https://algernon.roboticoverlords.org
BSD 3-Clause "New" or "Revised" License
2.81k stars 137 forks source link

Support LuaX #146

Open tooolbox opened 8 months ago

tooolbox commented 8 months ago

See https://bvisness.me/luax/

Essentially you could output HTML pages using a JSX-like syntax:

-- I can define whatever data I like in plain old Lua.
local articles = {
  {
    title = "I made JSX for Lua (because I hate static sites)",
    description = "This site now runs on a custom dialect of Lua.",
    slug = "luax",
    date = os.time({ year = 2023, month = 12, day = 27 }),
  },
  -- more articles...
}

-- "Components" are just Lua functions that return HTML.
-- Lua expressions can be placed in attributes or text.
function Article(atts, children)
  local a = atts.article
  return <article>
    <header>
      <h1><a href={ absurl(a.slug) }>{{ a.title }}</a></h1>
      <span class="post-details">
        <time datetime={ os.date("%Y-%m-%dT%H:%M:%S%z", atts.date) } itemprop="datePublished">
          {{ os.date("%B %-d, %Y", atts.date) }}
        </time>
      </span>
    </header>
    <p>
      {{ a.description }}
    </p>
  </article>
end

-- I can use Lua's package system to organize my templates.
require("base")

-- Whatever the file returns will be rendered and sent to the browser.
return <Base>
  <div class="list">
    {{ map(articles, function (a)
      <Article article={ a } />
    end) }}
  </div>
</Base>

I would vastly prefer this to any of the other template systems that exist. It does depend on LuaX getting extracted from the creator's personal project and made into a module that can be imported, which I have raised an issue on here: https://github.com/bvisness/bvisness.me/issues/1

tooolbox commented 8 months ago

Looks like bvisness is not interested in extracting it, but is fine with the code being used. Added an MIT license but annoyingly pkg.go.dev still doesn't pick it up, may or may not recognize the license in the subdirectory, so the API is not super visible.

Still, this is exported and looks appropriate: func Transpile(source, filename string) (string, error)