happytodev/blogr

Blogr is a FilamentPHP plugin that adds a powerful blog system to your Laravel application.

Fund package maintenance!
happytodev

Installs: 51

Dependents: 0

Suggesters: 0

Security: 0

Stars: 16

Watchers: 0

Forks: 2

Open Issues: 6

pkg:composer/happytodev/blogr

0.14.1 2025-11-13 19:58 UTC

README

πŸš€ Blogr – The Ultimate FilamentPHP Blog Plugin

Latest Version Tests Code Style Downloads

Blogr Banner

A production-ready, feature-rich blog system for Laravel & FilamentPHP

Features β€’ Installation β€’ Documentation β€’ Screenshots β€’ Support

✨ Overview

Transform your Laravel application into a powerful blogging platform with Blogr – a comprehensive FilamentPHP plugin designed for developers who demand excellence. Built with modern best practices, fully tested (680+ tests), and packed with features you'll actually use.

Why Blogr?

  • 🌍 True Multilingual – Translate everything (posts, series, categories, tags)
  • πŸ“š Blog Series – Organize content into cohesive learning paths
  • οΏ½ CMS Page Builder – Create static pages (About, Contact, etc.) with block system
  • οΏ½πŸ’Ύ Backup & Restore – Export/import all data with media files
  • 🎨 Fully Customizable – Theme system, dark mode, configurable UI
  • πŸ” SEO Optimized – Meta tags, Open Graph, Schema.org, RSS feeds
  • ⚑ Production Ready – Comprehensive test coverage, battle-tested code

🎯 Key Features

πŸ’Ύ Backup & Migration System

  • Complete data export to JSON or ZIP
  • Media files included (images, avatars)
  • One-click restore from admin panel
  • Migration-ready for site transfers

🌍 Multilingual Support

  • 4+ languages out of the box (en, fr, es, de)
  • Localized routes (/{locale}/blog/...)
  • Translation UI in admin panel
  • SEO-friendly hreflang tags
  • Language switcher component

πŸ“š Blog Series

  • Organize related posts into series
  • Auto-navigation (prev/next)
  • Position ordering within series
  • Featured series highlighting
  • Progress tracking for readers

πŸ“„ CMS Page Builder

  • Static pages (About, Contact, etc.)
  • Block-based editor (Hero, Features, Testimonials, CTA)
  • Multiple templates (Default, Full Width, Sidebar)
  • Homepage option – Set any page as homepage
  • Reserved slugs protection
  • Multilingual pages support

✍️ Content Management

  • Markdown editor with live preview
  • Drag & drop images in content
  • Post scheduling (draft/scheduled/published)
  • Categories & tags system
  • Reading time calculation
  • Table of contents (auto-generated)
  • TL;DR summaries

🎨 Theming & UI

  • CSS variables theming system
  • Dark mode support (auto/manual)
  • Customizable colors per component
  • Flexible layouts (sidebar TOC, centered)
  • Author profiles with avatars & bios
  • Responsive design mobile-first

πŸ” SEO & Performance

  • Meta tags (title, description, keywords)
  • Open Graph & Twitter Cards
  • Schema.org structured data
  • RSS feeds (global, per category/tag)
  • Optimized URLs & slugs
  • Sitemap ready

πŸ“Š Dashboard Widgets

Five powerful widgets to monitor your blog:

  • BlogStatsOverview – Posts, categories, tags metrics
  • RecentBlogPosts – Latest posts with quick actions
  • ScheduledPosts – Upcoming publications
  • BlogPostsChart – Publication trends (12 months)
  • BlogReadingStats – Reading time analytics

πŸ‘₯ Author Features

  • Enhanced profiles with bio (Markdown support)
  • Avatar management with auto-fallback
  • Author pages (/blog/author/{userId})
  • Role-based permissions (Admin, Writer)
  • Self-service profile editing

βš™οΈ Admin Experience

  • Filament v4 native integration
  • Intuitive settings page with tabs
  • Tutorial content for onboarding
  • Demo seeders for quick start
  • Extensive documentation

πŸ“Έ Screenshots

πŸ–ΌοΈ Click to view screenshots

Frontend Views

Blog Home Page Blogr home

Blog Post View Blog post view

Blog Series Series

Admin Panel

Posts List Backend - List of posts

Post Editor Backend - Edit post

Settings Page Backend - Settings

Backend - New Settings

Dashboard Widgets Backend - Widgets

Interactive Demo

Drag & Drop Images Drag & Drop Demo

πŸš€ Quick Start

Prerequisites

  • Laravel 12.x
  • FilamentPHP v4.x
  • PHP 8.3+

Installation (2 minutes!)

# 1. Install via Composer
composer require happytodev/blogr

# 2. Run automated installer
php artisan blogr:install

# 3. That's it! πŸŽ‰

The installer handles everything:

  • βœ… Publishes config & migrations
  • βœ… Runs database migrations
  • βœ… Configures Alpine.js & Tailwind CSS
  • βœ… Installs npm dependencies
  • βœ… Creates storage symlink
  • βœ… (Optional) Installs tutorial content

Installation Options

# Full installation (recommended)
php artisan blogr:install

# Skip tutorial content
php artisan blogr:install --skip-tutorials

# Skip asset building (build later)
php artisan blogr:install --skip-build

# Skip all frontend setup
php artisan blogr:install --skip-frontend

Manual Installation

Click for manual installation steps

Skip tutorial and series content

php artisan blogr:install --skip-tutorials --skip-series


### Manual Installation (Advanced)

If you prefer to configure everything manually or need more control, follow these detailed steps:

#### 1. Install Alpine.js

```bash
npm install alpinejs

Then add Alpine.js to your resources/js/app.js:

import Alpine from 'alpinejs'

window.Alpine = Alpine

// Theme Switcher Component (required for light/dark/auto mode)
Alpine.data('themeSwitch', () => ({
    theme: localStorage.getItem('theme') || 'auto',
    
    init() {
        this.applyTheme();
        
        // Watch for system preference changes when in auto mode
        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
            if (this.theme === 'auto') {
                this.applyTheme();
            }
        });
    },
    
    setTheme(newTheme) {
        this.theme = newTheme;
        localStorage.setItem('theme', newTheme);
        this.applyTheme();
    },
    
    applyTheme() {
        const isDark = this.theme === 'dark' || 
                      (this.theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
        
        if (isDark) {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
    }
}));

Alpine.start()

2. Configure Tailwind CSS v4 for dark mode

Add the dark mode variant to your resources/css/app.css:

@import 'tailwindcss';

@plugin "@tailwindcss/typography";

/* Add these @source directives to include Blogr views */
@source '../../vendor/happytodev/blogr/resources/views/**/*.blade.php';
@source '../views/vendor/blogr/**/*.blade.php';

/* Configure dark mode with class strategy */
@variant dark (.dark &);

⚠️ Important: The @variant dark (.dark &); line is required for the theme switcher to work with Tailwind CSS v4.

3. Publish configuration and migrations

php artisan vendor:publish --provider="Happytodev\Blogr\BlogrServiceProvider"

4. Run migrations

php artisan migrate

5. Add BlogrPlugin to your AdminPanelProvider

1. Publish configuration and migrations

php artisan vendor:publish --provider="Happytodev\Blogr\BlogrServiceProvider"
php artisan migrate

2. Install Alpine.js

npm install alpinejs

Add to resources/js/app.js:

import Alpine from 'alpinejs'
window.Alpine = Alpine

// Theme Switcher Component
Alpine.data('themeSwitch', () => ({
    theme: localStorage.getItem('theme') || 'auto',
    init() { this.applyTheme(); },
    setTheme(newTheme) {
        this.theme = newTheme;
        localStorage.setItem('theme', newTheme);
        this.applyTheme();
    },
    applyTheme() {
        const isDark = this.theme === 'dark' || 
                      (this.theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
        document.documentElement.classList[isDark ? 'add' : 'remove']('dark');
    }
}));

Alpine.start()

3. Configure Tailwind CSS v4

Add to resources/css/app.css:

@import 'tailwindcss';
@plugin "@tailwindcss/typography";

@source '../../vendor/happytodev/blogr/resources/views/**/*.blade.php';
@source '../views/vendor/blogr/**/*.blade.php';

@variant dark (.dark &);

4. Register BlogrPlugin

Edit app/Providers/Filament/AdminPanelProvider.php:

use Happytodev\Blogr\BlogrPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([BlogrPlugin::make()])
        ->profile(\Happytodev\Blogr\Filament\Pages\Auth\EditProfile::class);
}

5. Build assets

npm run build

First Steps

After installation:

  1. Access admin panel: /admin
  2. Create your first post: Admin β†’ Blog Posts β†’ New
  3. Configure settings: Admin β†’ Blogr Settings
  4. View your blog: /blog (or your configured prefix)

πŸ“š Documentation

Configuration

All settings are manageable via the admin panel Settings page or config/blogr.php:

Key Configuration Options
// config/blogr.php

// Route configuration
'route' => [
    'prefix' => 'blog', // Change to '' for homepage
    'middleware' => ['web'],
],

// Multilingual
'locales' => [
    'enabled' => true,
    'default' => 'en',
    'available' => ['en', 'fr', 'es', 'de'],
],

// SEO
'seo' => [
    'site_name' => 'My Blog',
    'default_title' => 'Blog',
    'og' => [
        'image' => '/images/og-default.jpg',
        'image_width' => 1200,
        'image_height' => 630,
    ],
],

// Theming
'colors' => [
    'primary' => '#FA2C36',
],

// Posts per page
'posts_per_page' => 10,

Core Concepts

πŸ“ Blog Posts & Translations

Creating Posts:

  • Markdown editor with live preview
  • TL;DR summaries
  • Custom slugs
  • Featured images (drag & drop)
  • Categories & tags
  • Publication scheduling

Translations:

  • Add translations via Repeater in admin
  • Each translation has independent:
    • Title, slug, content
    • SEO meta tags
    • Categories & tags
  • Automatic language detection
πŸ“š Blog Series

Setup:

  1. Create series: Admin β†’ Blog Series β†’ New
  2. Add translations (title, description, SEO)
  3. Assign posts to series with position ordering

Frontend Components:

{{-- Series navigation (prev/next) --}}
<x-blogr::series-navigation :post="$post" />

{{-- Complete series list --}}
<x-blogr::series-list :series="$series" :currentPost="$post" />

{{-- Series badge --}}
<x-blogr::series-badge :post="$post" />

URL: /blog/series/{slug}

πŸ“„ CMS Page Builder

Enable CMS:

// config/blogr.php
'cms' => [
    'enabled' => true,
    'prefix' => '', // Leave empty for /about, or set to 'page' for /page/about
],

Create Static Pages:

  1. Admin β†’ CMS β†’ Pages CMS β†’ New
  2. Set slug (e.g., about, contact)
  3. Choose template:
    • Default: Standard page with sidebar
    • Full Width: Wide content area
    • Sidebar Left/Right: Custom layouts
  4. Add translations (title, content, SEO)
  5. Publish the page

Block System:

Build pages using pre-designed blocks:

// Available blocks
- Hero Section (title, subtitle, CTA, background)
- Features Grid (icon, title, description)
- Testimonials (author, quote, avatar)
- Call-to-Action (button, background)
- Content Block (rich text, Markdown)
- Image Gallery
- Contact Form

Set as Homepage:

  1. Create a CMS page
  2. Toggle "Page d'accueil" (Homepage)
  3. Configure in config/blogr.php:
'homepage' => [
    'type' => 'cms', // 'blog' or 'cms'
],

Reserved Slugs: These slugs are protected and cannot be used:

  • blog, feed, author, category, tag, series
  • admin, login, logout, register, dashboard
  • api, assets, storage, vendor

URL Examples:

  • About page: /about or /en/about (with locales)
  • Contact: /contact or /fr/contact
  • Custom prefix: /page/about (if prefix = 'page')
🌍 Multilingual Setup

Enable in Settings:

  • Admin β†’ Blogr Settings β†’ Multilingual
  • Toggle "Enable Localized Routes"
  • Set default locale and available locales

URLs:

  • Enabled: /{locale}/blog/{slug} (e.g., /fr/blog/mon-article)
  • Disabled: /blog/{slug} (translation via relationships)

Components:

{{-- Language switcher --}}
<x-blogr::language-switcher 
    current-route="blog.show" 
    :route-parameters="['slug' => $post->slug]" 
/>

{{-- Hreflang SEO tags --}}
<x-blogr::hreflang-tags 
    current-route="blog.show" 
    :route-parameters="['slug' => $post->slug]" 
/>
πŸ’Ύ Backup & Import

Export Data:

  1. Admin β†’ Blogr Settings β†’ Backup tab
  2. Choose format (JSON or ZIP with media)
  3. Download backup file

Import Data:

php artisan blogr:import backup.zip

What's included:

  • Posts, series, categories, tags
  • All translations
  • Media files (images, avatars)
  • Relationships preserved
πŸ‘€ Author Profiles

Self-Service Profile:

  • Click user avatar β†’ Edit Profile
  • Upload avatar (auto-cropped)
  • Write bio (Markdown supported)
  • Update password

Author Bio Component:

{{-- Full bio box --}}
<x-blogr::author-bio :author="$post->user" />

{{-- Compact inline --}}
<x-blogr::author-bio :author="$post->user" :compact="true" />

Configuration:

'author_profile' => ['enabled' => true],
'author_bio' => [
    'enabled' => true,
    'position' => 'bottom', // top, bottom, both
    'compact' => false,
],

Advanced Features

πŸ” SEO Configuration

Per-Post SEO:

  • Meta title & description
  • Keywords
  • Custom OG image
  • Auto-generated Schema.org markup

Global SEO:

'seo' => [
    'site_name' => env('APP_NAME'),
    'default_title' => 'Blog',
    'twitter_handle' => '@yourhandle',
    'og' => [
        'type' => 'website',
        'image' => '/images/og-default.jpg',
    ],
    'structured_data' => [
        'enabled' => true,
        'organization' => [
            'name' => 'My Blog',
            'logo' => 'https://yoursite.com/logo.png',
        ],
    ],
],
πŸ“Š RSS Feeds

Available Feeds:

  • Main: /{locale}/blog/feed
  • Category: /{locale}/blog/feed/category/{slug}
  • Tag: /{locale}/blog/feed/tag/{slug}

Configuration:

'rss' => [
    'enabled' => true,
    'limit' => 20,
    'cache_ttl' => 3600, // 1 hour
],
🎨 Theming

CSS Variables:

:root {
    --blogr-primary: #FA2C36;
    --blogr-category: #3B82F6;
    --blogr-tag: #10B981;
}

Dark Mode:

  • Auto-detection via system preference
  • Manual toggle (light/dark/auto)
  • Configured via Alpine.js component

Customization Points:

  • Card colors & borders
  • TOC positioning (center, left, right sidebar)
  • Publication date display
  • Tag positioning (top/bottom)
  • Heading permalinks (symbol, spacing, visibility)

πŸ§ͺ Testing

Blogr is battle-tested with 680+ tests and 1900+ assertions:

cd vendor/happytodev/blogr
./vendor/bin/pest --parallel

# Test coverage
Tests:  57 skipped, 645 passed (1866 assertions)

Test Coverage:

  • βœ… Import/Export with media files
  • βœ… Multilingual translations
  • βœ… Blog series relationships
  • βœ… SEO meta tags & Schema.org
  • βœ… Author profiles & permissions
  • βœ… RSS feed generation
  • βœ… Database schema integrity

πŸ—ΊοΈ Roadmap

🎯 RC1 (November 2025)

  • Import/Export system with media backup
  • CMS Page Builder – Create static pages (About, Contact, etc.) with block system ✨ NEW
  • Clickable titles in RecentBlogPosts widget
  • Public blog link in admin panel
  • Theme presets (predefined color schemes)
  • Enhanced tables (sortable, filterable)
  • Writer notifications for admins
  • Comprehensive testing for v1 release

βœ… Beta 3 (Completed - September 2025)

  • Full multilingual support
  • Blog series feature
  • Writer role with permissions
  • RSS feeds (global, category, tag)
  • Configurable TOC positioning
  • Theme system with dark mode
  • Author profiles & bios
  • Customizable permalinks
  • Language switcher component
  • Footer & navigation settings

βœ… Beta 2 (Completed - September 2025)

  • SEO fields (meta, OG, Schema.org)
  • Scheduled publishing
  • Quick publish toggle
  • Auto-generated TOC
  • Reading time calculation
  • Dashboard widgets
  • Settings page with tabs
  • Tutorial content seeder

🀝 Support

Need Help?

πŸ“– Full Documentation β€’ πŸ› Report Bug β€’ πŸ’‘ Request Feature

Love Blogr?

If this package saves you time, consider:

GitHub Sponsors Star on GitHub

πŸ“„ License

MIT License – See LICENSE.md for details.

πŸ‘ Credits

Created with ❀️ by Frédéric Blanc

Contributors:

Special Thanks:

  • FilamentPHP team for the amazing framework
  • Laravel community for continuous inspiration
  • All users providing feedback and bug reports

⬆ Back to Top

Made with ❀️ using Laravel & FilamentPHP