package console import ( "context" "fmt" "git.golem15.com/golem15/sm-journal-plugin/classes" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/bonfire" ) // FixHeadings is journal:fix-headings: it converts H1 to H2 in stored // Journal rich text (post content in every locale and category pillar text) // while the Journal H1 setting is on. It is a dry run unless --apply is // given; with the setting off it refuses with exit code 1. It runs from the // generated application CLI: without a published database it opens // database.dsn (lookupDB) and, without one, names SUMMER_DATABASE__DSN. Its // output (UI-SPEC C27 with the P33-54 wording, English only): // // - dry run: "Would convert :count H1 headings in :posts posts and :categories categories. Run with --apply to save." // - applied: "Converted :count H1 headings in :posts posts and :categories categories." // - nothing to do: "No H1 headings found in post or category content." // - refused (classes.H1ConversionOffText): "H1 to H2 conversion is turned off in the Journal settings (Headings and links). Turn it on first, or keep the H1 headings." func FixHeadings(app *backpack.App) bonfire.Command { return bonfire.Command{ Name: "journal:fix-headings", Description: "Convert H1 headings to H2 in stored post and category content", Long: `Finds every H1 heading in stored Journal content: post content and content_html in the default locale and in every translation, and the pillar text of every category. Switching the Journal H1 setting (Settings › Journal, Headings and links) on never rewrites stored content; this command does. By default it only counts ("Would convert N H1 headings in N posts and N categories. Run with --apply to save."). With --apply it converts them in one transaction, fires a record event per changed post and category (so an SEO or search plugin hears about it) and queues the site cache purge. While the H1 setting is off the command prints "H1 to H2 conversion is turned off in the Journal settings (Headings and links). Turn it on first, or keep the H1 headings." and exits with code 1. The MCP tool journal_fix_headings runs the same conversion.`, Flags: []bonfire.Flag{ {Name: "apply", Description: "Save the converted content (default: dry run)", Bare: true}, {Name: "dry-run", Description: "Only count the H1 headings (the default)", Bare: true}, }, Examples: []bonfire.Example{ {Command: "journal:fix-headings", Description: "Count the H1 headings that would be converted"}, {Command: "journal:fix-headings --apply", Description: "Convert them and save"}, }, Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error { db, done, err := lookupDB(ctx, app) if err != nil { return err } defer done() if !classes.EffectiveH1ToH2(ctx, db, appConfig(app)) { out.Error(classes.H1ConversionOffText) return bonfire.Reported(classes.ErrH1ConversionOff) } apply := flagOn(in, "apply") && !flagOn(in, "dry-run") res, err := classes.FixStoredHeadings(ctx, app, db, apply) if err != nil { return err } switch { case res.Headings == 0: out.Info("No H1 headings found in post or category content.") case apply: out.Success(fmt.Sprintf("Converted %d H1 headings in %d posts and %d categories.", res.Headings, res.Posts, res.Categories)) default: out.Info(fmt.Sprintf("Would convert %d H1 headings in %d posts and %d categories. Run with --apply to save.", res.Headings, res.Posts, res.Categories)) } return nil }, } }