Skip to content

Commit 7f534c8

Browse files
committed
Tags implementation
1 parent 5bbc75a commit 7f534c8

25 files changed

+933
-86
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
"require": {
1919
"php": "^8.2",
2020
"artesaos/seotools": "^1.3",
21+
"filament/spatie-laravel-tags-plugin": "^3.2",
22+
"guava/filament-icon-picker": "^2.0",
2123
"illuminate/contracts": "^10.0||^11.0||^12.0",
2224
"mcamara/laravel-localization": "^2.3",
2325
"spatie/laravel-missing-page-redirector": "^2.11",
2426
"spatie/laravel-package-tools": "^1.16",
25-
"statikbe/laravel-filament-flexible-content-blocks": "^2.4"
27+
"statikbe/laravel-filament-flexible-content-blocks": "dev-main"
2628
},
2729
"require-dev": {
2830
"laravel/pint": "^1.14",

config/filament-flexible-content-block-pages.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,29 @@
1515

1616
return [
1717
'models' => [
18-
'page' => \Statikbe\FilamentFlexibleContentBlockPages\Models\Page::class,
19-
'redirect' => \Statikbe\FilamentFlexibleContentBlockPages\Models\Redirect::class,
20-
'settings' => \Statikbe\FilamentFlexibleContentBlockPages\Models\Settings::class,
18+
FilamentFlexibleContentBlockPagesConfig::TYPE_PAGE => \Statikbe\FilamentFlexibleContentBlockPages\Models\Page::class,
19+
FilamentFlexibleContentBlockPagesConfig::TYPE_REDIRECT => \Statikbe\FilamentFlexibleContentBlockPages\Models\Redirect::class,
20+
FilamentFlexibleContentBlockPagesConfig::TYPE_SETTINGS => \Statikbe\FilamentFlexibleContentBlockPages\Models\Settings::class,
21+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG => \Statikbe\FilamentFlexibleContentBlockPages\Models\Tag::class,
22+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG_TYPE => \Statikbe\FilamentFlexibleContentBlockPages\Models\TagType::class,
2123
],
2224

2325
'table_names' => [
2426
FilamentFlexibleContentBlockPagesConfig::TYPE_PAGE => 'pages',
2527
FilamentFlexibleContentBlockPagesConfig::TYPE_AUTHOR => 'users',
2628
FilamentFlexibleContentBlockPagesConfig::TYPE_SETTINGS => 'settings',
2729
FilamentFlexibleContentBlockPagesConfig::TYPE_REDIRECT => 'redirects',
30+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG => 'tags',
31+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAGGABLE => 'taggables',
32+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG_TYPE => 'tag_types',
2833
],
2934

3035
'resources' => [
3136
FilamentFlexibleContentBlockPagesConfig::TYPE_PAGE => \Statikbe\FilamentFlexibleContentBlockPages\Resources\PageResource::class,
3237
FilamentFlexibleContentBlockPagesConfig::TYPE_SETTINGS => \Statikbe\FilamentFlexibleContentBlockPages\Resources\SettingsResource::class,
3338
FilamentFlexibleContentBlockPagesConfig::TYPE_REDIRECT => \Statikbe\FilamentFlexibleContentBlockPages\Resources\RedirectResource::class,
39+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG => \Statikbe\FilamentFlexibleContentBlockPages\Resources\TagResource::class,
40+
FilamentFlexibleContentBlockPagesConfig::TYPE_TAG_TYPE => \Statikbe\FilamentFlexibleContentBlockPages\Resources\TagTypeResource::class,
3441
],
3542

3643
'panel' => [
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
use Statikbe\FilamentFlexibleContentBlockPages\Facades\FilamentFlexibleContentBlockPages;
7+
8+
return new class extends Migration
9+
{
10+
public function up(): void
11+
{
12+
$tagTable = FilamentFlexibleContentBlockPages::config()->getTagsTable();
13+
$tagTypeTable = FilamentFlexibleContentBlockPages::config()->getTagTypesTable();
14+
$taggableTable = FilamentFlexibleContentBlockPages::config()->getTaggablesTable();
15+
16+
Schema::create($tagTypeTable, function (Blueprint $table) {
17+
$table->string('code')
18+
->primary();
19+
$table->json('name');
20+
$table->string('colour')
21+
->nullable();
22+
$table->string('icon')
23+
->nullable();
24+
$table->boolean('is_default_type')
25+
->default(false);
26+
$table->boolean('has_seo_pages')
27+
->default(false);
28+
$table->timestamps();
29+
});
30+
31+
Schema::create($tagTable, function (Blueprint $table) {
32+
$table->id();
33+
$table->json('name');
34+
$table->json('seo_description')->nullable();
35+
$table->json('slug');
36+
$table->string('type')->nullable();
37+
$table->foreign('type')
38+
->references('code')
39+
->on(FilamentFlexibleContentBlockPages::config()->getTagTypesTable())
40+
->cascadeOnDelete();
41+
$table->integer('order_column')->nullable();
42+
$table->timestamps();
43+
});
44+
45+
Schema::create($taggableTable, function (Blueprint $table) {
46+
$table->foreignIdFor(FilamentFlexibleContentBlockPages::config()->getTagModel())
47+
->constrained()
48+
->cascadeOnDelete();
49+
$table->morphs('taggable');
50+
$table->unique([FilamentFlexibleContentBlockPages::config()->getTagModel()->getForeignKey(), 'taggable_id', 'taggable_type']);
51+
});
52+
}
53+
54+
public function down(): void
55+
{
56+
Schema::dropIfExists(FilamentFlexibleContentBlockPages::config()->getTagsTable());
57+
Schema::dropIfExists(FilamentFlexibleContentBlockPages::config()->getTagTypesTable());
58+
Schema::dropIfExists(FilamentFlexibleContentBlockPages::config()->getTaggablesTable());
59+
}
60+
};

resources/lang/nl/filament-flexible-content-block-pages.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,20 @@
3636
'translatable_field_hint' => 'Dit veld kan vertaald worden. De huidige taal kan je rechtsbovenaan bekijken/aanpassen.',
3737
'settings_footer_copyright' => 'Copyrightboodschap in footer',
3838
],
39+
'form_component' => [
40+
'name_lbl' => 'Naam',
41+
'colour_lbl' => 'Kleur',
42+
'seo_description_lbl' => 'SEO-beschrijving',
43+
],
44+
'tag_types' => [
45+
'navigation_group' => 'Tags',
46+
'tag_type_plural_lbl' => 'Tagtypes',
47+
'tag_type_lbl' => 'Tagtype',
48+
'tag_type_is_default_type_lbl' => 'Is standaard tagtype',
49+
],
50+
'tags' => [
51+
'navigation_group' => 'Tags',
52+
'tag_type_plural_lbl' => 'Tags',
53+
'tag_type_lbl' => 'Tag',
54+
],
3955
];

src/Cache/TaggableCache.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Statikbe\FilamentFlexibleContentBlockPages\Cache;
4+
5+
use Closure;
6+
use Illuminate\Support\Facades\Cache;
7+
8+
class TaggableCache
9+
{
10+
public static function rememberForeverWithTag(string $tag, string $key, Closure $callback)
11+
{
12+
$cachedValue = Cache::rememberForever($key, $callback);
13+
14+
// add key to tag cache
15+
$keysWithTag = Cache::get($tag, []);
16+
$keysWithTag[] = $key;
17+
Cache::forever($tag, $keysWithTag);
18+
19+
return $cachedValue;
20+
}
21+
22+
public static function flushTag(string $tag)
23+
{
24+
Cache::forget($tag);
25+
}
26+
}

src/FilamentFlexibleContentBlockPagesConfig.php

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Statikbe\FilamentFlexibleContentBlockPages\Models\Page;
77
use Statikbe\FilamentFlexibleContentBlockPages\Models\Redirect;
88
use Statikbe\FilamentFlexibleContentBlockPages\Models\Settings;
9+
use Statikbe\FilamentFlexibleContentBlockPages\Models\Tag;
10+
use Statikbe\FilamentFlexibleContentBlockPages\Models\TagType;
911
use Statikbe\FilamentFlexibleContentBlockPages\Routes\Contracts\HandlesPageRoutes;
1012
use Statikbe\FilamentFlexibleContentBlockPages\Routes\LocalisedPageRouteHelper;
1113
use Statikbe\FilamentFlexibleContentBlocks\FilamentFlexibleContentBlocksServiceProvider;
@@ -20,19 +22,32 @@ class FilamentFlexibleContentBlockPagesConfig
2022

2123
const TYPE_AUTHOR = 'authors';
2224

25+
const TYPE_TAG = 'tags';
26+
27+
const TYPE_TAG_TYPE = 'tag_types';
28+
29+
const TYPE_TAGGABLE = 'taggables';
30+
2331
private string $pageModel;
2432

2533
private string $redirectModel;
2634

2735
private string $settingsModel;
2836

37+
private string $tagModel;
38+
39+
private string $tagTypeModel;
40+
2941
private HandlesPageRoutes $routeHelper;
3042

3143
public function __construct()
3244
{
33-
$this->pageModel = $this->packageConfig('models.page', Page::class);
34-
$this->redirectModel = $this->packageConfig('models.redirect', Redirect::class);
35-
$this->settingsModel = $this->packageConfig('models.settings', Settings::class);
45+
$this->pageModel = $this->packageConfig('models.'.static::TYPE_PAGE, Page::class);
46+
$this->redirectModel = $this->packageConfig('models.'.static::TYPE_REDIRECT, Redirect::class);
47+
$this->settingsModel = $this->packageConfig('models.'.static::TYPE_SETTINGS, Settings::class);
48+
$this->tagModel = $this->packageConfig('models.'.static::TYPE_TAG, Tag::class);
49+
$this->tagTypeModel = $this->packageConfig('models.'.static::TYPE_TAG_TYPE, TagType::class);
50+
3651
}
3752

3853
public function getSupportedLocales(): array
@@ -58,24 +73,49 @@ public function getSettingsModel(): Settings
5873
return app($this->settingsModel);
5974
}
6075

76+
public function getTagModel(): Tag
77+
{
78+
return app($this->tagModel);
79+
}
80+
81+
public function getTagTypeModel(): TagType
82+
{
83+
return app($this->tagTypeModel);
84+
}
85+
6186
public function getAuthorsTable(): string
6287
{
63-
return $this->packageConfig('table_names.authors', 'users');
88+
return $this->packageConfig('table_names.'.static::TYPE_AUTHOR, 'users');
6489
}
6590

6691
public function getPagesTable(): string
6792
{
68-
return $this->packageConfig('table_names.pages', 'pages');
93+
return $this->packageConfig('table_names.'.static::TYPE_PAGE, 'pages');
6994
}
7095

7196
public function getRedirectsTable(): string
7297
{
73-
return $this->packageConfig('table_names.redirects', 'redirects');
98+
return $this->packageConfig('table_names.'.static::TYPE_REDIRECT, 'redirects');
7499
}
75100

76101
public function getSettingsTable(): string
77102
{
78-
return $this->packageConfig('table_names.settings', 'settings');
103+
return $this->packageConfig('table_names.'.static::TYPE_SETTINGS, 'settings');
104+
}
105+
106+
public function getTagsTable(): string
107+
{
108+
return $this->packageConfig('table_names.'.static::TYPE_TAG, 'tags');
109+
}
110+
111+
public function getTagTypesTable(): string
112+
{
113+
return $this->packageConfig('table_names.'.static::TYPE_TAG_TYPE, 'tag_types');
114+
}
115+
116+
public function getTaggablesTable(): string
117+
{
118+
return $this->packageConfig('table_names.'.static::TYPE_TAGGABLE, 'taggables');
79119
}
80120

81121
/**

src/FilamentFlexibleContentBlockPagesServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public function configurePackage(Package $package): void
2525
'create_filament_flexible_content_block_pages_table',
2626
'create_filament_flexible_content_block_pages_redirects_table',
2727
'create_filament_flexible_content_block_pages_settings_table',
28+
'create_filament_flexible_content_block_tags_table',
2829
])
2930
->hasTranslations()
3031
->hasCommand(SeedDefaultsCommand::class)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Statikbe\FilamentFlexibleContentBlockPages\Form\Components;
4+
5+
use Filament\Forms\Components\RichEditor;
6+
use Statikbe\FilamentFlexibleContentBlocks\Filament\Form\Fields\Concerns\HasTranslatableHint;
7+
8+
class DescriptionField extends RichEditor
9+
{
10+
use HasTranslatableHint;
11+
12+
public static function create(string $field, bool $required = false): static
13+
{
14+
return static::make($field)
15+
->label(flexiblePagesTrans("form_component.{$field}_lbl"))
16+
->maxLength(255)
17+
->live()
18+
->addsTranslatableHint()
19+
->required($required)
20+
->disableToolbarButtons([
21+
'attachFiles',
22+
]);
23+
}
24+
}

src/Form/Components/NameField.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Statikbe\FilamentFlexibleContentBlockPages\Form\Components;
4+
5+
use Statikbe\FilamentFlexibleContentBlocks\Filament\Form\Fields\TitleField;
6+
7+
class NameField extends TitleField
8+
{
9+
public static function create(bool $required = false): static
10+
{
11+
return parent::create($required)
12+
->label(flexiblePagesTrans('form_component.name_lbl'));
13+
}
14+
15+
public static function getFieldName(): string
16+
{
17+
return 'name';
18+
}
19+
}

src/Http/Controllers/PageController.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ protected function setBasicSEO(Page $page)
133133

134134
protected function setSEOImage(Page $page)
135135
{
136-
$seoMedia = $page->getFallbackImageMedia($page->SEOImage()->first(), $page->getSEOImageCollection());
136+
/** @var Media|null $firstSeoMedia */
137+
$firstSeoMedia = $page->seoImage()->first();
138+
$seoMedia = $page->getFallbackImageMedia($firstSeoMedia, $page->getSEOImageCollection());
137139
$seoUrl = null;
138140
$imageDimensions = null;
139141

@@ -143,7 +145,9 @@ protected function setSEOImage(Page $page)
143145
$imageDimensions = $this->getSEOImageDimensions($seoMedia, $page->getSEOImageConversionName());
144146
} else {
145147
// 2. try the hero image of the page
146-
$seoMedia = $page->getFallbackImageMedia($page->heroImage()->first(), $page->getHeroImageCollection());
148+
/** @var Media|null $firstHeroMedia */
149+
$firstHeroMedia = $page->heroImage()->first();
150+
$seoMedia = $page->getFallbackImageMedia($firstHeroMedia, $page->getHeroImageCollection());
147151
if ($seoMedia) {
148152
$seoUrl = $seoMedia->getUrl($page->getSEOImageConversionName());
149153
$imageDimensions = $this->getSEOImageDimensions($seoMedia, $page->getSEOImageConversionName());
@@ -153,7 +157,10 @@ protected function setSEOImage(Page $page)
153157
if (! $seoMedia || ! $seoUrl) {
154158
/** @var Settings $settings */
155159
$settings = FilamentFlexibleContentBlockPages::config()->getSettingsModel()::getSettings();
156-
$seoMedia = $settings->getFallbackImageMedia($settings->defaultSeoImage()->first(), $settings::COLLECTION_DEFAULT_SEO);
160+
161+
/** @var Media|null $firstSettingsMedia */
162+
$firstSettingsMedia = $settings->defaultSeoImage()->first();
163+
$seoMedia = $settings->getFallbackImageMedia($firstSettingsMedia, $settings::COLLECTION_DEFAULT_SEO);
157164
$seoUrl = $seoMedia->getUrl($settings::CONVERSION_DEFAULT_SEO);
158165
$imageDimensions = $this->getSEOImageDimensions($seoMedia, $settings::CONVERSION_DEFAULT_SEO);
159166
}
@@ -202,6 +209,6 @@ private function getValidTitle(?string $title): ?string
202209
return null;
203210
}
204211

205-
return $title ? trim($title) : null;
212+
return trim($title);
206213
}
207214
}

0 commit comments

Comments
 (0)