feat: pagination forms and suffixes in resolve and site
- Pagination tab: query or path form, per-locale segment, title and
description suffixes with %page% and %pages%
- ?page=1, /<segment>/1 and the other form answer 301 to the configured
address in one hop with normalisation and strict URLs; a page value
that is not a number answers not_found with pagination.invalid
- page 2 and later: self canonical with the page, index,follow, the
suffixes (%pages% left for the layer), paged hreflang alternates
- GET /site answers pagination {form, param, segments} and home_crumb
This commit is contained in:
@@ -15,7 +15,8 @@ import (
|
||||
// sitemap settings; Routes each content type's layered URL pattern for
|
||||
// the layer's drift check; RootFiles the file names the layer serves at
|
||||
// the site root (verification files, the IndexNow key file); LLMS whether
|
||||
// /llms.txt is served.
|
||||
// /llms.txt is served; Pagination the site's page address form and
|
||||
// HomeCrumb the home crumb (33-06, D-40, D-86).
|
||||
type SiteAnswer struct {
|
||||
SiteURL string `json:"site_url"`
|
||||
DefaultLocale string `json:"default_locale"`
|
||||
@@ -26,6 +27,25 @@ type SiteAnswer struct {
|
||||
Routes []SiteRoute `json:"routes"`
|
||||
RootFiles []string `json:"root_files"`
|
||||
LLMS bool `json:"llms"`
|
||||
Pagination SitePagination `json:"pagination"`
|
||||
HomeCrumb SiteHomeCrumb `json:"home_crumb"`
|
||||
}
|
||||
|
||||
// SitePagination is the site answer's pagination block: the form (query
|
||||
// or path), the query parameter and the path segment per locale, so the
|
||||
// layer builds numbered links and checks drift.
|
||||
type SitePagination struct {
|
||||
Form string `json:"form"`
|
||||
Param string `json:"param"`
|
||||
Segments map[string]string `json:"segments"`
|
||||
}
|
||||
|
||||
// SiteHomeCrumb is the home crumb: its name in the default locale, the
|
||||
// home URL and the name per locale.
|
||||
type SiteHomeCrumb struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Names map[string]string `json:"names"`
|
||||
}
|
||||
|
||||
// SiteLinks is the site answer's links block.
|
||||
@@ -86,6 +106,13 @@ func (s *Service) Site(ctx context.Context) (SiteAnswer, error) {
|
||||
out.Locales = s.Locales(ctx, db)
|
||||
out.Links.NewTab = settings.LinksNewTab
|
||||
out.LLMS = robots.LlmsEnabled
|
||||
pages := s.PageConfigOf(ctx, db, settings)
|
||||
out.Pagination = SitePagination{Form: pages.Form, Param: PageParam, Segments: pages.Segments}
|
||||
out.HomeCrumb = SiteHomeCrumb{URL: out.SiteURL + "/", Names: map[string]string{}}
|
||||
for _, locale := range out.Locales {
|
||||
out.HomeCrumb.Names[locale] = s.HomeCrumbName(ctx, db, settings, locale)
|
||||
}
|
||||
out.HomeCrumb.Name = out.HomeCrumb.Names[out.DefaultLocale]
|
||||
if reg := s.Registry(); reg != nil {
|
||||
for _, typ := range reg.ContentTypes() {
|
||||
if typ.Key == PageTypeKey {
|
||||
|
||||
Reference in New Issue
Block a user