+++ /dev/null
-# Today Web Engine
-
-The Today engine builds on Go's templating with reusable parts in the style of
-the Web Components standard. It aims to be usable for anything from static HTML
-websites to complex applications with a mix of server and client-side behavior.
-
-## Install
-
-```sh
-go get git.earlybird.gay/today-engine@latest
-```
-
-## Usage
-
-Currently, the `examples` folder contains a site going through concepts by
-example. You can walk through these examples yourself by installing them as
-an executable:
-
-```sh
-go install git.earlybird.gay/today-engine/cmd/run-today-examples@latest
-run-today-examples
-```
-
-## License
-
-> This section is not legally binding, please read the license text for
-> specifics!
-
-The Today Web Engine is licensed under the LGPL (GNU Lesser General Public
-License). This license affects how you can run, modify, and distribute
-today-engine. In short:
-
-- If you modify today-engine, you have to publish your modifications under the
- GPL or LGPL.
-- If you use today-engine without modifying it, you're in the clear.
-- Building a website using today-engine does not count as modifying today-engine.
--- /dev/null
+===== Today Engine =============================================================
+
+The Today engine builds on Go's templating with reusable parts in the style of
+the Web Components standard. It aims to be usable for anything from static HTML
+websites to complex applications with a mix of server and client-side behavior.
+
+===== Install ==================================================================
+
+go get git.earlybird.gay/today-engine@latest
+
+===== Usage ====================================================================
+
+I'm working on a by-example application to help with this.
+
+===== License ==================================================================
+
+> This section is not legally binding, please read the license text for
+> specifics!
+
+The Today Web Engine is licensed under the LGPL (GNU Lesser General Public
+License). This license affects how you can run, modify, and distribute
+today-engine. In short:
+
+- If you modify today-engine, you have to publish your modifications under the
+ GPL or LGPL.
+- If you use today-engine without modifying it, you're in the clear.
+- Building a website using today-engine does not count as modifying today-engine.
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package engine
-
-import (
- "net/http"
-)
-
-type App struct {
- http.ServeMux
-}
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package ex01
-
-import (
- "git.earlybird.gay/today-engine/page"
-)
-
-// Make a page like this, with page.New(name, file). Name doesn't matter much
-// for pages. File is a path to a file relative to *this Go file*, NOT the
-// working directory.
-// A Page is an http.Handler!
-var Page = page.New("ex01", "page.html")
+++ /dev/null
-<!DOCTYPE html>
-<html lang="en-US">
-<head>
- <title>Example 1</title>
- <link rel="stylesheet" href="/style.css">
-</head>
-
-<body>
- <main>
- <h1>Static HTML</h1>
- <p>Today supports regular HTML, without any modification. All of the
- features you'll see in these examples add on to the "normal experience".
- For each example, you'll see the rendered result in the browser, plus
- source files to show how that example is constructed.
- </p>
-
- <nav>
- <a href="/ex02">Parts ></a>
- <a href="/">Back to Overview</a>
- </nav>
-
- <h2>Sources for this example</h2>
- <!-- source-preview does not belong to the HTML specification, but elements
- with - in the name are allowed! We're going to do something with this in
- a second. -->
- <source-preview>
- <h3>page.html</h3>
- <pre><code>ᐸ!DOCTYPE htmlᐳ
-ᐸhtmlᐳ
-ᐸheadᐳ
- ᐸtitleᐳExample 1ᐸ/titleᐳ
- ᐸlink rel="stylesheet" href="/style.css"ᐳ
-ᐸ/headᐳ
-
-ᐸbodyᐳ
- ᐸmainᐳ
- ᐸh1ᐳStatic HTMLᐸ/h1ᐳ
- ᐸpᐳToday supports regular HTML, without any modification. All of the
- features you'll see in these examples add on to the "normal experience".
- For each example, you'll see the rendered result in the browser, plus
- source files to show how that example is constructed.
- ᐸ/pᐳ
-
- ᐸh2ᐳSources for this exampleᐸ/h2ᐳ
- ᐸ!-- source-preview does not belong to the HTML specification, but elements
- with - in the name are allowed! We're going to do something with this in
- a second. --ᐳ
- ᐸsource-previewᐳ
- ᐸh3ᐳpage.htmlᐸ/h3ᐳ
- ᐸpreᐳᐸcodeᐳ...ᐸ/codeᐳᐸ/preᐳ
- ᐸ/source-previewᐳ
- ᐸsource-previewᐳ
- ᐸh3ᐳexample.goᐸ/h3ᐳ
- ᐸpreᐳᐸcodeᐳ...ᐸ/codeᐳᐸ/preᐳ
- ᐸ/source-previewᐳ
- ᐸnavᐳ
- ᐸa href="/ex02"ᐳPartsᐸ/aᐳ
- ᐸa href="/"ᐳBack to Overviewᐸ/aᐳ
- ᐸ/navᐳ
- ᐸ/mainᐳ
-ᐸ/bodyᐳ
-
-ᐸ/htmlᐳ</code></pre>
- </source-preview>
- <source-preview>
- <h3>example.go</h3>
- <pre><code>// Copyright (C) 2024 early (LGPL)
-package ex01
-
-import (
- "git.earlybird.gay/today-engine/page"
-)
-
-// Make a page like this, with page.New(name, file). Name doesn't matter much
-// for pages. File is a path to a file relative to *this Go file*, NOT the
-// working directory.
-// A Page is an http.Handler!
-var Page = page.New("ex01", "page.html")
- </code></pre>
- </source-preview>
- </main>
-</body>
-
-</html>
\ No newline at end of file
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package ex02
-
-import (
- "math/rand/v2"
-
- "git.earlybird.gay/today-engine/cmd/run-today-examples/parts"
- "git.earlybird.gay/today-engine/include"
- "git.earlybird.gay/today-engine/page"
- "git.earlybird.gay/today-engine/part"
- "git.earlybird.gay/today-engine/render"
-)
-
-// Like pages, you make parts with part.New. The name is more important for
-// parts, since the name is the name of the element in HTML.
-var RandomGenerator = part.New("random-generator", "random-generator.html",
- part.OnLoad(func(data render.Data) error {
- // Generate a random number on load.
- data.Set("number", rand.Int()%100)
- return nil
- }),
-)
-
-var Page = page.New("ex01", "page.html",
- // When you want to use a part, you need to say so in page.Includes.
- page.Includes(RandomGenerator, parts.SourcePreview),
- page.OnLoad(func(data render.Data) error {
- // This is all for SourcePreview, don't worry about it just yet.
- sources := make(render.Data)
- sources.Set("page", include.File("page.html"))
- sources.Set("go", include.File("example.go"))
- data.Set("sources", sources)
- return nil
- }),
-)
+++ /dev/null
-<!DOCTYPE html>
-<html>
-
-<head>
- <title>Example 1</title>
- <link rel="stylesheet" href="/style.css">
-</head>
-
-<body>
- <main>
- <h1>Parts</h1>
- <p>
- In the previous example, you saw a <code>source-preview</code> element,
- which is not part of the HTML specification. However, custom elements with
- a - in the name are allowed by the specification, because they are used
- for the Web Components feature of the web platform. Today Engine borrows
- this for use with server-side "parts". Examples will focus on these for
- now, but we'll get into Web Components and how they're different later.
- </p>
- <p>
- Parts allow you to define custom elements that are rendered server-side,
- before any content is sent to the user agent. Each part can execute some
- behavior in Go, and decide how it is rendered based on the result. Here
- is a part that generates a random number every time the page is reloaded.
- </p>
-
- <random-generator></random-generator>
-
- <p>This isn't super useful.</p>
- <ul>
- <li>Generating a random number doesn't do much.</li>
- <li>We don't have any control over how the part chooses a number.</li>
- <li>
- It has an h3, but what if we need an h4 because of where it is in the
- document, or we want to change what the header says?
- </li>
- </ul>
- <p>
- Fortunately, these are solvable problems. In the next few examples, we'll
- evaluate how to make replacable markup in parts using slots and pass data
- using attributes.
- </p>
-
- <nav>
- <a href="/ex01">< Pages</a>
- <!--a href="/ex02">Parts ></a-->
- <a href="/">Back to Overview</a>
- </nav>
-
- <!--
- Source previews will now use this source-preview part instead of
- manually pasting in safe "html" or other code.
- -->
- <h2>Sources for this example</h2>
- <source-preview :source=".sources.page">
- <h3 slot="title">page.html</h3>
- </source-preview>
- <source-preview :source=".sources.go">
- <h3 slot="title">example.go</h3>
- </source-preview>
- </main>
-</body>
-
-</html>
\ No newline at end of file
+++ /dev/null
-<template>
- <h3>Oh wow, a random number.</h3>
- <!-- This value is set in random-generator.OnLoad. -->
- <p>{{ .number }}</p>
-</template>
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE html>
-<html>
- <header>
- <title>Today Engine Examples</title>
- </header>
- <body>
- <h1>Today Engine Examples</h1>
- <p>This is a set of examples for usage of the Today Web Engine!</p>
- <h2>Links</h2>
- <ol>
- <li><a href="/ex01">Pages</a></li>
- <li><a href="/ex02">Parts</a></li>
- <li><a href="/ex03">Slots</a></li>
- <li><a href="/ex04">Go Templates</a></li>
- <li>N/A</li>
- <li><a href="/ex06">Passing Data to Parts</a></li>
- <li><a href="/ex07">Web Components</a></li>
- </ol>
- </body>
-</html>
\ No newline at end of file
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package main
-
-import (
- "net/http"
-
- "git.earlybird.gay/today-engine/cmd/run-today-examples/ex01-pages"
- "git.earlybird.gay/today-engine/cmd/run-today-examples/ex02-parts"
- "git.earlybird.gay/today-engine/page"
-)
-
-var index = page.New("index", "index.html")
-
-func main() {
- mux := new(http.ServeMux)
- mux.Handle("GET /{$}", index)
- mux.Handle("GET /ex01", ex01.Page)
- mux.Handle("GET /ex02", ex02.Page)
- mux.Handle("GET /", http.FileServer(http.Dir("cmd/run-today-examples/public")))
-
- http.ListenAndServe("0.0.0.0:3000", mux)
-}
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package parts
-
-import (
- "errors"
- "io"
- "strings"
-
- "git.earlybird.gay/today-engine/include"
- "git.earlybird.gay/today-engine/part"
- "git.earlybird.gay/today-engine/render"
-)
-
-var SourcePreview = part.New("source-preview", "source-preview.html",
- part.OnLoad(func(data render.Data) error {
- opener, ok := data.Get("source").(include.Opener)
- if !ok || opener == nil {
- return errors.New("source-preview requires include.Opener source")
- }
- file, err := opener.Open()
- if err != nil {
- return err
- }
- buf := new(strings.Builder)
- io.Copy(buf, file)
- data.Set("source_raw", buf.String())
- return nil
- }),
-)
+++ /dev/null
-<template>
- <slot name="title"><h3>Page preview:</h3></slot>
- <pre><code>{{ .source_raw }}</code></pre>
-</template>
\ No newline at end of file
+++ /dev/null
-/* The Great Reset */
-* {
- padding: 0;
- margin: 0;
-}
-
-/* Containers */
-
-main, section, nav {
- display: flex;
- flex-direction: column;
- gap: .5rem;
-}
-
-main {
- margin: 2rem 20%;
-}
-
-/* Typography */
-
-/* Styling for parts and app-specific stuff */
-
-source-preview {
- width: fit-content;
- border: 1px solid black;
- border-radius: 5px;
- overflow: hidden;
-}
-
-source-preview > * {
- padding: 1rem;
-}
-
-source-preview pre {
- background-color: lightgray;
-}
module git.earlybird.gay/today-engine
-go 1.22.0
+go 1.22.4
require golang.org/x/net v0.27.0