package blog import ( "context" "embed" "io/fs" "git.golem15.com/golem15/summercms/docs/examples/blog/console" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/bonfire" "git.golem15.com/golem15/summercms/modules/lagoon" "git.golem15.com/golem15/summercms/modules/pact" "git.golem15.com/golem15/summercms/modules/party" "github.com/go-gormigrate/gormigrate/v2" "gorm.io/gorm" ) var ( _ pact.HasConfig = (*Plugin)(nil) _ pact.HasLang = (*Plugin)(nil) _ pact.HasMailTemplates = (*Plugin)(nil) _ pact.HasModels = (*Plugin)(nil) _ pact.HasMigrations = (*Plugin)(nil) _ pact.HasCommands = (*Plugin)(nil) _ pact.HasJobs = (*Plugin)(nil) _ pact.HasAdminControllers = (*Plugin)(nil) _ pact.AdminAssets = (*Plugin)(nil) _ pact.HasPermissions = (*Plugin)(nil) _ pact.HasNavigation = (*Plugin)(nil) ) //go:embed config var configFS embed.FS //go:embed lang var langFS embed.FS //go:embed views/mail var mailFS embed.FS //go:embed controllers/*/*.yaml models/*/*.yaml var adminFS embed.FS // Plugin is the acme.blog plugin, the Go form of Plugin.php. type Plugin struct { app *backpack.App } func (p *Plugin) ID() string { return "acme.blog" } func (p *Plugin) Requires() []string { return nil } func (p *Plugin) Register(*backpack.App) error { return nil } // Boot keeps the application, so route handlers and commands can reach its // services, such as the database, when they run. func (p *Plugin) Boot(app *backpack.App) error { p.app = app return nil } func (p *Plugin) ConfigFS() fs.FS { return configFS } func (p *Plugin) LangFS() fs.FS { return langFS } func (p *Plugin) MailTemplatesFS() fs.FS { return mailFS } func (p *Plugin) MailTemplates() []string { return nil } func (p *Plugin) MailLayouts() map[string]string { return nil } func (p *Plugin) Models() []any { return generatedModels() } func (p *Plugin) Migrations() []*gormigrate.Migration { return generatedMigrations() } func (p *Plugin) Jobs() []pact.Job { return generatedJobs() } func (p *Plugin) AdminControllers() []pact.AdminController { return generatedAdminControllers() } // Commands returns the generated commands plus blog:publish, which needs the // database and so is built here with the plugin's withDB. func (p *Plugin) Commands() []bonfire.Command { return append(generatedCommands(), console.PublishCommand(p.withDB)) } // AdminFS is the admin YAML the controllers read: controllers/posts and // models/posts. func (p *Plugin) AdminFS() fs.FS { return adminFS } // Permissions replaces registerPermissions(). func (p *Plugin) Permissions() []pact.Permission { return []pact.Permission{{ Code: "acme.blog.access_posts", Tab: "acme.blog::lang.plugin.name", Label: "acme.blog::lang.permissions.access_posts", }} } // Navigation replaces registerNavigation(). func (p *Plugin) Navigation() []pact.NavigationItem { return []pact.NavigationItem{{ Code: "blog", Label: "acme.blog::lang.plugin.name", Icon: "icon-pencil", Permissions: []string{"acme.blog.access_posts"}, Controller: "acme.blog.posts", }} } // withDB runs fn with the application's database: the one the serve command // published, or, when a console command runs, one opened from the config for // the duration of fn. func (p *Plugin) withDB(ctx context.Context, fn func(*gorm.DB) error) error { if gdb, ok := p.app.Lookup[*gorm.DB](); ok && gdb != nil { return fn(gdb) } sqlDB, gdb, err := lagoon.OpenFromApp(ctx, p.app) if err != nil { return err } defer sqlDB.Close() return fn(gdb) } func init() { party.Register(&Plugin{}) }