Stores: cmsstore

Manage multisite content, templates, and shortcodes with github.com/dracory/cmsstore.

github.com/dracory/cmsstore

cmsstore is a CMS-focused store that manages sites, pages, templates, blocks, menus, translations, and shortcodes. It gives Go applications a ready-made content layer backed by SQL with interface-driven design.


Highlights

  • Multisite aware – manage multiple sites from a single store instance with per-site templates, pages, blocks, menus, and translations.
  • Shortcodes – register custom shortcode renderers to inject dynamic content into pages.
  • Rich page model – pages support custom templates, SEO metadata, middleware hooks, and soft deletion.
  • Reusable blocks & menus – blocks provide reusable content snippets; menus define navigations with metadata and ordering helpers.
  • Translations – key/value translation entries scoped to site and locale for multi-language content.
  • Schema via migrations – schema creation is handled by migration files, not automigration.

Creating a Store

func NewCmsStore(db *sql.DB, debug bool) (cmsstore.StoreInterface, error) {
    st, err := cmsstore.NewStore(cmsstore.NewStoreOptions{
        DB:                   db,
        BlockTableName:       "snv_cms_block",
        PageTableName:        "snv_cms_page",
        TemplateTableName:    "snv_cms_template",
        SiteTableName:        "snv_cms_site",
        MenusEnabled:         true,
        MenuItemTableName:    "snv_cms_menu_item",
        MenuTableName:        "snv_cms_menu",
        TranslationsEnabled:  true,
        TranslationTableName: "snv_cms_translation",
        VersioningEnabled:    true,
        VersioningTableName:  "snv_cms_version",
    })
    if err != nil {
        return nil, err
    }
    st.EnableDebug(debug)
    return st, nil
}
  • Menus support – enabled with MenusEnabled: true, MenuTableName, and MenuItemTableName.
  • Versioning support – enabled with VersioningEnabled: true and VersioningTableName.
  • Translations support – enabled with TranslationsEnabled: true and TranslationTableName.
  • Debug is controlled via st.EnableDebug(debug) after store creation.
  • Schema creation is handled by migration files in database/migrations/ (invoked via migrations.MigrateAll(app)), not by automigration.
  • Register shortcode implementations via ShortcodeInterface for dynamic rendering.

Working with Pages

page := cmsstore.NewPage().
    SetSiteID(siteID).
    SetSlug("about").
    SetTitle("About Us").
    SetTemplateID(templateID).
    SetContent("<p>Hello world</p>").
    SetStatus(cmsstore.PAGE_STATUS_PUBLISHED)

if err := store.PageCreate(ctx, page); err != nil {
    log.Fatal(err)
}

page.SetSEODescription("Learn more about our company")
if err := store.PageUpdate(ctx, page); err != nil {
    log.Fatal(err)
}
  • Pages expose helpers for SEO fields, visibility scheduling, middleware, and metadata via SetMetas.
  • Use PageList with PageQuery() to filter by site, status, slug, template, created range, etc.

Blocks, Menus, Templates, Translations

block := cmsstore.NewBlock().
    SetSiteID(siteID).
    SetSlug("footer").
    SetContent("<footer>...</footer>")

if err := store.BlockCreate(ctx, block); err != nil {
    log.Fatal(err)
}

menu := cmsstore.NewMenu().
    SetSiteID(siteID).
    SetSlug("main-nav").
    SetItemsJSON(`[{"title":"Home","url":"/"}]`)

_ = store.MenuCreate(ctx, menu)
  • Templates capture layouts (HTML/Go template markup) with metadata and soft-delete support.
  • Translations store key/value pairs per locale and can be queried via TranslationQuery() to build localized content.

Shortcodes

  1. Implement cmsstore.ShortcodeInterface (alias, description, render).
  2. Register the shortcode in NewStoreOptions.Shortcodes.
  3. Use the shortcode delimiters in page content; cmsstore renders during processing.

Shortcodes live in your Go codebase, so they are version-controlled and share application dependencies.


  • Design Principles – review the shared store architecture.
  • Entities & Interfaces – explore how cmsstore embeds the dataobject traits.
  • Testing – repository uses SQLite-based tests to validate functionality.
  • Create Your Own Store – extend cmsstore patterns for custom CMS features or integrations.