feat: URL rules and the settings singleton
This commit is contained in:
99
controllers/settings.go
Normal file
99
controllers/settings.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"git.golem15.com/golem15/sm-seo-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// settingsAdminController edits the SEO settings singleton (D-104), linked
|
||||
// from the SEO settings tile. Its per-content-type tabs are added by the
|
||||
// plugin's own form extension on this controller.
|
||||
type settingsAdminController struct {
|
||||
app func() *backpack.App
|
||||
}
|
||||
|
||||
func (settingsAdminController) ID() string { return SettingsControllerID }
|
||||
func (settingsAdminController) ModelName() string { return `Golem15\SEO\Models\Settings` }
|
||||
func (settingsAdminController) ConfigDir() string { return "controllers/settings" }
|
||||
func (settingsAdminController) NewRecord() any { return &models.Settings{} }
|
||||
func (settingsAdminController) RequiredPermissions() []string {
|
||||
return []string{PermissionManage}
|
||||
}
|
||||
|
||||
// SingletonRecord returns settings row 1, creating it with the defaults
|
||||
// when the migration's row is gone (first or create, safe against a
|
||||
// concurrent first request through ON CONFLICT DO NOTHING).
|
||||
func (settingsAdminController) SingletonRecord(_ context.Context, db *gorm.DB) (any, error) {
|
||||
if db == nil {
|
||||
return nil, errors.New("golem15.seo: database is not configured")
|
||||
}
|
||||
var rows []models.Settings
|
||||
if err := db.Where("id = ?", 1).Limit(1).Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rows) > 0 {
|
||||
return &rows[0], nil
|
||||
}
|
||||
row := models.DefaultSettings()
|
||||
if err := db.Clauses(clause.OnConflict{DoNothing: true}).Create(&row).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Where("id = ?", 1).Limit(1).Find(&rows).Error; err != nil || len(rows) == 0 {
|
||||
return nil, errors.New("golem15.seo: settings row is missing")
|
||||
}
|
||||
return &rows[0], nil
|
||||
}
|
||||
|
||||
// FormBeforeUpdate refuses templates with unknown placeholders and
|
||||
// malformed or duplicate verification file names.
|
||||
func (c settingsAdminController) FormBeforeUpdate(ctx context.Context, model any) error {
|
||||
s, ok := model.(*models.Settings)
|
||||
if !ok || s == nil {
|
||||
return nil
|
||||
}
|
||||
return problemsError(ctx, translator(c.app), s.Problems())
|
||||
}
|
||||
|
||||
// FormBeforeCreate checks a created row like an update.
|
||||
func (c settingsAdminController) FormBeforeCreate(ctx context.Context, model any) error {
|
||||
return c.FormBeforeUpdate(ctx, model)
|
||||
}
|
||||
|
||||
// stagingView is the view model of the staging partial.
|
||||
type stagingView struct {
|
||||
Staging bool
|
||||
}
|
||||
|
||||
// PartialData serves the staging callout: shown outside production, where
|
||||
// every page is noindex whatever the settings say (D-22).
|
||||
func (c settingsAdminController) PartialData(_ context.Context, name string, _ any) (any, error) {
|
||||
if name != "staging" {
|
||||
return nil, nil
|
||||
}
|
||||
return stagingView{Staging: IsStaging(appOf(c.app))}, nil
|
||||
}
|
||||
|
||||
// IsStaging reports whether the application runs outside production. It
|
||||
// depends on the environment only (D-22): no setting can change it.
|
||||
func IsStaging(app *backpack.App) bool {
|
||||
if app == nil || app.Config == nil {
|
||||
return true
|
||||
}
|
||||
return app.Config.Environment() != "production"
|
||||
}
|
||||
|
||||
var (
|
||||
_ pact.AdminController = settingsAdminController{}
|
||||
_ pact.AdminPermissioned = settingsAdminController{}
|
||||
_ pact.AdminRecordSource = settingsAdminController{}
|
||||
_ pact.AdminSingleton = settingsAdminController{}
|
||||
_ pact.AdminPartialData = settingsAdminController{}
|
||||
_ pact.FormBeforeCreate = settingsAdminController{}
|
||||
_ pact.FormBeforeUpdate = settingsAdminController{}
|
||||
)
|
||||
Reference in New Issue
Block a user