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

Voyager Blog Laravel Package

pvtl/voyager-blog

A Laravel Voyager package that adds blog management to the admin panel, providing CRUD for posts, categories, and tags plus frontend-ready models and routes for publishing and displaying articles in your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Acknowledge the archive status before anything else. This package is archived and has not tracked Voyager or Laravel releases since. Before installing, check composer.json in the repo for its Laravel/Voyager constraints and confirm they intersect with your app. On a modern Laravel (10+) you will almost certainly need to fork it, bump constraints, and fix type/return declarations yourself. Treat installation as "vendor and own it," not "composer require and forget."

Minimal path:

  1. Install alongside Voyager. Voyager (the the-control-group/voyager admin panel) must already be installed, migrated, and have an admin user. This package is a module on top of Voyager's BREAD system, not a standalone blog.
  2. Require the package (path repository or VCS fork is safer than Packagist given the archive), then run the service provider's publish command — typically php artisan vendor:publish --provider="Pvtl\VoyagerBlog\VoyagerBlogServiceProvider" — to get migrations, seeders, config, and views into your app.
  3. Migrate, then seed. The migrations create the posts/categories/tags tables plus pivots. The seeder is what registers the BREAD entries and the "Blog" section in the Voyager admin menu — without it you get tables but no admin UI. Run migrations first, then the seeder.
  4. Look first at: database/migrations/ (table names and columns — you will extend them), src/Models/ (relationships and any scopes), the seeder (which BREAD rows and menu items get created), and resources/views/ (whether any frontend templates actually ship, which is often not the case).
  5. First use case: log into /admin, open the new Blog menu, create a Category, then a Post with a title, slug, body, and category. Then wire a trivial frontend route in your app (Route::get('/blog', ...)) that queries the Post model and renders the results. The package gives you content modeling and admin CRUD; the public-facing routing and controllers are yours to write.

Implementation Patterns

Let BREAD do the schema work, not migrations. The idiomatic Voyager workflow is: add columns via a normal migration, then use the Voyager BREAD editor (or data_rows inserts) to expose them as form fields. Fight the urge to hardcode admin forms — the whole point of this package is that editors manage posts through Voyager's UI.

Relationships are configured in two places. Post→Category (belongsTo) and Post↔Tag (belongsToMany) need both the Eloquent methods on the models and the relationship declared in the BREAD "Relationships" tab so Voyager renders the correct select/multi-select and persists pivot rows. If tags silently don't save, this is the first thing to check.

Frontend integration pattern. Build a thin BlogController with index/show (and optionally category/tag filtered variants), use route model binding on slug, and add query scopes for published state (whereNotNull('published_at')->where('published_at', '<=', now())). Keep the scopes on the model so admin previews and frontend listings share one definition of "published."

Media handling. Featured images normally go through Voyager's media manager, which stores a path string for single-image fields or JSON for multi-image fields. Normalize on read (helper/accessor) so your Blade templates don't care which shape the field returns.

Caching and sidebars. Blog indexes and "recent posts"/category sidebars are read-heavy and rarely change minute-to-minute. Cache rendered fragments keyed by page/category, and clear on Post save via a model observer. A view composer is a clean place to inject categories/tags into layouts.

Extending without forking. Publish the views and override them in resources/views/vendor/.... If you need behavior changes, prefer model observers, extra BREAD fields, and subclassing over editing package source — this keeps your fork delta small, which matters for a package nobody is maintaining.

Gotchas and Tips

  • Archived means version drift is your problem. Pin exact versions, commit the fork, and add a smoke test that hits the admin post list and a frontend post page so a future Laravel upgrade breaks loudly rather than silently.
  • Seeder re-runs duplicate BREAD/menu rows. Voyager seeders are usually not idempotent. Run them once; if you need to re-register, clear the relevant bread/data_rows/menu_items rows first or write guarded inserts.
  • Table name collisions. If you already have posts, categories, or tags tables, the package migrations will conflict. Rename or prefix before migrating — retrofitting after data exists is painful.
  • Slugs are not auto-generated by default in Voyager. Users type them. Add a model saving hook to slugify from the title when empty and enforce uniqueness, or you will get 404s and duplicate-slug route-binding surprises.
  • The published_at null case. A common bug is where('published_at', '<=', now()) excluding drafts correctly but also excluding posts where the field is stored as 0000-00-00 by older MySQL modes. Standardize on NULL for drafts.
  • Permissions. BREAD entries exist but roles still need the browse/read/edit/add/delete permissions granted. New admin users seeing an empty blog menu is a permissions issue, not a broken install.
  • Clear caches after publishing. php artisan config:clear && php artisan view:clear && php artisan cache:clear after any vendor:publish — stale compiled views are the most common "my changes aren't showing" cause with Voyager modules.
  • Debugging BREAD issues: inspect the bread and data_rows tables directly. Field-name mismatches between data_rows.field and the actual column are the usual culprit when form saves appear to succeed but nothing persists.
  • Don't expect routes or a working /blog out of the box. Budget time for frontend controllers, views, pagination, and SEO metadata — the package's value is admin CRUD and content modeling, not a finished blog.
  • If you're starting fresh today, weigh a maintained alternative (a simple custom Post model + Filament, or Voyager's own page module) against adopting an archived module. Adopt this only if you're already committed to Voyager and the fork cost is acceptable.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager