philetaylor/gravatar-bundle
A Symfony bundle for integrating Gravatar avatars into your application. It provides Twig helpers to generate Gravatar URLs with configurable size, rating, and default image settings, making it easy to display consistent user profile images across your site. Simple installation and configuration.
This is a Symfony bundle, not a Laravel package. There is no GravatarServiceProvider, no facade, and Laravel's package discovery will not register it. Treat it as a reference implementation, not a dependency you composer require into a Laravel app.
Minimal steps if you want to inspect it:
composer require --dev philetaylor/gravatar-bundle
Then read two files first:
gravatar(...) helper) — this shows the exact parameter mapping.The package is tiny; the whole behaviour is "normalise email → md5 → append s, r, d query params to https://www.gravatar.com/avatar/{hash}". You can reimplement it in a Laravel app in ~20 lines.
First use case in Laravel: a user avatar fallback in a Blade partial.
// app/Support/Gravatar.php
class Gravatar
{
public function url(?string $email, array $overrides = []): string
{
$hash = md5(strtolower(trim((string) $email)));
$params = array_merge([
's' => config('gravatar.size', 80),
'r' => config('gravatar.rating', 'g'),
'd' => config('gravatar.default', 'mp'),
], $overrides);
return "https://www.gravatar.com/avatar/{$hash}?".http_build_query($params);
}
}
<img src="{{ app(\App\Support\Gravatar::class)->url($user->email) }}"
width="80" height="80" alt="{{ $user->name }}">
That is the entire day-to-day surface area of this bundle.
Config-driven defaults. Mirror the bundle's Symfony config with a Laravel config file so environments can override size/rating/default without touching code:
// config/gravatar.php
return [
'size' => env('GRAVATAR_SIZE', 80),
'rating' => env('GRAVATAR_RATING', 'g'),
'default' => env('GRAVATAR_DEFAULT', 'mp'),
'secure' => true,
];
Model accessor. Don't call the service from views directly; expose it from the model so every avatar is consistent:
public function getAvatarAttribute(): string
{
return app(Gravatar::class)->url($this->email);
}
// $user->avatar
Blade component / directive. Wrap the <img> tag once:
{{-- resources/views/components/avatar.blade.php --}}
@props(['user', 'size' => 80])
<img src="{{ app(\App\Support\Gravatar::class)->url($user->email, ['s' => $size]) }}"
width="{{ $size }}" height="{{ $size }}"
alt="{{ $user->name }}" loading="lazy">
Parameter overrides. The bundle exposes size/rating/default per call; keep that flexibility, since you'll want large avatars on profile pages and small ones in comment lists.
$gravatar->url($email, ['s' => 200, 'd' => 'identicon']);
Integration with existing auth. If your users table already has an avatar_path column, resolve it first and fall back to Gravatar:
return $user->avatar_path
? Storage::url($user->avatar_path)
: app(Gravatar::class)->url($user->email);
Testing. Because it's pure URL construction, no HTTP call is made. Assert the hash and query string in a unit test; there's nothing to mock.
$this->assertSame(
'https://www.gravatar.com/avatar/'.md5('[email protected]').'?s=80&r=g&d=mp',
app(Gravatar::class)->url('[email protected] ')
);
When you actually need the Symfony bundle. Only if you maintain a Symfony app too. Register it in config/bundles.php, configure it under config/packages/, and use the Twig helper or inject the service. The Laravel-side logic above ports cleanly from the same parameter semantics. Note that 7.0.0.x targets Symfony 7.1+ (see below), so it is not usable on a legacy Symfony 5/6 app.
composer.json expecting auto-wiring; vendor risk (2 stars, 0 dependents) is high for a package whose logic is a one-liner.Symfony\Component\HttpKernel\DependencyInjection\Extension to Symfony\Component\DependencyInjection\Extension\Extension, to get ahead of a deprecation slated for Symfony 8.1. No new Gravatar parameters, no new features, no Laravel-facing surface. If you already ported the twenty lines, there is nothing to port again; the URL the bundle generates is byte-for-byte identical.composer update this in a Symfony/Laravel hybrid repo blindly. The base-class swap requires symfony/dependency-injection at a version that exposes Symfony\Component\DependencyInjection\Extension\Extension as non-internal; if you pinned Symfony 7.0 and your composer.json allows the bundle to float, Composer may resolve to a combination that is untested. Pin or bump the Symfony constraint deliberately.md5(strtolower(trim($email))) — Gravatar hashes are case-sensitive. A trailing space or mixed case silently returns the default image instead of the user's avatar. This is the #1 source of "my avatar doesn't work" bugs.src. The hash is not a secret but the email is.d is not always a preset. It accepts mp, identicon, monsterid, wavatar, retro, robohash, 404, or a fully URL-encoded absolute URL to your own fallback image. 404 means Gravatar returns HTTP 404 — you must handle a broken <img>.s is clamped to 1–2048. Passing s=5000 won't error, it just caps. Pass integers, not strings with units.r is the content rating, not "resolution": g, pg, r, x. Keep it g unless you have a reason; users can upload anything.https://www.gravatar.com/avatar/. The old http://gravatar.com/avatar/ and secure.gravatar.com variants cause mixed-content warnings or extra redirects.f=y forces the default image even when the user has a real avatar — useful for testing fallbacks, easy to ship by accident.gravatar.com leaks an md5 of the user's email to Automattic. If that's a concern, proxy avatars through your own route, or switch to a locally generated identicon. This bundle has no proxy support, so you'd be building that anyway.Gravatar class or interface in a service provider instead; that's the Laravel-native equivalent.How can I help you explore Laravel packages today?