feat: auto-link phrases in the resolve answer (tracer)
- golem15_seo_autolinks (migration 202610280007) and the settings column autolink_max (Links tab, 0 to 20, default 3) - classes/autolinks.go: checked save and delete with history, ForPage - ok resolve answers carry autolinks for the page's locale without disabled phrases and links to the page itself, and autolink_max
This commit is contained in:
113
models/autolink.go
Normal file
113
models/autolink.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// The origins of an auto-link phrase: entered in the admin, added from a
|
||||
// record's focus keyphrase, or created through MCP.
|
||||
const (
|
||||
AutolinkOriginManual = "manual"
|
||||
AutolinkOriginKeyphrase = "keyphrase"
|
||||
AutolinkOriginMCP = "mcp"
|
||||
)
|
||||
|
||||
// AutolinkOrigins lists the origins in filter order.
|
||||
var AutolinkOrigins = []string{AutolinkOriginManual, AutolinkOriginKeyphrase, AutolinkOriginMCP}
|
||||
|
||||
// The limits of an auto-link phrase and of the settings' autolink_max
|
||||
// (UI-SPEC C20, C22).
|
||||
const (
|
||||
MinAutolinkPhrase = 3
|
||||
MaxAutolinkPhrase = 200
|
||||
MaxAutolinkURL = 2048
|
||||
DefaultAutolinkMax = 3
|
||||
MinAutolinkMax = 0
|
||||
MaxAutolinkMax = 20
|
||||
)
|
||||
|
||||
// Autolink is one phrase of the auto-link table on golem15_seo_autolinks
|
||||
// (D-82, P33-45): texts link the phrase's first occurrence to URL (a path
|
||||
// or an absolute http(s) address). Locale is the content locale it applies
|
||||
// in, "" for every locale; a disabled phrase is kept but never linked.
|
||||
type Autolink struct {
|
||||
ID uint `gorm:"column:id;primaryKey"`
|
||||
Phrase string `gorm:"column:phrase"`
|
||||
URL string `gorm:"column:url"`
|
||||
Locale string `gorm:"column:locale"`
|
||||
Enabled bool `gorm:"column:enabled"`
|
||||
Origin string `gorm:"column:origin"`
|
||||
Note string `gorm:"column:note"`
|
||||
CreatedAt *time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt *time.Time `gorm:"column:updated_at"`
|
||||
}
|
||||
|
||||
func (Autolink) TableName() string { return "golem15_seo_autolinks" }
|
||||
|
||||
// MorphName names an auto-link in history and the admin.
|
||||
func (Autolink) MorphName() string { return `Golem15\SEO\Models\Autolink` }
|
||||
|
||||
// Fillable lists the form's columns.
|
||||
func (*Autolink) Fillable() []string {
|
||||
return []string{"phrase", "url", "locale", "enabled", "note"}
|
||||
}
|
||||
|
||||
// Rules is empty: the Auto-links controller and the service check a
|
||||
// phrase before a save (classes.AutolinkProblems).
|
||||
func (*Autolink) Rules() map[string]string { return map[string]string{} }
|
||||
|
||||
// NewAutolink is a phrase with the form's defaults: every locale, active,
|
||||
// entered by hand.
|
||||
func NewAutolink() Autolink {
|
||||
return Autolink{Enabled: true, Origin: AutolinkOriginManual}
|
||||
}
|
||||
|
||||
// IDText is the auto-link's id as text.
|
||||
func (a Autolink) IDText() string { return strconv.FormatUint(uint64(a.ID), 10) }
|
||||
|
||||
// The filter scopes of the Auto-links list (UI-SPEC C22).
|
||||
const (
|
||||
FilterAutolinkLocale = "FilterAutolinkLocale"
|
||||
FilterAutolinkOrigin = "FilterAutolinkOrigin"
|
||||
// AutolinkLocaleAll is the locale filter's value of the phrases that
|
||||
// apply in every locale.
|
||||
AutolinkLocaleAll = "all"
|
||||
)
|
||||
|
||||
// FilterScopes lists the Auto-links list's filter scopes.
|
||||
func (Autolink) FilterScopes() []string {
|
||||
return []string{FilterAutolinkLocale, FilterAutolinkOrigin}
|
||||
}
|
||||
|
||||
// FilterScope narrows the Auto-links list by locale ("all" for the
|
||||
// phrases of every locale) or origin; an unknown origin matches nothing.
|
||||
// The active filter is a switch on the enabled column.
|
||||
func (Autolink) FilterScope(name string, db *gorm.DB, value any) *gorm.DB {
|
||||
if db == nil {
|
||||
return db
|
||||
}
|
||||
switch name {
|
||||
case FilterAutolinkLocale:
|
||||
s, _ := value.(string)
|
||||
if s == AutolinkLocaleAll {
|
||||
s = ""
|
||||
}
|
||||
return db.Where("golem15_seo_autolinks.locale = ?", s)
|
||||
case FilterAutolinkOrigin:
|
||||
s, _ := value.(string)
|
||||
for _, o := range AutolinkOrigins {
|
||||
if o == s {
|
||||
return db.Where("golem15_seo_autolinks.origin = ?", s)
|
||||
}
|
||||
}
|
||||
return db.Where("1 = 0")
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(Autolink{})
|
||||
}
|
||||
@@ -25,6 +25,8 @@ const (
|
||||
SubjectNotFound = "notfound"
|
||||
// SubjectPage is a page of the page registry (D-33).
|
||||
SubjectPage = "page"
|
||||
// SubjectAutolink is a phrase of the auto-link table (D-82).
|
||||
SubjectAutolink = "autolink"
|
||||
)
|
||||
|
||||
// Revision is one recorded SEO change on golem15_seo_revisions (D-13): who
|
||||
|
||||
@@ -179,6 +179,10 @@ type Settings struct {
|
||||
LinksNewTab bool `gorm:"column:links_new_tab"`
|
||||
NofollowDomains string `gorm:"column:nofollow_domains"`
|
||||
SponsoredDomains string `gorm:"column:sponsored_domains"`
|
||||
// AutolinkMax is the most phrases of SEO › Auto-links linked in one
|
||||
// text (Links tab, 0 to 20, 3 by default); 0 turns auto-linking off
|
||||
// (D-82).
|
||||
AutolinkMax int `gorm:"column:autolink_max"`
|
||||
// BreadcrumbHome is the home crumb's name (translatable; empty: the
|
||||
// per-locale default copy).
|
||||
BreadcrumbHome string `gorm:"column:breadcrumb_home"`
|
||||
@@ -247,7 +251,7 @@ func (Settings) Fillable() []string {
|
||||
"local_region", "local_country", "local_latitude", "local_longitude",
|
||||
"local_hours", "page_form", "page_segment", "page_title_suffix",
|
||||
"page_description_suffix", "crawl_schedule", "crawl_max_pages",
|
||||
"crawl_delay", "crawl_keep", "generic_anchors",
|
||||
"crawl_delay", "crawl_keep", "generic_anchors", "autolink_max",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +268,7 @@ func DefaultSettings() Settings {
|
||||
URLHost: HostKeep,
|
||||
URLSlash: SlashKeep,
|
||||
LinksNewTab: true,
|
||||
AutolinkMax: DefaultAutolinkMax,
|
||||
PageForm: PageFormQuery,
|
||||
PublisherType: PublisherOrganization,
|
||||
LocalType: DefaultLocalType,
|
||||
@@ -299,9 +304,9 @@ const (
|
||||
// pl lists of UI-SPEC C27, one per line.
|
||||
const DefaultGenericAnchors = "click here\nhere\nmore\nread more\nlearn more\nthis link\nlink\nkliknij tutaj\ntutaj\ntu\nwięcej\nczytaj więcej\nczytaj dalej\nten link"
|
||||
|
||||
// AuditProblems refuses Site audit values outside their ranges
|
||||
// (lagoon::validation.between.numeric, UI-SPEC C20) and an unknown
|
||||
// schedule. The settings screen and the API check it on save; Problems
|
||||
// AuditProblems refuses Site audit values and the Links tab's
|
||||
// autolink_max outside their ranges (lagoon::validation.between.numeric,
|
||||
// UI-SPEC C20) and an unknown schedule. The settings screen and the API check it on save; Problems
|
||||
// leaves it out, so a partial Settings value checks its templates only.
|
||||
func (s Settings) AuditProblems() map[string][]Problem {
|
||||
out := map[string][]Problem{}
|
||||
@@ -315,6 +320,7 @@ func (s Settings) AuditProblems() map[string][]Problem {
|
||||
between("crawl_max_pages", s.CrawlMaxPages, MinCrawlMaxPages, MaxCrawlMaxPages)
|
||||
between("crawl_delay", s.CrawlDelay, MinCrawlDelay, MaxCrawlDelay)
|
||||
between("crawl_keep", s.CrawlKeep, MinCrawlKeep, MaxCrawlKeep)
|
||||
between("autolink_max", s.AutolinkMax, MinAutolinkMax, MaxAutolinkMax)
|
||||
switch s.CrawlSchedule {
|
||||
case CrawlOff, CrawlDaily, CrawlWeekly:
|
||||
default:
|
||||
|
||||
@@ -178,6 +178,14 @@ fields:
|
||||
span: right
|
||||
tab: golem15.seo::lang.settings.tab_pagination
|
||||
|
||||
autolink_max:
|
||||
label: golem15.seo::lang.settings.autolink_max
|
||||
comment: golem15.seo::lang.settings.autolink_max_comment
|
||||
type: number
|
||||
span: left
|
||||
default: 3
|
||||
tab: golem15.seo::lang.settings.tab_links
|
||||
|
||||
links_new_tab:
|
||||
label: golem15.seo::lang.settings.links_new_tab
|
||||
comment: golem15.seo::lang.settings.links_new_tab_comment
|
||||
|
||||
Reference in New Issue
Block a user