contract.ListingSettings.TypesOff lists the signpost keys of the content types switched off in the sitemap settings, so another plugin (the SEO tab's sitemap status) can tell an address left out with ReasonType without reading the sitemap's tables. Additive.
154 lines
5.6 KiB
Go
154 lines
5.6 KiB
Go
// Package contract is the published seam of the golem15.sitemap plugin:
|
|
// the Filter another plugin implements to keep addresses out of the
|
|
// sitemaps or move them to another file group, and the Listing other
|
|
// plugins read to show the sitemap's addresses (an HTML sitemap, IndexNow).
|
|
//
|
|
// It is a package of its own so a plugin can import it without importing
|
|
// the sitemap plugin's root package, whose init registers the plugin. The
|
|
// sitemap plugin depends on no implementation: it looks a Filter up with
|
|
//
|
|
// f, ok := app.Lookup[contract.Filter]()
|
|
//
|
|
// and includes every published address when none is published. A plugin
|
|
// publishes one in its Register:
|
|
//
|
|
// app.Publish[contract.Filter](myFilter{})
|
|
package contract
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// The reasons a Decision may give for leaving an address out. The sitemap
|
|
// counts excluded addresses by reason; another reason is counted under its
|
|
// own name.
|
|
const (
|
|
// ReasonNoindex is an address whose page is set to noindex.
|
|
ReasonNoindex = "noindex"
|
|
// ReasonCanonical is an address whose canonical URL points elsewhere.
|
|
ReasonCanonical = "canonical"
|
|
// ReasonRedirect is an address that redirects.
|
|
ReasonRedirect = "redirect"
|
|
// ReasonType is an address of a content type switched off in the
|
|
// sitemap settings; the sitemap sets it itself, a Filter need not.
|
|
ReasonType = "type"
|
|
)
|
|
|
|
// Candidate is one address the sitemap would list: TypeKey is the content
|
|
// type key (a signpost menu item type, or "extra" for an additional address
|
|
// of the settings), RecordID the record's ID within it (for an additional
|
|
// address the hex SHA-256 of its path), Locale the locale ("" when the
|
|
// address has none) and URL its public path or absolute URL.
|
|
type Candidate struct {
|
|
TypeKey string
|
|
RecordID string
|
|
Locale string
|
|
URL string
|
|
}
|
|
|
|
// Decision is a Filter's answer for one Candidate. Exclude leaves the
|
|
// address out of the sitemap files, counted under Reason. Group, when not
|
|
// empty, puts the address in another file group: the files are then named
|
|
// sitemap-<group>-<n>.xml, so a Group must use lowercase letters, digits and
|
|
// hyphens (another value is ignored). LastMod, when set, is the first
|
|
// lastmod of an address the sitemap has not listed before; it never moves
|
|
// the lastmod of a listed address.
|
|
type Decision struct {
|
|
Exclude bool
|
|
Reason string
|
|
Group string
|
|
LastMod *time.Time
|
|
}
|
|
|
|
// Group names a file group a Filter's decisions use: Key is the group as
|
|
// in Decision.Group, Titles its heading per locale for an HTML sitemap.
|
|
type Group struct {
|
|
Key string
|
|
Titles map[string]string
|
|
}
|
|
|
|
// Filter decides which addresses the sitemap lists. Decide receives one
|
|
// batch (a page of records of one content type, or the additional
|
|
// addresses) and answers one Decision per Candidate in the same order; an
|
|
// answer of another length or an error fails the rebuild, which keeps the
|
|
// files it served before. Groups lists the groups the Filter's decisions
|
|
// may name, with their titles.
|
|
type Filter interface {
|
|
Decide(ctx context.Context, batch []Candidate) ([]Decision, error)
|
|
Groups(ctx context.Context) ([]Group, error)
|
|
}
|
|
|
|
// Listing is what the sitemap publishes for other plugins: its settings and
|
|
// the listed addresses of each group. The sitemap plugin publishes it with
|
|
// app.Publish[contract.Listing] in its Register.
|
|
type Listing interface {
|
|
Settings(ctx context.Context) (ListingSettings, error)
|
|
Entries(ctx context.Context, q EntriesQuery) (EntriesPage, error)
|
|
}
|
|
|
|
// ListingSettings are the sitemap's settings as other plugins need them.
|
|
// SiteURL is the absolute site address every address starts with ("" when
|
|
// none is configured), IndexURL the absolute address of the sitemap index,
|
|
// DefaultLocale the site's default locale ("" when not set) and Groups the
|
|
// file groups with listed addresses. HTMLEnabled, HTMLPaths (locale to
|
|
// path) and HTMLPageSize are the HTML sitemap's settings (the sitemap
|
|
// serves its data at /_sitemap/api/v1/html); KeyFile is the IndexNow key
|
|
// file name (<key>.txt, served at /_sitemap/indexnow/<key>.txt for the
|
|
// site root), "" while IndexNow is off. TypesOff lists the content types
|
|
// (signpost keys) switched off in the sitemap settings, whose addresses
|
|
// are left out with ReasonType.
|
|
type ListingSettings struct {
|
|
SiteURL string
|
|
IndexURL string
|
|
DefaultLocale string
|
|
Groups []GroupInfo
|
|
HTMLEnabled bool
|
|
HTMLPaths map[string]string
|
|
HTMLPageSize int
|
|
KeyFile string
|
|
TypesOff []string
|
|
}
|
|
|
|
// GroupInfo is one file group: Key is the group (as Entries takes it), Slug
|
|
// the name part of its files (sitemap-<slug>-<n>.xml; today the same as
|
|
// Key), Titles its heading per locale and Count its listed addresses.
|
|
type GroupInfo struct {
|
|
Key string
|
|
Slug string
|
|
Titles map[string]string
|
|
Count int
|
|
}
|
|
|
|
// EntriesQuery asks for one page of a group's listed addresses. Locale,
|
|
// when set, keeps the addresses of that locale and those without one.
|
|
// After is the Next of the previous page ("" for the first) and Limit the
|
|
// page size (at most 1000; 0 means 100).
|
|
type EntriesQuery struct {
|
|
Group string
|
|
Locale string
|
|
After string
|
|
Limit int
|
|
}
|
|
|
|
// Entry is one listed address. URL is absolute (on ListingSettings.SiteURL)
|
|
// and LastMod its last real change, nil when unknown.
|
|
type Entry struct {
|
|
Group string
|
|
TypeKey string
|
|
RecordID string
|
|
Locale string
|
|
URL string
|
|
Title string
|
|
LastMod *time.Time
|
|
}
|
|
|
|
// EntriesPage is one page of Entries in a stable order: Next is the After
|
|
// of the following page ("" on the last page) and Total the number of
|
|
// addresses the query matches across all pages.
|
|
type EntriesPage struct {
|
|
Entries []Entry
|
|
Next string
|
|
Total int
|
|
}
|