Weave Code
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

Ink Laravel Package

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.

View on GitHub
Deep Wiki
Context7

title: Tags Taxonomy description: Opt-in many-to-many tags taxonomy with admin UI and public archive. navigation: icon: i-lucide-hash

Tags are an opt-in feature — the schema ships with every install but the admin UI, form field, and public archive only appear when features.tags is on.

Enable

'features' => [
    'tags' => true,
],

That single flag activates:

  • TagResource in the Filament admin (Blog group, after Categories)
  • Multi-select tags field on the Post create/edit form (with inline create)
  • Public archive route at /blog/tag/{slug} (when public_routes is also on)
  • Post::tags() relation always exists; without the flag the table is just empty

Schema

Two tables, both shipped via the package's discovered migrations:

blog_tags                blog_post_tag (pivot)
─────────────            ───────────────
id                       post_id  → blog_posts.id (cascade)
name                     tag_id   → blog_tags.id  (cascade)
slug (unique)            created_at
deleted_at               updated_at
created_at               primary (post_id, tag_id)
updated_at               index   (tag_id)

Soft deletes are enabled on blog_tags. Pivot rows cascade-delete when a post or tag is force-deleted.

Model

Relaticle\Ink\Models\Tag:

$tag = Tag::factory()->create(['name' => 'Laravel']);
$tag->slug;     // "laravel" — auto-generated, frozen on rename
$tag->posts;    // BelongsToMany<Post>

The slug is stable — renaming a tag preserves its slug (and existing URLs).

Attaching tags to posts

use Relaticle\Ink\Models\Post;
use Relaticle\Ink\Models\Tag;

$post = Post::find($id);
$tag = Tag::firstOrCreate(['name' => 'Laravel']);

$post->tags()->attach($tag);              // single
$post->tags()->sync([$tagA->id, $tagB->id]); // replace set
$post->tags()->detach($tag);              // remove one

In the Filament admin, the multi-select tags field handles this for you — and supports inline create:

Select::make('tags')
    ->relationship('tags', 'name')
    ->multiple()
    ->searchable()
    ->preload()
    ->createOptionForm([
        TextInput::make('name')->required(),
    ]);

Public archive

When both features.public_routes and features.tags are on, the route /blog/tag/{slug} lists published posts for that tag:

// auto-registered by the package
Route::get('/tag/{slug}', [BlogController::class, 'tag'])->name('blog.tag');

The shipped view at resources/views/vendor/blog/pages/tag.blade.php uses the <x-ink::post-card> component. Publish and edit it to customize.

Disabling tags after enabling

Flip the flag back to false and the admin UI + archive route disappear. Existing data stays in the tables — uninstall fully via:

php artisan migrate:rollback --path=vendor/relaticle/ink/database/migrations

Related-posts behavior

Post::relatedPosts() currently uses category matching, not tags. If you want tag-based relations, override it in your own model that extends the package's Post:

public function relatedPosts(int $limit = 3): Builder
{
    $tagIds = $this->tags()->pluck('blog_tags.id');

    return static::query()
        ->published()
        ->where('id', '!=', $this->getKey())
        ->whereHas('tags', fn ($q) => $q->whereIn('blog_tags.id', $tagIds))
        ->latest('published_at')
        ->limit($limit);
}
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity