aboutsummaryrefslogtreecommitdiffstats
path: root/internal/store/sections.go
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-16 18:37:20 +0300
committergrm <grm@eyesin.space>2026-09-16 18:37:20 +0300
commit6b6b5d2e35ff182a0732da245f4eb37c8afa0564 (patch)
treef56960ae86c3c289f9a68e38ec01f1e3ff997466 /internal/store/sections.go
parent5119018feeaa22c47c0e91e15d3b9414dd6e0772 (diff)
downloadblogspace-6b6b5d2e35ff182a0732da245f4eb37c8afa0564.tar.gz
blogspace-6b6b5d2e35ff182a0732da245f4eb37c8afa0564.tar.bz2
blogspace-6b6b5d2e35ff182a0732da245f4eb37c8afa0564.zip
Add an HTML mode to posts, page intros and announcements
Markdown is the default and unchanged; the editor's new Format switch stores the text as raw HTML instead, put on the blog exactly as written. Like the custom HTML module it is unsanitised on purpose: the escape hatch for embeds, scripts and inline styles that Markdown cannot express. The source column keeps holding the text in both modes and a `format` column says how to read it, so the public templates and the feed still print the stored `*_html`. The dashboard preview of HTML goes into a sandboxed iframe rather than the page, because a superadmin edits other people's blogs and their markup must never run on the dashboard origin. Search snippets of HTML posts are cut from a tag-stripped copy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/store/sections.go')
-rw-r--r--internal/store/sections.go15
1 files changed, 8 insertions, 7 deletions
diff --git a/internal/store/sections.go b/internal/store/sections.go
index 2f742f7..2d72ea4 100644
--- a/internal/store/sections.go
+++ b/internal/store/sections.go
@@ -12,6 +12,7 @@ type Section struct {
Title string
BodyMD string
BodyHTML string
+ Format string // FormatMarkdown | FormatHTML: how BodyMD is read
Placement string // <column>-<position>: left|main|right - top|bottom
Style string // plain | note | warning
Enabled bool
@@ -24,11 +25,11 @@ type Section struct {
func (s Section) Column() string { c, _, _ := strings.Cut(s.Placement, "-"); return c }
func (s Section) Position() string { _, p, _ := strings.Cut(s.Placement, "-"); return p }
-const sectionCols = `id, title, body_md, body_html, placement, style, enabled, sort_order, created_at, updated_at`
+const sectionCols = `id, title, body_md, body_html, format, placement, style, enabled, sort_order, created_at, updated_at`
func scanSection(row interface{ Scan(...any) error }) (*Section, error) {
var s Section
- err := row.Scan(&s.ID, &s.Title, &s.BodyMD, &s.BodyHTML, &s.Placement, &s.Style, &s.Enabled, &s.SortOrder, &s.CreatedAt, &s.UpdatedAt)
+ err := row.Scan(&s.ID, &s.Title, &s.BodyMD, &s.BodyHTML, &s.Format, &s.Placement, &s.Style, &s.Enabled, &s.SortOrder, &s.CreatedAt, &s.UpdatedAt)
if err != nil {
return nil, wrap(err)
}
@@ -66,14 +67,14 @@ func (bs *BlogStore) SectionByID(ctx context.Context, id int64) (*Section, error
}
func (bs *BlogStore) CreateSection(ctx context.Context, sec *Section) (*Section, error) {
- return scanSection(bs.db.QueryRow(ctx, `INSERT INTO sections (title, body_md, body_html, placement, style, enabled, sort_order)
- VALUES ($1,$2,$3,$4,$5,$6,(SELECT coalesce(max(sort_order),-1)+1 FROM sections)) RETURNING `+sectionCols,
- sec.Title, sec.BodyMD, sec.BodyHTML, sec.Placement, sec.Style, sec.Enabled))
+ return scanSection(bs.db.QueryRow(ctx, `INSERT INTO sections (title, body_md, body_html, format, placement, style, enabled, sort_order)
+ VALUES ($1,$2,$3,$4,$5,$6,$7,(SELECT coalesce(max(sort_order),-1)+1 FROM sections)) RETURNING `+sectionCols,
+ sec.Title, sec.BodyMD, sec.BodyHTML, formatOrMD(sec.Format), sec.Placement, sec.Style, sec.Enabled))
}
func (bs *BlogStore) UpdateSection(ctx context.Context, sec *Section) error {
- _, err := bs.db.Exec(ctx, `UPDATE sections SET title=$2, body_md=$3, body_html=$4, placement=$5, style=$6, enabled=$7, updated_at=now() WHERE id=$1`,
- sec.ID, sec.Title, sec.BodyMD, sec.BodyHTML, sec.Placement, sec.Style, sec.Enabled)
+ _, err := bs.db.Exec(ctx, `UPDATE sections SET title=$2, body_md=$3, body_html=$4, format=$5, placement=$6, style=$7, enabled=$8, updated_at=now() WHERE id=$1`,
+ sec.ID, sec.Title, sec.BodyMD, sec.BodyHTML, formatOrMD(sec.Format), sec.Placement, sec.Style, sec.Enabled)
return wrap(err)
}