Files
sm-journal-plugin/classes/journal_settings.go
Jakub Zych 305f94afd9 feat: H1 to H2 setting with the admin save conversion (tracer)
- content_h1_to_h2 and generic_anchors on the settings row (migration
  202610280001), Headings and links tab, config key
  golem15.journal.content_h1_to_h2 used when no settings row exists
- classes.ConvertH1 on the x/net/html tokenizer; the Blog Editor types
  convert while the setting is on and answer editor.h1_converted
- GET /posts/{slug} reports content_h1_to_h2 (additive key)
2026-11-04 09:44:58 +01:00

85 lines
2.8 KiB
Go

package classes
import (
"context"
"strings"
"git.golem15.com/golem15/sm-journal-plugin/models"
"git.golem15.com/golem15/summercms/modules/compass"
"gorm.io/gorm"
)
// H1ToH2Key is the config key of the H1 setting, used only when the Journal
// settings row does not exist (EffectiveH1ToH2). Its shipped default is true.
const H1ToH2Key = "golem15.journal.content_h1_to_h2"
// DefaultGenericAnchors are the link texts the editor warns about when the
// settings row has no list of its own: the English and the Polish seed list,
// each entry once.
var DefaultGenericAnchors = []string{
"click here", "here", "more", "read more", "learn more", "this link", "link",
"kliknij tutaj", "tutaj", "tu", "więcej", "czytaj więcej", "czytaj dalej", "ten link",
}
// headingSettings is the part of the settings row the heading rules read.
type headingSettings struct {
ContentH1ToH2 bool
GenericAnchors *string
}
// readHeadingSettings reads the settings row (ID 1); found is false when
// there is no row or no database.
func readHeadingSettings(ctx context.Context, db *gorm.DB) (headingSettings, bool) {
if db == nil {
return headingSettings{}, false
}
if ctx != nil {
db = db.WithContext(ctx)
}
var rows []headingSettings
if err := db.Model(&models.Settings{}).Select("content_h1_to_h2", "generic_anchors").
Where("id = ?", 1).Limit(1).Find(&rows).Error; err != nil || len(rows) == 0 {
return headingSettings{}, false
}
return rows[0], true
}
// EffectiveH1ToH2 is the one reader of the H1 setting (P33-04): the settings
// row's content_h1_to_h2 decides; without a row (or a database) the config
// key golem15.journal.content_h1_to_h2 does, and true when that is unset
// too. While it is true every H1 saved in Journal rich text becomes an H2.
func EffectiveH1ToH2(ctx context.Context, db *gorm.DB, cfg *compass.Config) bool {
if row, ok := readHeadingSettings(ctx, db); ok {
return row.ContentH1ToH2
}
if cfg != nil && cfg.Has(H1ToH2Key) {
return cfg.Bool(H1ToH2Key)
}
return true
}
// GenericAnchors is the list of generic link texts: the settings row's
// generic_anchors, one entry per line, trimmed and lowercased with blank
// lines dropped, or DefaultGenericAnchors when the row has no list (no
// row, NULL or only blank lines).
func GenericAnchors(ctx context.Context, db *gorm.DB) []string {
row, ok := readHeadingSettings(ctx, db)
if !ok || row.GenericAnchors == nil {
return append([]string(nil), DefaultGenericAnchors...)
}
var out []string
seen := map[string]bool{}
for _, line := range strings.Split(*row.GenericAnchors, "\n") {
entry := strings.ToLower(strings.TrimSpace(line))
if entry == "" || seen[entry] {
continue
}
seen[entry] = true
out = append(out, entry)
}
if len(out) == 0 {
return append([]string(nil), DefaultGenericAnchors...)
}
return out
}