feat(admin): post content on the Blog Editor field type
- blogeditor and mlblogeditor field types (classes.BlogEditorTypes) on the plugin; post content is mlblogeditor with htmlColumn content_html - Decode stores SanitizeHTMLReport output per locale with notices naming what was removed; clean HTML is stored byte for byte, nothing is refused because of markup - Load serves HTML as stored and markdown posts as their content_html - the admin hooks copy written content to content_html per locale without goldmark; untouched content leaves both columns as they are - editor lang keys (en, pl plural notices), tracer smoke test, updated Postgres admin tests
This commit is contained in:
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.golem15.com/golem15/sm-journal-plugin/classes"
|
||||
"git.golem15.com/golem15/sm-journal-plugin/console"
|
||||
"git.golem15.com/golem15/sm-journal-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
@@ -210,13 +209,75 @@ func preparePostWrite(ctx context.Context, post *models.Post) error {
|
||||
"published_at": []string{"golem15.journal::lang.post.published_validation"},
|
||||
}}
|
||||
}
|
||||
html, err := classes.FormatHTML(post.Content)
|
||||
if err != nil {
|
||||
return &cabana.ValidationError{Details: map[string]any{
|
||||
"content": []string{err.Error()},
|
||||
}}
|
||||
// D-02: the Blog Editor's Decode already stored the policy's output in
|
||||
// content; content_html gets the same HTML, without goldmark. Content the
|
||||
// save does not write (untouched, D-03) leaves content_html as it is.
|
||||
if writes, ok := cabana.FieldWritesFromContext(ctx); ok {
|
||||
for _, w := range writes["content"] {
|
||||
if !w.Default {
|
||||
continue
|
||||
}
|
||||
if html, isString := w.Value.(string); isString {
|
||||
post.ContentHTML = html
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FormAfterCreate writes content_html for every non-default locale whose
|
||||
// content the save wrote (D-02).
|
||||
func (c postsAdminController) FormAfterCreate(ctx context.Context, model any) error {
|
||||
return c.writeContentHTMLTranslations(ctx, model)
|
||||
}
|
||||
|
||||
// FormAfterUpdate writes content_html for every non-default locale whose
|
||||
// content the save wrote (D-02). Untouched locales are not listed and keep
|
||||
// their content_html.
|
||||
func (c postsAdminController) FormAfterUpdate(ctx context.Context, model any) error {
|
||||
return c.writeContentHTMLTranslations(ctx, model)
|
||||
}
|
||||
|
||||
// writeContentHTMLTranslations stores each written non-default content
|
||||
// value as that locale's content_html through the published
|
||||
// cabana.TranslationWriter, inside the save transaction. Without a writer
|
||||
// there is nothing to write.
|
||||
func (c postsAdminController) writeContentHTMLTranslations(ctx context.Context, model any) error {
|
||||
post, ok := model.(*models.Post)
|
||||
if !ok || post == nil {
|
||||
return errors.New("posts admin: form model is not a post")
|
||||
}
|
||||
writes, ok := cabana.FieldWritesFromContext(ctx)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
var pending []cabana.FieldWrite
|
||||
for _, w := range writes["content"] {
|
||||
if !w.Default && w.Locale != "" {
|
||||
pending = append(pending, w)
|
||||
}
|
||||
}
|
||||
if len(pending) == 0 {
|
||||
return nil
|
||||
}
|
||||
app := c.application()
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
writer, ok := app.Lookup[cabana.TranslationWriter]()
|
||||
if !ok || writer == nil {
|
||||
return nil
|
||||
}
|
||||
tx := c.db(ctx)
|
||||
for _, w := range pending {
|
||||
html, isString := w.Value.(string)
|
||||
if !isString {
|
||||
return fmt.Errorf("posts admin: content for %s is %T, want a string", w.Locale, w.Value)
|
||||
}
|
||||
if err := writer.WriteTranslated(ctx, tx, post, "content_html", w.Locale, html); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
post.ContentHTML = html
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user