antoniputra/ngeblog
A lightweight blogging package for Laravel that adds posts, categories, and tags with ready-made CRUD, routes, and Blade views. Drop it into an existing app to get a simple blog or news section up and running quickly, with configurable models and migrations.
Ngeblog is a Laravel "quickstart" blog: it ships routes, controllers, a Post model, migrations, and Blade views so you can stand up a working blog with minimal wiring. Treat it as scaffolding you will fork and edit, not as a locked-down CMS.
Install and smoke test in ~10 minutes:
composer require antoniputra/ngeblog
php artisan vendor:publish --provider="Antoniputra\Ngeblog\NgeblogServiceProvider"
php artisan migrate
php artisan route:list | grep -i blog
Then hit the routes you just listed (likely /blog for the front end and a prefixed group such as /ngeblog or /admin/blog for CRUD). If nothing routes, check config/ngeblog.php for a prefix / route_group toggle and the package README for the expected namespace.
Where to look first, in order:
php artisan route:list — the fastest way to learn what the package actually registers and which middleware it assumes.config/ngeblog.php (after publishing) — route prefix, layout, middleware, pagination, upload disk.src/Http/Controllers directory in vendor/antoniputra/ngeblog — this is your real API surface; there is no formal docs site.posts, categories, tags) before you write anything that joins to them.First realistic use case: a marketing/company site where a content editor needs a "News" or "Blog" section. You mount the front-end routes under /news, keep the admin CRUD behind your existing auth guard, and publish only the views you want to restyle. Do not try to use it as a multi-author editorial platform on day one — see Gotchas.
1. Publish selectively, not everything at once. Vendor publish tags are your friend. Publish config and migrations first, run them, verify the front end renders, then publish views you intend to override:
php artisan vendor:publish --provider="Antoniputra\Ngeblog\NgeblogServiceProvider" --tag=config
php artisan vendor:publish --provider="Antoniputra\Ngeblog\NgeblogServiceProvider" --tag=migrations
php artisan vendor:publish --provider="Antoniputra\Ngeblog\NgeblogServiceProvider" --tag=views
Once views are in resources/views/vendor/ngeblog, the package's view namespace resolves to yours and you can extend the shipped layout rather than replacing it.
2. Guard the admin surface behind your own auth. The package predates a strong opinion about authorization. Wrap its admin routes in your app's middleware rather than relying on whatever the package ships:
// routes/web.php
Route::middleware(['web', 'auth', 'can:manage-blog'])
->prefix('admin/blog')
->group(function () {
// re-declare or include the package's admin route file
});
If the package registers routes unconditionally, disable auto-loading in config/ngeblog.php (or in the service provider via $this->app['config']->set(...)) and register them yourself.
3. Extend the schema additively. Don't edit published package migrations in place — they are already applied on other environments. Add a new migration that alters posts:
Schema::table('posts', function (Blueprint $table) {
$table->boolean('featured')->default(false)->after('published_at');
$table->foreignId('author_id')->nullable()->constrained('users');
});
Then bind your own model that extends the package model and swap it via the config key (most quickstart packages expose a models.post entry) or a container binding in AppServiceProvider.
4. Front-end integration via named routes. Use route('ngeblog.posts.show', $post) (verify the exact names in route:list) rather than hardcoding /blog/{slug}. This lets you change the prefix later without hunting through Blade files.
5. Seed for local dev. Write a seeder that creates a handful of Post records with categories so the index/show views have something to render. This is far faster than clicking through the CRUD, and it makes visual regression obvious after you publish-and-edit views.
6. Feature flag the whole thing. If you're unsure whether the package fits, gate it behind a config toggle (config('features.blog')) and keep the routes registered conditionally. Removing it later is then a one-line change plus composer remove.
Low maintenance signal — plan for ownership. ~18 stars and a last release in April 2024 means you should expect to own this code. Before committing: check the repo's issue backlog, whether the service provider uses modern Laravel idioms (auto-discovery, loadMigrationsFrom, Route::middleware), and whether CI runs against current Laravel versions. If the provider is pre-5.5 style, you'll add it to config/app.php manually on modern Laravel.
Route name and prefix collisions. Quickstart packages commonly register generic names like posts.index. If your app already has a Post resource, route:cache will silently pick a winner and you'll get wrong URLs. Run php artisan route:list immediately after install and grep for the names the package uses. If they conflict, disable the package's route loading and re-register under distinct names.
Auth is on you. "Quickstart" often means "no admin authentication shipped." Do not deploy to a staging server reachable from the open internet until you have verified every admin route is behind auth. Test by logging out and hitting the CRUD URLs directly.
Republishing overwrites edits. vendor:publish --force on views will clobber your customizations. Keep your overrides in resources/views/vendor/ngeblog/** and never run --force on that tag again; if you must, git diff first.
Config cache staleness. If you change config/ngeblog.php in production and forget php artisan config:cache, route prefixes and disk settings will appear to "not work." Standard Laravel footgun, but it hits especially hard here because the package has no validation on its config.
Uploads and storage. If the package supports cover images, it almost certainly writes to a disk defined in its config. Verify php artisan storage:link has been run and that the disk in config/ngeblog.php matches config/filesystems.php. Broken images after deploy are usually a disk-name mismatch, not a code bug.
Slug uniqueness and route-model binding. If the package binds {post} by slug, duplicate or empty slugs cause 404s that look like routing bugs. Add a unique index on slug and, if the package doesn't auto-generate it, override the model's booted() to set slug from Str::slug($title) with a collision suffix.
Indonesian-language lineage. The package name ("ngeblog" = "blogging") and author suggest the README, comments, and any UI strings may be in Indonesian. Budget an afternoon for translating admin Blade strings to English if that matters for your users — it's a find-and-replace across published views, not a package config toggle.
Extension point you'll likely need: events. Quickstart packages rarely fire domain events (e.g., PostPublished). If you need side effects — newsletly notify, sitemap ping, Slack — the cleanest pattern is to hook into the controller via your own subclass, or to override the published controller and call event(new PostPublished($post)) there. Don't monkey-patch the vendor controller.
Testing. Add a smoke feature test that hits the blog index and a known post show route. It's five lines and it will catch 80% of the breakage the next time you run composer update:
public function test_blog_index_renders(): void
{
$this->get(route('ngeblog.posts.index'))->assertOk();
}
Escape hatch. If the package starts fighting you (hardcoded views, no config for auth, no route control), the honest call is to copy its Post model, migrations, and controllers into your app and drop the dependency. You lose upstream fixes that aren't coming anyway, and you gain full control. Weigh that after the first week — quickstart packages are often more useful as a reference implementation than a long-term dependency.
How can I help you explore Laravel packages today?