feat(11.1-05): add the acme.blog walkthrough plugin with its model, migration and posts route
- docs/examples/blog: scaffolder output for acme.blog (make:plugin, make:model) in the root module, with a Post model, a fill allow-list and NewPost, the create migration and GET /api/blog/posts paginated through lagoon - short tests activate the plugin, check the route with surf, the fill allow-list and the migration order - docs/setup/porting-a-plugin.md: registration, model, migrations and routes sections with src= copies of the plugin - TestDocsRequiredPages requires setup/porting-a-plugin
This commit is contained in:
2
docs/examples/blog/models/doc.go
Normal file
2
docs/examples/blog/models/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package models holds GORM models for the acme.blog plugin.
|
||||
package models
|
||||
37
docs/examples/blog/models/post.go
Normal file
37
docs/examples/blog/models/post.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Code generated by summer make. DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
)
|
||||
|
||||
// Post is a blog post, the Go form of the WinterCMS Acme\Blog\Models\Post
|
||||
// model.
|
||||
type Post struct {
|
||||
ID uint `gorm:"column:id;primaryKey"`
|
||||
Title string `gorm:"column:title"`
|
||||
Slug string `gorm:"column:slug"`
|
||||
Body string `gorm:"column:body"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||
}
|
||||
|
||||
// TableName keeps the WinterCMS table name.
|
||||
func (Post) TableName() string { return "acme_blog_posts" }
|
||||
|
||||
// Fillable is the Go form of $fillable: the only columns lagoon.Fill may
|
||||
// set from a request.
|
||||
func (Post) Fillable() []string { return []string{"title", "slug", "body"} }
|
||||
|
||||
// NewPost is the Go form of Post::make($input): it copies only the fillable
|
||||
// keys of input onto a new post and drops the rest, such as id.
|
||||
func NewPost(input map[string]any) (*Post, error) {
|
||||
post := &Post{}
|
||||
if err := lagoon.Fill(post, post.Fillable(), input, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return post, nil
|
||||
}
|
||||
44
docs/examples/blog/models/post_test.go
Normal file
44
docs/examples/blog/models/post_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"git.golem15.com/golem15/summercms/docs/examples/blog/models"
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
)
|
||||
|
||||
var _ lagoon.HasFillable = models.Post{}
|
||||
|
||||
func TestPostTableAndFill(t *testing.T) {
|
||||
if got := (models.Post{}).TableName(); got != "acme_blog_posts" {
|
||||
t.Fatalf("TableName = %q, want acme_blog_posts", got)
|
||||
}
|
||||
if got, want := (models.Post{}).Fillable(), []string{"title", "slug", "body"}; !slices.Equal(got, want) {
|
||||
t.Fatalf("Fillable = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
input := map[string]any{"id": 99, "title": "Hello", "slug": "hello-world", "body": "First post.", "created_at": "2020-01-01"}
|
||||
post, err := models.NewPost(input)
|
||||
if err != nil {
|
||||
t.Fatalf("NewPost: %v", err)
|
||||
}
|
||||
if post.ID != 0 {
|
||||
t.Errorf("ID = %d, want 0: id is not fillable", post.ID)
|
||||
}
|
||||
if !post.CreatedAt.IsZero() {
|
||||
t.Errorf("CreatedAt = %v, want zero: created_at is not fillable", post.CreatedAt)
|
||||
}
|
||||
if post.Title != "Hello" || post.Slug != "hello-world" || post.Body != "First post." {
|
||||
t.Errorf("post = %+v, want the title, slug and body from input", post)
|
||||
}
|
||||
|
||||
// lagoon.Fill with the same allow-list, as NewPost does, drops id too.
|
||||
var direct models.Post
|
||||
if err := lagoon.Fill(&direct, direct.Fillable(), map[string]any{"id": 7, "title": "Direct"}, true); err != nil {
|
||||
t.Fatalf("Fill: %v", err)
|
||||
}
|
||||
if direct.ID != 0 || direct.Title != "Direct" {
|
||||
t.Errorf("Fill result = %+v, want ID 0 and title Direct", direct)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user