feat: SEO field types and the complete SEO tab
This commit is contained in:
@@ -93,6 +93,47 @@ func (c rulesAdminController) ListExtendRecords(ctx context.Context, _ *gorm.DB,
|
||||
return nil
|
||||
}
|
||||
|
||||
// service returns the SEO service of the booted app, nil before boot.
|
||||
func (c rulesAdminController) service() *classes.Service {
|
||||
svc, err := classes.NewService(appOf(c.app))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return svc
|
||||
}
|
||||
|
||||
// AdminJS loads the SEO element bundle on the rules screens (the result
|
||||
// preview widget).
|
||||
func (rulesAdminController) AdminJS() []string { return []string{"assets/dist/seo.js"} }
|
||||
|
||||
// AdminCSS loads the SEO element styles on the rules screens.
|
||||
func (rulesAdminController) AdminCSS() []string { return []string{"assets/dist/seo.css"} }
|
||||
|
||||
// AdminActions registers the result preview's widget action (E3).
|
||||
func (c rulesAdminController) AdminActions() []pact.AdminAction {
|
||||
return []pact.AdminAction{classes.RuleSnippetAction(c.service, "golem15.seo::lang.snippet.action", PermissionManage)}
|
||||
}
|
||||
|
||||
// PartialData serves P1 seo_status (canonical warnings) and P2
|
||||
// seo_effective of a rule.
|
||||
func (c rulesAdminController) PartialData(ctx context.Context, name string, record any) (any, error) {
|
||||
svc := c.service()
|
||||
r, ok := record.(*models.Rule)
|
||||
if svc == nil || !ok || r == nil {
|
||||
if name == "seo_effective" {
|
||||
return classes.EffectiveView{}, nil
|
||||
}
|
||||
return classes.StatusView{}, nil
|
||||
}
|
||||
switch name {
|
||||
case "seo_status":
|
||||
return svc.RuleStatus(ctx, *r), nil
|
||||
case "seo_effective":
|
||||
return svc.RuleEffective(ctx, *r)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FilterOptions serves the match filter's two choices.
|
||||
func (rulesAdminController) FilterOptions(scope string) []pact.Option {
|
||||
if scope != models.FilterMatch {
|
||||
@@ -113,4 +154,7 @@ var (
|
||||
_ pact.ListExtendRecords = rulesAdminController{}
|
||||
_ pact.FilterOptions = rulesAdminController{}
|
||||
_ pact.FormAfterDelete = rulesAdminController{}
|
||||
_ pact.HasAdminActions = rulesAdminController{}
|
||||
_ pact.AdminPartialData = rulesAdminController{}
|
||||
_ pact.AdminClientAssets = rulesAdminController{}
|
||||
)
|
||||
|
||||
24
controllers/rules/_seo_effective.htm
Normal file
24
controllers/rules/_seo_effective.htm
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if .Data.Staging -}}
|
||||
<div class="summer-callout summer-callout--warning" role="status">
|
||||
<p class="summer-callout__text">{{ .Data.StagingText }}</p>
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- range .Data.Locales -}}
|
||||
<section>
|
||||
<h4>{{ .Heading }}</h4>
|
||||
{{- if .NoURL -}}
|
||||
<p>{{ .NoURLText }}</p>
|
||||
{{- else -}}
|
||||
<div class="summer-table-wrap">
|
||||
<table class="summer-table">
|
||||
<thead><tr><th>{{ $.Data.PropertyLabel }}</th><th>{{ $.Data.ValueLabel }}</th><th>{{ $.Data.SourceLabel }}</th></tr></thead>
|
||||
<tbody>
|
||||
{{- range .Rows -}}
|
||||
<tr><td>{{ .Property }}</td><td>{{ if .Mono }}<code>{{ .Value }}</code>{{ else }}{{ .Value }}{{ end }}</td><td>{{ .Source }}</td></tr>
|
||||
{{- end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{- end -}}
|
||||
</section>
|
||||
{{- end -}}
|
||||
6
controllers/rules/_seo_status.htm
Normal file
6
controllers/rules/_seo_status.htm
Normal file
@@ -0,0 +1,6 @@
|
||||
{{- range .Data.Callouts -}}
|
||||
<div class="summer-callout summer-callout--warning" role="status">
|
||||
<p class="summer-callout__title">{{ .Title }}</p>
|
||||
{{- if .Text }}<p class="summer-callout__text">{{ .Text }}</p>{{ end }}
|
||||
</div>
|
||||
{{- end -}}
|
||||
@@ -101,13 +101,21 @@ 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
|
||||
// PartialData serves the staging callout, shown outside production where
|
||||
// every page is noindex whatever the settings say (D-22), and the P3
|
||||
// placeholder table.
|
||||
func (c settingsAdminController) PartialData(ctx context.Context, name string, _ any) (any, error) {
|
||||
switch name {
|
||||
case "staging":
|
||||
return stagingView{Staging: IsStaging(appOf(c.app))}, nil
|
||||
case "placeholders":
|
||||
svc, err := classes.NewService(appOf(c.app))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Placeholders(ctx), nil
|
||||
}
|
||||
return stagingView{Staging: IsStaging(appOf(c.app))}, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// IsStaging reports whether the application runs outside production. It
|
||||
|
||||
11
controllers/settings/_placeholders.htm
Normal file
11
controllers/settings/_placeholders.htm
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="summer-table-wrap">
|
||||
<table class="summer-table">
|
||||
<caption>{{ .Data.Caption }}</caption>
|
||||
<thead><tr><th>{{ .Data.CodeLabel }}</th><th>{{ .Data.MeaningLabel }}</th></tr></thead>
|
||||
<tbody>
|
||||
{{- range .Data.Rows -}}
|
||||
<tr><td><code>{{ .Code }}</code></td><td>{{ .Meaning }}</td></tr>
|
||||
{{- end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
Reference in New Issue
Block a user