Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Post Content Laravel Package

guillaumeferron/post-content

PostContent is a Laravel package for managing post content in Eloquent models. It offers a clean API to store, organize, and render post bodies and related content, making it easy to add flexible publishing or CMS-style features to your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the field via Composer into an existing Laravel Nova app:

composer require guillaumeferron/post-content

Before wiring it into a resource, read the README end-to-end and open src/ to inspect the field class. At 22 stars and a single maintainer, the source is the documentation for anything the README glosses over — check the Field subclass to see what $component it registers, what meta() it exposes to the frontend, and whether it ships a publishable config.

Add the field to a Nova resource:

use GuillaumeFerron\PostContent\PostContent;

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Title')->rules('required', 'max:255'),
        PostContent::make('Content'),
    ];
}

The first real use case is replacing a Trix or Textarea field where editors were hand-writing repeated block markup. This field gives you a structured builder instead: you keep the model column as a single JSON/comma column and render it in Blade. Create the migration column as json (or longText on older MySQL) and add an array/json cast to the model before you first save, so you never debug a half-stringified payload.

Implementation Patterns

Store structured, render declaratively. The field's value comes back as a nested structure, not HTML. Cast it in the model and hand blocks to partials:

protected $casts = ['content' => 'array'];
@foreach ($post->content['blocks'] ?? [] as $block)
    @includeIf("partials.blocks.{$block['type']}", ['block' => $block])
@endforeach

@includeIf keeps unknown block types from 500-ing your page when an editor adds a block you haven't built a partial for yet — important, because the field lets non-developers mint structure faster than you can ship templates.

Pair it with the rest of a post resource. The field is deliberately a content builder, not a page builder. Compose around it: Text for title, Slug/Text for the permalink, DateTime/Date for published_at, BelongsTo for author, and a Boolean for draft status. Keep the content field isolated so index views stay cheap — use PostContent::make('Content')->onlyOnForms() and surface a derived excerpt accessor in the index instead.

Draft/revision workflows. Because the whole payload is one JSON column, revisions are trivial: a PostRevision model plus a Nova action that copies $post->content into a revision row on save gives you version history without fighting the field. This is often the single highest-value integration and it's why a JSON column beats per-block Eloquent models here.

Feed the front end. Expose content through an API resource unchanged and let the SPA render blocks — the structure is already serializable. Do not pre-render to HTML in the field or in an accessor; you'll lose the ability to restyle blocks later.

Gotchas and Tips

  • Confirm Nova major-version compatibility first. Nova fields break silently on major upgrades (asset compilation, meta() contract). Check the package's composer.json constraint against your Nova version before adopting, and pin the field version.
  • The stored shape is your migration risk, not the package's. Log or dd() one saved payload early and snapshot the JSON shape in a test fixture. A future block-type rename is a data migration; decide now whether your renderer tolerates unknown/missing type keys.
  • Don't cast to object. Use array and null-coalesce aggressively (?? [], ?? ''). Half-saved or editor-cleared blocks are the number one source of Trying to access array offset on null in Blade.
  • Validation lives with you. Nova rules() on a JSON field is weak; add a FormRequest or model-level validation for required content and block count limits, and validate required subkeys of each block type when you render.
  • Index/search friction. JSON columns aren't searchable in Nova's default Text-based index. Add a derived excerpt column or scope with whereJsonContains if you need filtering, and avoid sortable() on the content field.
  • Small-package bus factor. With 22 stars and one maintainer, expect to fork. Keep your Blade partials decoupled from the exact payload shape via a small renderBlock() helper so a maintained fork — or a swap to a Block-model approach — is a one-file change.
  • Extension points to check in source: whether the field exposes per-block configuration through meta(), whether the frontend component list is hardcoded (in which case custom block types mean publishing and editing the Vue component), and whether a config file can be published (php artisan vendor:publish). If block types are hardcoded with no config hook, that's your main long-term constraint — plan for a fork or a wrapper field.
  • Debugging tip: when the Nova form renders empty but the DB has data, the issue is almost always the cast (string vs array) or a payload saved before the cast existed. Re-save once after fixing the cast.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console