feat(11.1-04): add the Database section and the core Services pages

- docs/database: models, migrations, queries and pagination, relations,
  casts and validation, attachments and transactions (lagoon.Transaction,
  lagoon.AfterCommit, nested savepoints, lagoon.OnDatabase)
- docs/services: configuration, events, routing with auth groups, rate
  limiting, authentication, the OAuth server, mail and localization
- runnable Examples for lagoon, attach, compass, surf, wire, bouncer,
  wristband, postcard, phrasebook and festival; lagoon TestDocs* regions
  run on the package's Postgres harness through DocsDB
- 15 new required pages
This commit is contained in:
Jakub Zych
2026-09-30 22:59:25 +02:00
parent 9d37d56486
commit efb35a2d35
28 changed files with 3138 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
package postcard_test
import (
"context"
"fmt"
"strings"
"testing/fstest"
"git.golem15.com/golem15/summercms/modules/postcard"
)
// mailFS stands in for the plugin's embedded views/mail directory.
var mailFS = fstest.MapFS{
"views/mail/welcome.htm": {Data: []byte(`subject = "Welcome, {{ .name }}"
layout = "blog"
description = "Sent after registration"
==
Hi **{{ .name }}**, thanks for joining the blog.
`)},
"views/mail/layouts/blog.htm": {Data: []byte(`name = "Blog"
==
{{ .Content }}
-- The Acme blog
==
<div class="blog-mail">{{ .Content }}</div>
<style>{{ .brandCss }}{{ .css }}</style>
`)},
}
func ExampleMailer_Send() {
// At boot, postcard.BootPlugin registers what pact.HasMailTemplates
// declares; a test registers the same thing directly.
cat := postcard.NewCatalog()
err := cat.Register("acme.blog", mailFS,
[]string{"acme.blog::mail.welcome"},
map[string]string{"blog": "acme.blog::mail.layouts.blog"})
if err != nil {
fmt.Println(err)
return
}
driver := postcard.NewMemoryDriver() // mail.driver: memory
mailer := postcard.NewMailer(cat, driver, postcard.Options{From: "blog@example.com"})
err = mailer.Send(context.Background(), postcard.Message{
Template: "acme.blog::mail.welcome",
To: []string{"ada@example.com"},
Vars: map[string]any{"name": "Ada"},
})
if err != nil {
fmt.Println(err)
return
}
sent := driver.Messages()[0]
fmt.Println(sent.From, sent.To, sent.Subject)
fmt.Println(sent.Text)
fmt.Println(strings.Contains(sent.HTML, `<div class="blog-mail"><p>Hi <strong>Ada</strong>`))
// Header injection is refused before any driver sees the message.
err = mailer.Send(context.Background(), postcard.Message{
Template: "acme.blog::mail.welcome",
To: []string{"ada@example.com\r\nBcc: all@example.com"},
Vars: map[string]any{"name": "Ada"},
})
fmt.Println(err != nil, len(driver.Messages()))
// Output:
// blog@example.com [ada@example.com] Welcome, Ada
// Hi **Ada**, thanks for joining the blog.
//
// -- The Acme blog
// true
// true 1
}