Installation
composer require antwebes/metadata-bundle
Register the bundle in config/bundles.php:
return [
// ...
Antwebes\MetadataBundle\MetadataBundle::class => ['all' => true],
];
Basic Configuration Publish the default config:
php artisan vendor:publish --tag=metadata-config
Edit config/metadata.php to define your metadata sources (e.g., database, API, or static data).
First Use Case: Fetching Metadata
Inject the MetadataService into a controller or service:
use Antwebes\MetadataBundle\Service\MetadataService;
public function __construct(private MetadataService $metadataService) {}
public function showPageContent()
{
$metadata = $this->metadataService->get('page_title');
return view('page', ['title' => $metadata]);
}
Defining Metadata Sources
Configure sources in config/metadata.php:
'sources' => [
'database' => [
'driver' => 'database',
'query' => 'SELECT title FROM pages WHERE id = :id',
'params' => ['id' => 1],
],
'api' => [
'driver' => 'http',
'url' => 'https://api.example.com/metadata',
'method' => 'GET',
],
'static' => [
'driver' => 'static',
'data' => ['description' => 'Default page description'],
],
],
Fetching Metadata
Use the MetadataService to retrieve data:
// Single key
$title = $this->metadataService->get('page_title');
// Multiple keys (returns associative array)
$data = $this->metadataService->get(['title', 'description']);
// Fallback to default if key not found
$author = $this->metadataService->get('author', 'Unknown Author');
Dynamic Metadata (e.g., Route-Based)
Bind metadata to routes in routes/web.php:
Route::get('/blog/{slug}', function ($slug) {
$metadata = app('metadata')->get(['title', 'excerpt'], ['slug' => $slug]);
return view('blog.post', $metadata);
})->name('blog.post');
Caching Strategies Enable caching in config:
'cache' => [
'enabled' => true,
'ttl' => 3600, // 1 hour
],
Clear cache manually:
php artisan metadata:clear-cache
Integration with Blade
Share metadata globally in AppServiceProvider:
public function boot()
{
View::share('metadata', $this->metadataService->getAll());
}
Use in Blade:
<title>{{ $metadata['page_title'] ?? 'Default Title' }}</title>
Driver Configuration Errors
driver keys in config/metadata.php match registered drivers (e.g., database, http, static).src/Service/Drivers/ or extend the bundle (see below).Caching Issues
Missing Dependencies
database driver requires doctrine/dbal or illuminate/database.composer require doctrine/dbal
Static Data Overrides
HTTP Driver Timeouts
config/metadata.php:
'http' => [
'timeout' => 5, // seconds
],
Log Metadata Sources: Enable debug mode in config:
'debug' => true,
Check logs for resolved metadata (e.g., storage/logs/laravel.log).
Validate Config:
Use the metadata:validate artisan command:
php artisan metadata:validate
Override Drivers:
Extend the bundle by creating custom drivers in app/Service/Drivers/. Example:
namespace App\Service\Drivers;
use Antwebes\MetadataBundle\Service\DriverInterface;
class CustomDriver implements DriverInterface
{
public function fetch($key, array $params = [])
{
return "Custom data for {$key}";
}
}
Register in config/metadata.php:
'drivers' => [
'custom' => App\Service\Drivers\CustomDriver::class,
],
Custom Drivers:
Implement DriverInterface for new data sources (e.g., Redis, Elasticsearch).
Middleware for Metadata: Create middleware to inject metadata into requests:
namespace App\Http\Middleware;
use Antwebes\MetadataBundle\Service\MetadataService;
class InjectMetadata
{
public function __construct(private MetadataService $metadata) {}
public function handle($request, Closure $next)
{
$request->merge($this->metadata->getAll());
return $next($request);
}
}
Event Listeners:
Listen for metadata events (e.g., Metadata.Fetched) to log or transform data:
use Antwebes\MetadataBundle\Events\MetadataFetched;
MetadataFetched::listen(function (MetadataFetched $event) {
\Log::debug('Metadata fetched:', $event->data);
});
Testing:
Mock the MetadataService in tests:
$this->mock(MetadataService::class)
->shouldReceive('get')
->with('page_title')
->andReturn('Test Title');
How can I help you explore Laravel packages today?