Blog

The filament-blog plugin is the CMS half of a blog: a blog_posts table, a Filament PostResource, markdown body editing, an optional thumbnail, and a Draft / Published workflow. It is a first-party Qcentic package (Plugins), one of the Docs stack plugins enabled per clone.

What the plugin owns

  • Tableblog_posts (id, user_idusers, title, slug, body longText, published_at nullable, timestamps). The migration ships with the package.
  • ResourcePostResource in the panel: title, unique slug, MediaLibraryFileUpload thumbnail, MediaMarkdownEditor body, a PublishStatus field, and SeoFields from the SEO plugin.
  • ModelPost uses InteractsWithMedia (Spatie), HasSeo, and CanBePreviewed. thumbnail is a single-file collection on the s3 disk; body is a media collection for inline images.
  • Statuspublished_at is the single source of truth. Post::isPublished() and the published scope return rows where published_at <= now(); everything else is a draft.

What the plugin does NOT ship

Public HTML. The package deliberately stops at the CMS and table. The clone renders /blog/{slug} with its own Blade layout so crawlers see real HTML and the product keeps its own look (Build a product). Post::publicPath() defaults to /blog/{slug}; override the method in the clone if the product uses another prefix.

Draft preview

The Preview action on the edit and list pages opens publicPath() in a new tab. Logged-in editors and super_admin (or the row's author) see the draft rendered by the clone; guests still get a 404. Preview is not a Filament page — it is the real public URL with the visibility gate described in Draft preview.

SEO and the Content API

Posts use the SEO plugin (HasSeo): per-post title, description, and JSON-LD, with the thumbnail as the social image (Post::seoThumbnailUrl()). Posts can also be written programmatically through the Content API at /api/v1/posts when the API key carries posts:* abilities.

Writing on edge.qcentic.com

No posts are published yet on this site. Writers are welcome — contact info@qcentic.com (shown as an image on the /blog page, not plain text, to deter scraping).

flowchart LR
    A["PostResource (panel)"] --> B["blog_posts table"]
    B --> C{"published_at <= now()?"}
    C -- yes --> D["clone /blog/{slug} view"]
    C -- no --> E["draft: editors only"]
    E --> D

See also

Built by Qcentic