feat: H1 conversion on the API, markdown and import paths
- the /_journal/api/v1 post writes convert default and translated content in the write transaction and answer an additive notices key - journal:import-posts converts and prints the converted count (ImportFromDirConfig, ImportStats.H1Converted) - a category's pillar text saved in the admin answers editor.h1_converted_category - every GET /categories row reports content_h1_to_h2 (additive key)
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"git.golem15.com/golem15/sm-journal-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/compass"
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
@@ -35,6 +36,9 @@ const (
|
||||
// EditorH1Converted is the notice of a save that turned H1 headings
|
||||
// into H2 (Count is the number of headings).
|
||||
EditorH1Converted = "golem15.journal::lang.editor.h1_converted"
|
||||
// EditorH1ConvertedCategory is EditorH1Converted for a category's
|
||||
// pillar text, which names the category name instead of the post title.
|
||||
EditorH1ConvertedCategory = "golem15.journal::lang.editor.h1_converted_category"
|
||||
)
|
||||
|
||||
// blogListValueRunes is how many runes of text a list column shows.
|
||||
@@ -153,8 +157,9 @@ func checkUploadFolder(folder string) error {
|
||||
|
||||
// decodeBlogHTMLFor is the Blog Editor types' Decode: decodeBlogHTML, then,
|
||||
// while the H1 setting is on (EffectiveH1ToH2 on the save transaction and
|
||||
// the booted application's config), ConvertH1 on the stored HTML with the
|
||||
// EditorH1Converted notice counting the converted headings. app may be nil
|
||||
// the booted application's config), ConvertH1 on the stored HTML with a
|
||||
// notice counting the converted headings: EditorH1ConvertedCategory on a
|
||||
// category's pillar text, EditorH1Converted otherwise. app may be nil
|
||||
// or answer nil; the setting is then read from the database alone.
|
||||
func decodeBlogHTMLFor(app func() *backpack.App) func(context.Context, pact.FormFieldValue) (pact.FormFieldDecoded, error) {
|
||||
return func(ctx context.Context, in pact.FormFieldValue) (pact.FormFieldDecoded, error) {
|
||||
@@ -174,11 +179,21 @@ func decodeBlogHTMLFor(app func() *backpack.App) func(context.Context, pact.Form
|
||||
return out, nil
|
||||
}
|
||||
out.Value = converted
|
||||
out.Notices = append(out.Notices, pact.FormFieldNotice{Message: EditorH1Converted, Count: n})
|
||||
out.Notices = append(out.Notices, pact.FormFieldNotice{Message: h1ConvertedNotice(in.Record), Count: n})
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
// h1ConvertedNotice is the conversion notice for the saved record: the
|
||||
// category phrase for a category, the post phrase otherwise.
|
||||
func h1ConvertedNotice(record any) string {
|
||||
switch record.(type) {
|
||||
case *models.Category, models.Category:
|
||||
return EditorH1ConvertedCategory
|
||||
}
|
||||
return EditorH1Converted
|
||||
}
|
||||
|
||||
// appConfig is the config of the application app answers, nil when there
|
||||
// is none.
|
||||
func appConfig(app func() *backpack.App) *compass.Config {
|
||||
|
||||
@@ -60,3 +60,39 @@ func CountH1(html string) int {
|
||||
func containsFold(s, sub string) bool {
|
||||
return strings.Contains(strings.ToLower(s), sub)
|
||||
}
|
||||
|
||||
// ConvertContentH1 applies ConvertH1 to a post body and its rendered HTML
|
||||
// (content and content_html) and returns both with the number of headings
|
||||
// converted: content_html's count, or content's when content_html had none
|
||||
// (a markdown body has no h1 tag, its rendered HTML does).
|
||||
func ConvertContentH1(content, contentHTML string) (string, string, int) {
|
||||
content, nContent := ConvertH1(content)
|
||||
contentHTML, nHTML := ConvertH1(contentHTML)
|
||||
if nHTML > 0 {
|
||||
return content, contentHTML, nHTML
|
||||
}
|
||||
return content, contentHTML, nContent
|
||||
}
|
||||
|
||||
// ConvertTranslationH1 applies ConvertContentH1 to the string content and
|
||||
// content_html of one locale's translated attributes, in place, and returns
|
||||
// the number of headings converted. Other attributes and values that are
|
||||
// not strings are left alone.
|
||||
func ConvertTranslationH1(attrs map[string]any) int {
|
||||
if attrs == nil {
|
||||
return 0
|
||||
}
|
||||
content, hasContent := attrs["content"].(string)
|
||||
html, hasHTML := attrs["content_html"].(string)
|
||||
if !hasContent && !hasHTML {
|
||||
return 0
|
||||
}
|
||||
content, html, n := ConvertContentH1(content, html)
|
||||
if hasContent {
|
||||
attrs["content"] = content
|
||||
}
|
||||
if hasHTML {
|
||||
attrs["content_html"] = html
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user