feat: SEO field types and the complete SEO tab

This commit is contained in:
2026-10-27 11:04:03 +01:00
parent deebd9aa65
commit 93ddbcc9ef
26 changed files with 1827 additions and 50 deletions

View File

@@ -357,6 +357,55 @@ func (r *Resolver) Resolve(ctx context.Context, rawURL string) (Result, error) {
if err != nil {
return Result{}, err
}
key, match, rec, err := r.lookup(ctx, path)
if err != nil {
return Result{}, err
}
return r.resolveAt(ctx, db, settings, path, query, rawQueryOf(rawURL), key, match, rec, false)
}
// ResolveRecord answers the effective SEO of a record in one locale at its
// own address, published or not (the SEO tab's effective-values partial).
// ok is false when the record has no address in that locale.
func (r *Resolver) ResolveRecord(ctx context.Context, key, id, locale string) (Result, bool, error) {
svc := r.Service
reg := svc.Registry()
if reg == nil {
return Result{}, false, nil
}
rec, err := reg.Describe(ctx, key, id, svc.UnprefixedLocale())
if err != nil || rec == nil {
return Result{}, false, err
}
var path string
for _, l := range rec.Locales {
if l.Locale == locale {
path = l.URL
}
}
if strings.TrimSpace(path) == "" {
return Result{}, false, nil
}
target, query, err := parseTarget(path)
if err != nil {
return Result{}, false, nil
}
db, err := svc.DB(ctx)
if err != nil {
return Result{}, false, err
}
settings, err := LoadSettings(db)
if err != nil {
return Result{}, false, err
}
res, err := r.resolveAt(ctx, db, settings, target, query, rawQueryOf(path), key, &pact.ContentMatchResult{ID: id, Locale: locale, Exact: true}, rec, true)
return res, err == nil, err
}
// resolveAt computes the answer for a path whose owner lookup is done:
// key, match and rec name the record behind it (key "" when none).
func (r *Resolver) resolveAt(ctx context.Context, db *gorm.DB, settings models.Settings, path string, query url.Values, rawQuery, key string, match *pact.ContentMatchResult, rec *pact.ContentRecord, force bool) (Result, error) {
svc := r.Service
site := svc.SiteURL()
kept, filtered := splitQuery(settings.Params(), path, query)
self := site + path
@@ -365,16 +414,12 @@ func (r *Resolver) Resolve(ctx context.Context, rawURL string) (Result, error) {
}
res := Result{Action: ActionNotFound, Status: 404, URL: self, Staging: svc.Staging(), Sources: map[string]string{}}
rules, err := matchingRules(db, path, rawQueryOf(rawURL))
if err != nil {
return Result{}, err
}
key, match, rec, err := r.lookup(ctx, path)
rules, err := matchingRules(db, path, rawQuery)
if err != nil {
return Result{}, err
}
home := path == "/"
if key == "" && len(rules) == 0 && !home {
if key == "" && len(rules) == 0 && !home && !force {
return res, nil
}