augustpermana/laravel-meta-generator
Attach and manage key-value metadata for Eloquent models without altering main tables. Provides auto type detection and casting, a MetaModel base, and artisan commands to generate meta models and clean orphaned records for easy setup and maintenance.
Installation:
composer require augustpermana/laravel-meta-generator
Publish the config file:
php artisan vendor:publish --provider="Augustpermana\MetaGenerator\MetaGeneratorServiceProvider" --tag="config"
Basic Usage:
Define metadata for a model in its meta() method:
use Augustpermana\MetaGenerator\MetaGenerator;
class Post extends Model
{
public function meta()
{
return [
'title' => 'Default Post Title',
'description' => 'Default description',
'keywords' => ['laravel', 'meta', 'generator'],
];
}
}
First Use Case: Retrieve metadata for a model instance:
$post = Post::find(1);
$meta = MetaGenerator::get($post); // Returns ['title', 'description', 'keywords']
Use closures for dynamic metadata (e.g., SEO-friendly titles):
public function meta()
{
return [
'title' => function ($post) {
return "Read '{$post->title}' on {$this->app->make('App\Services\SiteNameService')}";
},
];
}
Define fallback metadata in config/meta-generator.php:
'fallbacks' => [
'title' => 'Default Site Title',
'description' => 'Default description for all pages',
],
Generate <meta> tags in views:
@foreach(MetaGenerator::get($post) as $name => $value)
<meta name="{{ $name }}" content="{{ $value }}">
@endforeach
Attach metadata to API responses (e.g., Laravel Sanctum):
use Augustpermana\MetaGenerator\MetaGenerator;
return response()->json([
'data' => $post,
'meta' => MetaGenerator::get($post),
]);
Update metadata on model events (e.g., updated):
protected static function boot()
{
static::updated(function ($model) {
$model->meta['last_updated'] = now()->toDateTimeString();
});
}
Caching Issues:
Overriding Defaults:
config/meta-generator.php are merged after model-specific metadata. Explicitly set null to override:
return ['title' => null]; // Disables fallback title
Nested Relationships:
with() to eager-load dependencies:
$post = Post::with('author')->find(1);
$meta = MetaGenerator::get($post); // Access $post->author if needed
\Log::debug('Post Meta', MetaGenerator::get($post));
php artisan config:clear if fallbacks aren’t applying.Custom Resolvers:
Extend the MetaGenerator class to add logic:
class CustomMetaGenerator extends MetaGenerator
{
public function get($model)
{
$meta = parent::get($model);
$meta['custom_field'] = $this->resolveCustomField($model);
return $meta;
}
}
Bind it in AppServiceProvider:
$this->app->bind(MetaGenerator::class, function ($app) {
return new CustomMetaGenerator($app);
});
Model Observers: Sync metadata with external services (e.g., Google Search Console):
class PostObserver
{
public function saved(Post $post)
{
$meta = MetaGenerator::get($post);
// Send to external API
}
}
Middleware: Inject metadata into the request or session:
public function handle($request, Closure $next)
{
$request->merge(['meta' => MetaGenerator::get($request->route('model'))]);
return $next($request);
}
How can I help you explore Laravel packages today?