baijunyao/laravel-bjyblog
Laravel BJYBlog is an open-source blog system built on Laravel, offering article and category management, tags, comments, an admin dashboard, and customizable themes. It provides a practical foundation for launching and managing a personal or technical blog with a modern PHP framework.
This is a complete Laravel 9 application, not a Composer library — you do not composer require it. You fork or clone it and treat the codebase as your own.
git clone https://github.com/baijunyao/laravel-bjyblog.git my-blog
cd my-blog
composer install
cp .env.example .env
php artisan key:generate
Configure .env (MySQL/MariaDB with utf8mb4 is the safe choice), then:
php artisan migrate --seed
php artisan storage:link
npm install && npm run build # check whether the branch uses Vite or Mix
php artisan serve
Where to look first:
routes/web.php and the admin route file (usually routes/admin.php or registered in RouteServiceProvider) — this reveals the frontend vs. /admin split.app/Http/Controllers/Admin/ — the CRUD pattern you will copy for any new content type.database/seeders/ — admin account credentials are seeded here; change the password immediately after first login.config/ — check for a project-specific config file (e.g. bjyblog.php) for site name, upload paths, and behavior toggles.resources/views/ — separate admin/ and frontend theme trees.First use case: log in at /admin with the seeded credentials, publish one article with a category and tags, then confirm it renders on the frontend. This exercises the full write path (auth → controller → model → sitemap/cache hooks → public view) before you customize anything.
Copy the Article module for new entities. The Article flow (migration → Model → Admin resource controller → Blade create/edit forms → frontend presenter) is the canonical template. When adding something like "Series" or "Projects," clone those files structurally rather than inventing a new pattern; it keeps the admin navigation, validation, and listing conventions consistent.
Respect the admin/frontend split. Keep admin controllers in the Admin namespace and behind the package's auth guard/middleware. Frontend controllers should stay thin — read models, pass to Blade, done. Mixing concerns here is the fastest way to make upgrades painful.
Use model scopes for visibility. Publish/draft state should be a query scope (e.g. published()), applied consistently in frontend controllers, widgets, and sitemap generation. Never filter inline in views — it will drift.
Hook caching and sitemap regeneration to model events. Register Observer or model event listeners in a service provider for save/delete on Article to bust the cache and rebuild the sitemap. This is the intended extension point rather than sprinkling logic in controllers.
Extend via Blade composition. Frontend themes are Blade layouts plus partials. Add widgets as Blade components or includes rather than editing core layout files, so you can swap themes without conflicts.
Add admin menu entries in one place. The admin sidebar is typically driven by config or a single Blade partial — add new modules there so navigation stays consistent.
Handle uploads through the existing storage abstraction. Article cover images and attachments already have a convention; reuse that disk/path helper instead of hardcoding public_path(), otherwise storage:link assumptions break.
If search is wired up (Scout/Elasticsearch), keep the index in sync via observers, not manual reindex calls in controllers.
composer update. Since this is an app, upstream changes must be pulled and merged by hand. Tag your fork and diff against upstream releases deliberately.APP_KEY before exposing anything. Default seeders are the single most common source of compromised deployments.utf8mb4 in both the database and the connection config, or emoji and CJK content in comments will truncate or error.config/app.php timezone and locale — scheduled posts and displayed dates will be wrong if left as-is.storage/ and bootstrap/cache/ are writable and that storage:link succeeded; failed cover images are almost always a symlink or permission issue, not a code bug.package.json scripts and vite.config.js/webpack.mix.js presence.How can I help you explore Laravel packages today?