From 0d7b190c236e8ec222629dece1541eda6110dbe7 Mon Sep 17 00:00:00 2001 From: early Date: Tue, 30 Jul 2024 12:59:08 -0600 Subject: [PATCH] rework examples a bit --- cmd/run-today-examples/ex01-pages/example.go | 7 +- cmd/run-today-examples/ex01-pages/page.html | 95 ++++++++++++++++--- cmd/run-today-examples/ex02-parts/example.go | 28 +++++- cmd/run-today-examples/ex02-parts/page.html | 79 +++++++++++---- .../ex02-parts/random-generator.html | 5 + .../ex02-parts/section.html | 6 -- cmd/run-today-examples/ex03-slots/example.go | 13 --- cmd/run-today-examples/ex03-slots/page.html | 33 ------- .../ex03-slots/section.html | 13 --- .../ex04-templates/example.go | 29 ------ .../ex04-templates/page.html | 39 -------- cmd/run-today-examples/ex06-data/example.go | 42 -------- .../ex06-data/message-printer.html | 4 - cmd/run-today-examples/ex06-data/page.html | 25 ----- .../ex07-components/counter.html | 15 --- .../ex07-components/example.go | 11 --- .../ex07-components/page.html | 17 ---- cmd/run-today-examples/main.go | 9 +- cmd/run-today-examples/parts/example-nav.html | 7 -- cmd/run-today-examples/parts/parts.go | 27 +++++- .../parts/source-preview.html | 4 + cmd/run-today-examples/public/style.css | 37 +++++++- internal/compile/component.go | 2 - 23 files changed, 241 insertions(+), 306 deletions(-) create mode 100644 cmd/run-today-examples/ex02-parts/random-generator.html delete mode 100644 cmd/run-today-examples/ex02-parts/section.html delete mode 100644 cmd/run-today-examples/ex03-slots/example.go delete mode 100644 cmd/run-today-examples/ex03-slots/page.html delete mode 100644 cmd/run-today-examples/ex03-slots/section.html delete mode 100644 cmd/run-today-examples/ex04-templates/example.go delete mode 100644 cmd/run-today-examples/ex04-templates/page.html delete mode 100644 cmd/run-today-examples/ex06-data/example.go delete mode 100644 cmd/run-today-examples/ex06-data/message-printer.html delete mode 100644 cmd/run-today-examples/ex06-data/page.html delete mode 100644 cmd/run-today-examples/ex07-components/counter.html delete mode 100644 cmd/run-today-examples/ex07-components/example.go delete mode 100644 cmd/run-today-examples/ex07-components/page.html delete mode 100644 cmd/run-today-examples/parts/example-nav.html create mode 100644 cmd/run-today-examples/parts/source-preview.html diff --git a/cmd/run-today-examples/ex01-pages/example.go b/cmd/run-today-examples/ex01-pages/example.go index 82bd9b2..ee1056f 100644 --- a/cmd/run-today-examples/ex01-pages/example.go +++ b/cmd/run-today-examples/ex01-pages/example.go @@ -2,8 +2,11 @@ package ex01 import ( - "git.earlybird.gay/today-engine/cmd/run-today-examples/parts" "git.earlybird.gay/today-engine/page" ) -var Page = page.New("ex01", "page.html", page.Includes(parts.ExampleNav)) +// 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") diff --git a/cmd/run-today-examples/ex01-pages/page.html b/cmd/run-today-examples/ex01-pages/page.html index 1e3cc1d..b5ba9b6 100644 --- a/cmd/run-today-examples/ex01-pages/page.html +++ b/cmd/run-today-examples/ex01-pages/page.html @@ -1,15 +1,84 @@ - -
- Example 1 -
- -

Static HTML

-

This is a static page. Hooray.

- - - - Parts - - + + + Example 1 + + + + +
+

Static HTML

+

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. +

+ + + +

Sources for this example

+ + +

page.html

+
ᐸ!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ᐳ
+
+ +

example.go

+
// 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")
+      
+
+
+ + \ No newline at end of file diff --git a/cmd/run-today-examples/ex02-parts/example.go b/cmd/run-today-examples/ex02-parts/example.go index 3a7b821..cfb3fea 100644 --- a/cmd/run-today-examples/ex02-parts/example.go +++ b/cmd/run-today-examples/ex02-parts/example.go @@ -2,12 +2,34 @@ 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" ) -var section = part.New("my-section", "section.html") +// 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 + }), +) -// Use *.Includes to include a part as a dependency. -var Page = page.New("ex02", "page.html", page.Includes(section, parts.ExampleNav)) +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 + }), +) diff --git a/cmd/run-today-examples/ex02-parts/page.html b/cmd/run-today-examples/ex02-parts/page.html index 830c64d..8b6dd31 100644 --- a/cmd/run-today-examples/ex02-parts/page.html +++ b/cmd/run-today-examples/ex02-parts/page.html @@ -1,23 +1,64 @@ -
- Example 2 -
- -

Page with Parts

-

This page uses "parts" to create sections on the page. Parts are - HTML blocks that you can re-use. -

- - -

Section

-

This is inner HTML for a my-section "part". It replaces the slot tag - in the part. -

-
- - Pages - Slots - + + Example 1 + + + + +
+

Parts

+

+ In the previous example, you saw a source-preview 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. +

+

+ 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. +

+ + + +

This isn't super useful.

+ +

+ 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. +

+ + + + +

Sources for this example

+ +

page.html

+
+ +

example.go

+
+
+ + \ No newline at end of file diff --git a/cmd/run-today-examples/ex02-parts/random-generator.html b/cmd/run-today-examples/ex02-parts/random-generator.html new file mode 100644 index 0000000..6bff857 --- /dev/null +++ b/cmd/run-today-examples/ex02-parts/random-generator.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/cmd/run-today-examples/ex02-parts/section.html b/cmd/run-today-examples/ex02-parts/section.html deleted file mode 100644 index a4fb103..0000000 --- a/cmd/run-today-examples/ex02-parts/section.html +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/cmd/run-today-examples/ex03-slots/example.go b/cmd/run-today-examples/ex03-slots/example.go deleted file mode 100644 index 823218b..0000000 --- a/cmd/run-today-examples/ex03-slots/example.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2024 early (LGPL) -package ex03 - -import ( - "git.earlybird.gay/today-engine/cmd/run-today-examples/parts" - "git.earlybird.gay/today-engine/page" - "git.earlybird.gay/today-engine/part" -) - -var section = part.New("my-section", "section.html") - -// Use *.Includes to include a part as a dependency. -var Page = page.New("ex03", "page.html", page.Includes(section, parts.ExampleNav)) diff --git a/cmd/run-today-examples/ex03-slots/page.html b/cmd/run-today-examples/ex03-slots/page.html deleted file mode 100644 index 2ea74a3..0000000 --- a/cmd/run-today-examples/ex03-slots/page.html +++ /dev/null @@ -1,33 +0,0 @@ - - -
- Example 3 -
- -

Page with Parts

-

This page uses "parts" to create sections on the page. Parts are - HTML blocks that you can re-use. -

- - - -

Section with Named Slots

-

Use the slot tag to fill in named slots.

-

You can do this with multiple HTML elements!

-
- - - -

Section with a Subsection

-

You can also include parts inside parts.

- -

Subsection

-

This my-section is a subsection!

-
-
- - - Parts - Go Templates - - \ No newline at end of file diff --git a/cmd/run-today-examples/ex03-slots/section.html b/cmd/run-today-examples/ex03-slots/section.html deleted file mode 100644 index 75f31ac..0000000 --- a/cmd/run-today-examples/ex03-slots/section.html +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/cmd/run-today-examples/ex04-templates/example.go b/cmd/run-today-examples/ex04-templates/example.go deleted file mode 100644 index 43f4cd2..0000000 --- a/cmd/run-today-examples/ex04-templates/example.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2024 early (LGPL) -package ex04 - -import ( - "text/template" - - "git.earlybird.gay/today-engine/cmd/run-today-examples/parts" - "git.earlybird.gay/today-engine/page" - "git.earlybird.gay/today-engine/render" -) - -var Page = page.New("ex04", "page.html", - page.OnLoad(func(data render.Data) error { - data.Set("message", "Hello, Today!") - return nil - }), - page.Funcs(template.FuncMap{ - "reverse": func(s string) string { - out := make([]byte, len(s)) - for i := range (len(s) + 1) / 2 { - j := len(s) - i - 1 - out[i] = s[j] - out[j] = s[i] - } - return string(out) - }, - }), - page.Includes(parts.ExampleNav), -) diff --git a/cmd/run-today-examples/ex04-templates/page.html b/cmd/run-today-examples/ex04-templates/page.html deleted file mode 100644 index 23f0124..0000000 --- a/cmd/run-today-examples/ex04-templates/page.html +++ /dev/null @@ -1,39 +0,0 @@ - - -
- Example 4 -
- -

Template Data

-

Let's step back to talk about template data. Go provides templates - using "handlebars" notation to create server-side behavior on your - pages. For example, on this page, {{ `{{ .message }}` }} is - "{{ .message }}". -

-

You can also add functions, if the ones provided do not do everything - you need. On this page, {{ `{{ reverse "hello" }}`}} is - "{{ reverse "hello" }}". -

-
var index = page.New("index", "index.html",
-    page.OnLoad(func(data render.Data) error {
-        data.Set("message", "Hello, Today!")
-        return nil
-    }),
-    page.Funcs(template.FuncMap{
-        "reverse": func(s string) string {
-            out := make([]byte, len(s))
-            for i := range (len(s) + 1) / 2 {
-                j := len(s) - i - 1
-                out[i] = s[j]
-                out[j] = s[i]
-            }
-            return string(out)
-        },
-    }),
-)
- - - Slots - - - \ No newline at end of file diff --git a/cmd/run-today-examples/ex06-data/example.go b/cmd/run-today-examples/ex06-data/example.go deleted file mode 100644 index 7154bd2..0000000 --- a/cmd/run-today-examples/ex06-data/example.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2024 early (LGPL) -package ex06 - -import ( - "errors" - "strings" - - "git.earlybird.gay/today-engine/cmd/run-today-examples/parts" - "git.earlybird.gay/today-engine/page" - "git.earlybird.gay/today-engine/part" - "git.earlybird.gay/today-engine/render" -) - -type exampleStruct struct { - Data string -} - -var Page = page.New("ex01", "page.html", - page.OnLoad(func(data render.Data) error { - // This sets .some.really.nested.Data to "hello!". - // Bit of a silly example, but it shows the point. - data.Set("some", map[string]any{ - "really": map[string]any{ - "nested": exampleStruct{ - Data: "hello, nested data!", - }, - }, - }) - return nil - }), - page.Includes(parts.ExampleNav, messagePrinter), -) -var messagePrinter = part.New("message-printer", "message-printer.html", - part.OnLoad(func(data render.Data) error { - message, ok := data.Get("message").(string) - if !ok { - return errors.New("no message set") - } - data.Set("transformedMessage", strings.ToUpper(message)) - return nil - }), -) diff --git a/cmd/run-today-examples/ex06-data/message-printer.html b/cmd/run-today-examples/ex06-data/message-printer.html deleted file mode 100644 index 7ee3d8b..0000000 --- a/cmd/run-today-examples/ex06-data/message-printer.html +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/cmd/run-today-examples/ex06-data/page.html b/cmd/run-today-examples/ex06-data/page.html deleted file mode 100644 index cf6c2b6..0000000 --- a/cmd/run-today-examples/ex06-data/page.html +++ /dev/null @@ -1,25 +0,0 @@ - - -
- Example 6 -
- -

Passing Data to Parts

-

Sometimes, you may want to provide more data to a part than just the - HTML to include. To do this, write attributes on the part that start - with a colon ":". -

-

You can even do this with template fields by starting with a ".". - Unfortunately, full template pipelines aren't supported this way - right now. You can only pass a string or a value contained in the - parent data. -

- - - - - - Parts - - - \ No newline at end of file diff --git a/cmd/run-today-examples/ex07-components/counter.html b/cmd/run-today-examples/ex07-components/counter.html deleted file mode 100644 index 5ee7850..0000000 --- a/cmd/run-today-examples/ex07-components/counter.html +++ /dev/null @@ -1,15 +0,0 @@ - - diff --git a/cmd/run-today-examples/ex07-components/example.go b/cmd/run-today-examples/ex07-components/example.go deleted file mode 100644 index 8f7afb8..0000000 --- a/cmd/run-today-examples/ex07-components/example.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2024 early (LGPL) -package ex07 - -import ( - "git.earlybird.gay/today-engine/cmd/run-today-examples/parts" - "git.earlybird.gay/today-engine/component" - "git.earlybird.gay/today-engine/page" -) - -var Page = page.New("ex01", "page.html", page.Includes(parts.ExampleNav, counter)) -var counter = component.New("example-counter", "counter.html") diff --git a/cmd/run-today-examples/ex07-components/page.html b/cmd/run-today-examples/ex07-components/page.html deleted file mode 100644 index 7a81538..0000000 --- a/cmd/run-today-examples/ex07-components/page.html +++ /dev/null @@ -1,17 +0,0 @@ - - -
- Example 1 -
- -

Web Components

- - - Example: - - - - Parts - - - \ No newline at end of file diff --git a/cmd/run-today-examples/main.go b/cmd/run-today-examples/main.go index bf0c9c2..70d78b0 100644 --- a/cmd/run-today-examples/main.go +++ b/cmd/run-today-examples/main.go @@ -6,10 +6,6 @@ import ( "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/cmd/run-today-examples/ex03-slots" - "git.earlybird.gay/today-engine/cmd/run-today-examples/ex04-templates" - "git.earlybird.gay/today-engine/cmd/run-today-examples/ex06-data" - "git.earlybird.gay/today-engine/cmd/run-today-examples/ex07-components" "git.earlybird.gay/today-engine/page" ) @@ -20,10 +16,7 @@ func main() { mux.Handle("GET /{$}", index) mux.Handle("GET /ex01", ex01.Page) mux.Handle("GET /ex02", ex02.Page) - mux.Handle("GET /ex03", ex03.Page) - mux.Handle("GET /ex04", ex04.Page) - mux.Handle("GET /ex06", ex06.Page) - mux.Handle("GET /ex07", ex07.Page) + mux.Handle("GET /", http.FileServer(http.Dir("cmd/run-today-examples/public"))) http.ListenAndServe("0.0.0.0:3000", mux) } diff --git a/cmd/run-today-examples/parts/example-nav.html b/cmd/run-today-examples/parts/example-nav.html deleted file mode 100644 index e704aae..0000000 --- a/cmd/run-today-examples/parts/example-nav.html +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/cmd/run-today-examples/parts/parts.go b/cmd/run-today-examples/parts/parts.go index 2921182..8ec00d7 100644 --- a/cmd/run-today-examples/parts/parts.go +++ b/cmd/run-today-examples/parts/parts.go @@ -1,6 +1,29 @@ // Copyright (C) 2024 early (LGPL) package parts -import "git.earlybird.gay/today-engine/part" +import ( + "errors" + "io" + "strings" -var ExampleNav = part.New("example-nav", "example-nav.html") + "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 + }), +) diff --git a/cmd/run-today-examples/parts/source-preview.html b/cmd/run-today-examples/parts/source-preview.html new file mode 100644 index 0000000..ec9c1b0 --- /dev/null +++ b/cmd/run-today-examples/parts/source-preview.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/cmd/run-today-examples/public/style.css b/cmd/run-today-examples/public/style.css index 7d27a61..557cbab 100644 --- a/cmd/run-today-examples/public/style.css +++ b/cmd/run-today-examples/public/style.css @@ -1,5 +1,36 @@ -nav { +/* The Great Reset */ +* { + padding: 0; + margin: 0; +} + +/* Containers */ + +main, section, nav { display: flex; flex-direction: column; - gap: 1rem; -} \ No newline at end of file + 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; +} diff --git a/internal/compile/component.go b/internal/compile/component.go index e335559..ed06d35 100644 --- a/internal/compile/component.go +++ b/internal/compile/component.go @@ -2,7 +2,6 @@ package compile import ( "errors" - "fmt" "git.earlybird.gay/today-engine/htmltree" "golang.org/x/net/html" @@ -37,7 +36,6 @@ func insertComponentSource(subSource Source, document *html.Node) error { var template, script, body *html.Node for _, node := range innerHTML { - fmt.Printf("%+v\n", node) if node.Type == html.ElementNode && node.DataAtom == atom.Template { template = node } -- 2.39.5