Installation:
composer require reddatas/placeholder-image
The package auto-registers via Laravel’s service provider discovery.
First Use Case: Generate a placeholder image for missing avatars or product thumbnails by visiting:
/placeholder/200/200/User%20Name/eeeeee/333333
(URL-encoded text: User Name → User%20Name)
Where to Look First:
routes/web.php for the auto-registered route (placeholder/{width}/{height?}/{text?}/{bgColor?}/{textColor?}).vendor/reddatas/placeholder-image/src/ for core logic (e.g., PlaceholderImageService.php).Dynamic Placeholders in Views:
// Blade template for user avatars
<img src="{{ route('placeholder', [
'width' => 100,
'height' => 100,
'text' => auth()->user()->name ?? 'Guest',
'bgColor' => 'f0f0f0',
'textColor' => '333'
]) }}" alt="Avatar">
Str::of($user->name)->slug('-')) to avoid regenerating for the same user.API Responses: Return placeholder URLs in JSON:
return response()->json([
'image_url' => route('placeholder', [
'width' => 800,
'height' => 600,
'text' => 'Product Image',
]),
]);
Fallback for Missing Images:
// In a controller or service
public function getImageUrl($entity, $defaultText = 'No Image') {
return route('placeholder', [
'width' => 300,
'height' => 300,
'text' => $entity->name ?? $defaultText,
]);
}
Image Optimization:
Combine with Laravel’s Image facade to resize placeholders before serving:
use Intervention\Image\Facades\Image;
$img = Image::make(public_path('placeholder.png'));
$img->resize(400, 400)->save();
(Note: This requires manual handling since the package generates images on-the-fly via HTTP.)
Localization: Override text defaults in a middleware:
public function handle($request, Closure $next) {
if ($request->routeIs('placeholder') && $request->text === null) {
$request->merge(['text' => __('messages.placeholder_text')]);
}
return $next($request);
}
Caching:
Use Laravel’s cache to store generated images (e.g., Cache::remember()) to reduce server load for repeated requests.
$cacheKey = "placeholder_{$width}_{$height}_{$text}";
return Cache::remember($cacheKey, now()->addHours(1), function() use ($width, $height, $text) {
return route('placeholder', compact('width', 'height', 'text'));
});
Testing: Mock the route in PHPUnit:
$response = $this->get('/placeholder/100/100/Test');
$response->assertStatus(200);
$response->assertHeader('Content-Type', 'image/png');
URL Encoding:
text (e.g., Hello World) break the URL unless encoded.$text = urlencode('Hello World');
route('placeholder', ['text' => $text]);
Str::of($text)->replace(' ', '-') for slug-like placeholders.Color Format:
333 or 333333). Shorthand like #abc or RGB values (rgb(0,0,0)) are unsupported.$bgColor = preg_match('/^#[0-9a-f]{3,6}$|^[0-9a-f]{3,6}$/i', $bgColor)
? $bgColor
: 'cccccc'; // Default fallback
No Height Provided:
width === height).height is omitted. Always specify height for non-square images.Performance:
Cache::forever() for static placeholders).No Configuration:
Content-Type header in the response. If it’s not image/png, the image generation failed.
curl -I http://your-app.test/placeholder/100/100
try {
$image = file_get_contents(route('placeholder', [...]));
} catch (\Exception $e) {
Log::error("Placeholder generation failed: " . $e->getMessage());
}
Custom Fonts:
Override the PlaceholderImageService to load a custom font:
// In a service provider
$this->app->bind('Reddatas\PlaceholderImage\PlaceholderImageService', function () {
$service = new \Reddatas\PlaceholderImage\PlaceholderImageService();
$service->setFont(public_path('fonts/custom.ttf'));
return $service;
});
Add Parameters:
Extend the route to support additional options (e.g., borderColor):
// In a custom service
public function generate($width, $height, $text, $bgColor, $textColor, $borderColor = null) {
// Implement border logic
}
Update the route in routes/web.php:
Route::get('/placeholder/{width}/{height?}/{text?}/{bgColor?}/{textColor?}/{borderColor?}', [PlaceholderController::class, 'show']);
Output Formats: Modify the service to support JPEG/WebP:
// In PlaceholderImageService.php
public function getImage($width, $height, $format = 'png') {
switch ($format) {
case 'jpg':
return $this->generateJpeg($width, $height);
case 'webp':
return $this->generateWebP($width, $height);
default:
return $this->generatePng($width, $height);
}
}
Update the route to accept a format parameter.
No Config File:
All settings (e.g., default colors, font) are in PlaceholderImageService.php. To change them:
config/ after installation).config('placeholder.default_bg')).Default Values: Hardcoded defaults:
// In PlaceholderImageService.php
private $defaultBgColor = 'cccccc';
private $defaultTextColor = '333333';
private $defaultText = 'Placeholder';
Override them by extending the class or using dependency injection.
How can I help you explore Laravel packages today?