Skip to content

Commit

Permalink
feat: add favicon support (#53)
Browse files Browse the repository at this point in the history
* refactor image variants

* add favicon setting

* use favicon in views

* cleanup
  • Loading branch information
andreiio authored Sep 26, 2022
1 parent 7f3fbd5 commit b7d2a82
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 35 deletions.
10 changes: 8 additions & 2 deletions app/Http/Controllers/Admin/SettingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
use Intervention\Image\Image;

class SettingController extends Controller
{
Expand Down Expand Up @@ -48,8 +49,13 @@ public function store(string $section, SettingRequest $request): RedirectRespons
$settings = match ($section) {
'site' => $attributes->map(
fn ($value, $key) => match ($key) {
default => $value,
'logo' => $value?->storePubliclyAs('assets', 'logo.' . $value?->extension()),
default => $value,
'logo' => $value?->storePubliclyAs('assets', 'logo.' . $value?->extension()),
'favicon' => $value
?->manipulate(function (Image $image) {
$image->fit(48, 48)->encode('png');
})
->storePubliclyAs('assets', 'favicon.' . $value?->extension()),
}
),
'donations' => $attributes->map(
Expand Down
3 changes: 1 addition & 2 deletions app/Http/Middleware/Front/SetSeoDefaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ public function handle(Request $request, Closure $next)
default: $title,
modifier: fn (string $title) => $title . '' . localized_settings('site.title')
)
->description(default: $description)
->favicon();
->description(default: $description);

return $next($request);
}
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Requests/Admin/SettingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public function rules(): array
$rules = [
'settings.title' => ['array'],
'settings.description' => ['array'],
'settings.logo' => ['nullable', 'image'],
'settings.logo' => ['nullable', 'image', 'mimes:jpg,png,gif,svg'],
'settings.favicon' => ['nullable', 'image', 'mimes:jpg,png,gif', 'dimensions:min_width=32,max_width=1000'],
'settings.default_locale' => ['required', 'exists:languages,code'],
'settings.front_page' => ['required', 'exists:pages,id'],
'settings.privacy_page' => ['required', 'exists:pages,id'],
Expand Down
1 change: 1 addition & 0 deletions app/Models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ protected static function defaults(): Collection
'privacy_page' => null,
'terms_page' => null,
'logo' => null,
'favicon' => null,
'html' => [
'header' => null,
'footer' => null,
Expand Down
55 changes: 31 additions & 24 deletions app/Providers/MediaServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,58 @@

namespace App\Providers;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Intervention\Image\Constraint;
use Intervention\Image\Facades\Image as ImageFacade;
use Intervention\Image\Image;
use Plank\Mediable\Facades\ImageManipulator;
use Plank\Mediable\ImageManipulation;

class MediaServiceProvider extends ServiceProvider
{
/**
* Register any application services.
* Bootstrap any application services.
*
* @return void
*/
public function register()
public function boot()
{
//
$this->registerMacros();

$this->imageVariants()
->each(function (ImageManipulation $manipulation, string $name) {
ImageManipulator::defineVariant($name, $manipulation);
});
}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
protected function registerMacros(): void
{
$this->registerImageVariants();
UploadedFile::macro('manipulate', function (callable $callback) {
return tap($this, function (UploadedFile $file) use ($callback) {
$image = ImageFacade::make($file->getPathname());

$callback($image);

$image->save();
});
});
}

protected function registerImageVariants(): void
protected function imageVariants(): Collection
{
ImageManipulator::defineVariant(
'thumb',
ImageManipulation::make(function (Image $image) {
$image->resize(256, 256, function ($constraint) {
return collect([
'thumb' => ImageManipulation::make(function (Image $image) {
$image->resize(256, 256, function (Constraint $constraint) {
$constraint->aspectRatio();
});
})
);

ImageManipulator::defineVariant(
'600',
ImageManipulation::make(function (Image $image) {
$image->resize(600, 600, function ($constraint) {
}),
'600' => ImageManipulation::make(function (Image $image) {
$image->resize(600, 600, function (Constraint $constraint) {
$constraint->aspectRatio();
});
})
);
}),
]);
}
}
10 changes: 10 additions & 0 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Services\Features;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

if (! function_exists('locales')) {
Expand Down Expand Up @@ -146,3 +147,12 @@ function is_external_site(): bool
return ! is_internal_site();
}
}

if (! function_exists('favicon_url')) {
function favicon_url(): string
{
return settings('site.favicon')
? Storage::url(settings('site.favicon'))
: asset(mix('assets/images/favicon.png'));
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"guzzlehttp/guzzle": "^7.5",
"htmlmin/htmlmin": "^9.0",
"inertiajs/inertia-laravel": "^0.6",
"intervention/image": "^2.7",
"kalnoy/nestedset": "^6.0",
"laravel/framework": "^9.30",
"laravel/tinker": "^2.7",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@
"field.url": "URL",
"field.uuid": "UUID",

"field_help.embed_url": "Add the link to the element you want to embed. Link format: https://www.youtube.com/watch?v=LrzDjOmQguE",
"field_help.empty_to_disable": "To remove the limit, empty this field.",
"field_help.favicon": "Allowed files: gif, jpg, png. Min 32x32px, max: 500x500px.",
"field_help.logo": "Allowed files: gif, jpg, png, svg",
"field_help.one_per_line": "Add one item per line.",
"field_help.paypal_button_id": "Generate a new button from your PayPal account",
"field_help.zero_to_disable": "To remove the limit, set this field to 0.",

"form.label": "Form|Forms",
"form.action.create": "Add form",
"form.action.edit": "Edit formu",
Expand Down Expand Up @@ -372,6 +380,7 @@
"setting.site.title": "Site title",
"setting.site.description": "Site description",
"setting.site.logo": "Logo",
"setting.site.favicon": "Favicon",
"setting.site.colors.primary": "Primary color",
"setting.site.html.header": "HTML code inserted before </head>",
"setting.site.html.footer": "HTML code inserted before </body>",
Expand Down
7 changes: 5 additions & 2 deletions lang/ro.json
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,11 @@
"field.uuid": "UUID",

"field_help.embed_url": "Adaugă linkul elementului pe care vrei să îl afișezi. Formă link: https://www.youtube.com/watch?v=LrzDjOmQguE",
"field_help.paypal_button_id": "Generează un buton nou din contul tău de PayPal",
"field_help.one_per_line": "Adaugă câte un item per rând.",
"field_help.empty_to_disable": "Pentru a dezactiva limita, șterge valoarea câmpului.",
"field_help.favicon": "Fișiere permise: gif, jpg, png. Min 32x32px, max: 500x500px.",
"field_help.logo": "Fișiere permise: gif, jpg, png, svg",
"field_help.one_per_line": "Adaugă câte un item per rând.",
"field_help.paypal_button_id": "Generează un buton nou din contul tău de PayPal",
"field_help.zero_to_disable": "Pentru a dezactiva limita, setează valoarea câmpului la 0.",

"form.label": "Formular|Formulare",
Expand Down Expand Up @@ -382,6 +384,7 @@
"setting.site.title": "Titlu site",
"setting.site.description": "Descriere site",
"setting.site.logo": "Logo",
"setting.site.favicon": "Favicon",
"setting.site.colors.primary": "Culoare principală",
"setting.site.html.header": "Cod HTML introdus înainte de </head>",
"setting.site.html.footer": "Cod HTML introdus înainte de </body>",
Expand Down
Empty file removed public/favicon.ico
Empty file.
1 change: 0 additions & 1 deletion resources/images/favicon.svg

This file was deleted.

9 changes: 9 additions & 0 deletions resources/js/pages/Settings/Site.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@
name="settings.logo"
v-model="form.settings.logo"
:accept="['.png', '.gif', '.jpg', '.jpeg', '.svg']"
:help="$t('field_help.logo')"
/>

<form-file
:label="$t('setting.site.favicon')"
name="settings.favicon"
v-model="form.settings.favicon"
:accept="['.png', '.gif', '.jpg', '.jpeg']"
:help="$t('field_help.favicon')"
/>
</panel>

Expand Down
3 changes: 1 addition & 2 deletions resources/views/admin.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
{{-- Scripts --}}
<script src="{{ asset(mix('assets/admin.js')) }}" defer></script>

<link rel="icon" type="image/svg+xml" href="{{ asset(mix('assets/images/favicon.svg')) }}">
<link rel="icon" type="image/png" href="{{ asset(mix('assets/images/favicon.png')) }}">
<link rel="icon" type="image/png" href="{{ favicon_url() }}">

@routes
</head>
Expand Down
2 changes: 2 additions & 0 deletions resources/views/components/site/meta.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@
@foreach (seo()->extensions() as $extension)
<x-dynamic-component :component="$extension" />
@endforeach

<link rel="icon" type="image/png" href="{{ favicon_url() }}">

0 comments on commit b7d2a82

Please sign in to comment.