relaticle/ink
Filament-native content publishing for Laravel: Eloquent models, full admin for posts/categories, SEO + JSON-LD, RSS, search, Blade UI components, and 13 MCP tools for AI agents. Headless by default with optional public blog routes.
Widens the spatie/laravel-sluggable constraint to ^3.0 || ^4.0.
Ink's models use only the HasSlug trait and getSlugOptions()/SlugOptions, all unchanged in sluggable v4. The single breaking change in v4 moved otherRecordExistsWithSlug() out of HasSlug into GenerateSlugAction; Ink overrides neither, so it is unaffected.
The previous ^3.0 pin made Ink uninstallable in any host app that had already upgraded to sluggable v4. No code changes — existing v3 users are unaffected.
Full Changelog: https://github.com/relaticle/ink/compare/v2.1.0...v2.1.1
First feature release on the new namespace. Two real bug fixes and seven new features, no breaking changes.
BlogSitemapGenerator documented /blog/tag/{slug} as a first-class route but only iterated categories + posts. Now iterates tags too, gated by Route::has('blog.tag') + config('ink.features.tags')./blog?page=2, /blog/category/X?page=2, and /blog/tag/X?page=2 was telling Google "this is a duplicate of page 1." Now each page carries its own canonical and a — Page N title suffix.show and preview routes didn't call seo()->for(\$post) — BlogPosting + BreadcrumbList only worked for consumers who overrode the controller.FAQPage JSON-LD auto-detected from ## FAQ H2 + ### Question? / answer paragraphs. Default on; disable via config('ink.schema.faq_auto', false).HowTo JSON-LD auto-detected from ## Steps H2 + ### Step Name / paragraphs. Opt-in via config('ink.schema.howto_auto', true).Blog + CollectionPage JSON-LD on /blog, /blog/category/{slug}, /blog/tag/{slug}.Relaticle\Ink\Support\SchemaExtractor — pure helper for FAQ + HowTo HTML parsing.Relaticle\Ink\Support\BlogListingSeo — forIndex/forCategory/forTag factories for headless consumers. Used internally by the shipped controllers.ink::pagination.blog. Replaces Laravel's default tailwind paginator on the shipped listing pages. Publish via --tag=ink-views to customize.wire:navigate on <x-ink::post-card> for SPA-feel navigation in Livewire 4 hosts.Post::search(\$term) scope — portable LIKE search across title/excerpt/content. Empty terms are no-ops. LIKE wildcards in the term are escaped.config('ink.search.callback') to a function (Builder \$query, string \$term): void to use Postgres FTS, MySQL FULLTEXT, Scout, Meilisearch, etc.?q= honored on the shipped /blog route with noindex,follow on result URLs (search queries should not be indexed as separate pages).<livewire:blog::search /> — drop-in Livewire component with URL-synced query, 400ms debounce, and empty state. Theme-agnostic.Three new pages: search.md, schema.md, listing-seo.md. Configuration + blade-components pages updated for the new config keys and components.
```bash composer require relaticle/ink:^2.1 ```
No breaking changes vs v2.0.0. Consumers on the previous manukminasyan/filament-blog v1.x should follow the v2.0.0 release notes first.
23 → 58 tests (+35, +152%). 118 assertions. All passing.
First release under the new namespace. This package was renamed from manukminasyan/filament-blog to relaticle/ink.
| Before | After |
|---|---|
manukminasyan/filament-blog |
relaticle/ink |
ManukMinasyan\FilamentBlog\ |
Relaticle\Ink\ |
FilamentBlogServiceProvider |
InkServiceProvider |
FilamentBlogPlugin |
InkPlugin |
config/filament-blog.php |
config/ink.php |
config('filament-blog.X') |
config('ink.X') |
<x-blog::post-card> etc. |
<x-ink::post-card> etc. |
view('blog::pages.show') |
view('ink::pages.show') |
--tag=filament-blog-{config,views,migrations,translations} |
--tag=ink-* |
blog_posts, blog_categories, blog_tags, blog_post_tag — no data migrationblog.index, blog.show, blog.category, blog.preview, blog.feed, blog.tag/blog (configurable via config('ink.prefix'))composer remove manukminasyan/filament-blog
composer require relaticle/ink:^2.0
See UPGRADING.md for the consumer-side sed recipe.
/ink/)Phase 2 of the strategy from .context/blog-package-comparison.md.
features.tags)blog_tags table + blog_post_tag pivotTag model with HasSlug + SoftDeletesTagResource admin UI (full CRUD, hidden from nav when feature off)Post::tags() belongsToMany relationPostResource form (with inline create)/blog/tag/{slug}features.media_library)SpatieMediaLibraryFileUpload used for featured image when both features.media_library is on AND the Spatie class existsFileUpload otherwise — no hard dep, no crashAll flags default to false. Existing installs unaffected.
23 tests / 39 assertions, including 9 new tag-related tests.
PR: #3
Phase 1 of the Tapix/FilaForms drop-in replacement work.
features.public_routes config flag) — /blog, /blog/{slug}, /blog/category/{slug}, signed /blog/preview/{post}features.feed) — /blog/feed returning RSS 2.0'layout' => 'layouts.app') for page views to extendPost::readingTime() and Post::relatedPosts() helpersAll flags default to false. Existing installs see zero behavior change. Upgrading is a no-op until the host opts in.
PR: #2
illuminate/contracts constraint widened to ^12.0|^13.0. No source changes; the package uses no Laravel-13-breaking APIs.composer require manukminasyan/filament-blog now installs cleanly.How can I help you explore Laravel packages today?