Skip to content

Worked extension examples

These developer-facing recipes are kept beside the package contract. Replace the example values with the site-specific records and data objects used by the calling workflow.

<?php
declare(strict_types=1);
final class ExamplePublicLayoutWidgetAssetsRendererImplementation implements \Capell\LayoutBuilder\Contracts\Assets\PublicLayoutWidgetAssetsRenderer
{
/**
* @param array<string, mixed> $widgetData
* @param array<string, mixed> $options
*/
public function render(mixed $widget, string $containerKey, array $widgetData = [], mixed $widgetAssets = null, mixed $widgetAssetsByWidget = null, array $options = []): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\Assets\PublicLayoutWidgetAssetsRenderer::class, ExamplePublicLayoutWidgetAssetsRendererImplementation::class);
<?php
declare(strict_types=1);
final class ExampleLayoutContainerSchemaExtenderImplementation implements \Capell\LayoutBuilder\Contracts\Extenders\LayoutContainerSchemaExtender
{
public function themeKey(): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function themeLabel(): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function supports(\Capell\LayoutBuilder\Data\LayoutContainerSchemaContextData $context): bool
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @return array<int, Htmlable>
*/
public function extendContainerComponents(\Filament\Schemas\Schema $schema, \Capell\LayoutBuilder\Data\LayoutContainerSchemaContextData $context): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\Extenders\LayoutContainerSchemaExtender::class, ExampleLayoutContainerSchemaExtenderImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetAssetSchemaExtenderImplementation implements \Capell\LayoutBuilder\Contracts\Extenders\WidgetAssetSchemaExtender
{
/**
* @param array<int, mixed> $components
* @return array<int, mixed>
*/
public function extendAssetComponents(\Filament\Schemas\Schema $schema, array $components): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @param array<int, mixed> $components
* @return array<int, mixed>
*/
public function extendRepeaterComponents(array $components): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\Extenders\WidgetAssetSchemaExtender::class, ExampleWidgetAssetSchemaExtenderImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetSchemaExtenderImplementation implements \Capell\LayoutBuilder\Contracts\Extenders\WidgetSchemaExtender
{
/**
* @param array<int, mixed> $components
* @return array<int, mixed>
*/
public function extendDisplayComponents(\Filament\Schemas\Schema $schema, array $components): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\Extenders\WidgetSchemaExtender::class, ExampleWidgetSchemaExtenderImplementation::class);
<?php
declare(strict_types=1);
final class ExampleLayoutContainerThemePresentationProjectorImplementation implements \Capell\LayoutBuilder\Contracts\LayoutContainerThemePresentationProjector
{
public function themeKey(): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @param array<string, mixed> $state
*/
public function project(array $state): \Capell\LayoutBuilder\Data\LayoutContainerThemePresentationData
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\LayoutContainerThemePresentationProjector::class, ExampleLayoutContainerThemePresentationProjectorImplementation::class);
<?php
declare(strict_types=1);
final class ExampleLayoutContentGroupContributorImplementation implements \Capell\LayoutBuilder\Contracts\LayoutContentGroupContributor
{
public function priority(): int
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function group(\Capell\LayoutBuilder\Data\LayoutContentGroupData $group, \Capell\LayoutBuilder\Data\LayoutContentInventoryContextData $context): \Capell\LayoutBuilder\Data\LayoutContentGroupData
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function item(\Capell\LayoutBuilder\Data\LayoutContentItemData $item, \Capell\LayoutBuilder\Data\LayoutContentInventoryContextData $context): \Capell\LayoutBuilder\Data\LayoutContentItemData
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @return array<int, string>
*/
public function eagerLoads(): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @return array<int, string>
*/
public function cacheDependencies(): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\LayoutContentGroupContributor::class, ExampleLayoutContentGroupContributorImplementation::class);
<?php
declare(strict_types=1);
final class ExampleLayoutSidebarWidgetContributorImplementation implements \Capell\LayoutBuilder\Contracts\LayoutSidebarWidgetContributor
{
/**
* @return array<int, LayoutSidebarWidgetData>
*/
public function sidebarWidgets(): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\LayoutSidebarWidgetContributor::class, ExampleLayoutSidebarWidgetContributorImplementation::class);
<?php
declare(strict_types=1);
final class ExamplePublicLayoutWidgetPayloadContributorImplementation implements \Capell\LayoutBuilder\Contracts\PublicLayoutWidgetPayloadContributor
{
public function priority(): int
{
throw new LogicException('Implement this package contract for the calling site.');
}
/**
* @return array<string, mixed>
*/
public function data(\Capell\LayoutBuilder\Models\Widget $widget, \Capell\Core\Models\Page $page, \Capell\Core\Models\Language $language, string $containerKey, int $occurrence): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function html(\Capell\LayoutBuilder\Models\Widget $widget, \Capell\Core\Models\Page $page, \Capell\Core\Models\Language $language, string $containerKey, int $occurrence): ?string
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\PublicLayoutWidgetPayloadContributor::class, ExamplePublicLayoutWidgetPayloadContributorImplementation::class);
<?php
declare(strict_types=1);
final class ExamplePublicLayoutWidgetPayloadResolverImplementation implements \Capell\LayoutBuilder\Contracts\PublicLayoutWidgetPayloadResolver
{
/**
* @return array<string, mixed>
*/
public function data(\Capell\LayoutBuilder\Models\Widget $widget, \Capell\Core\Models\Page $page, \Capell\Core\Models\Language $language, string $containerKey, int $occurrence): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function html(\Capell\LayoutBuilder\Models\Widget $widget, \Capell\Core\Models\Page $page, \Capell\Core\Models\Language $language, string $containerKey, int $occurrence): ?string
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\PublicLayoutWidgetPayloadResolver::class, ExamplePublicLayoutWidgetPayloadResolverImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetAssetReferenceRepointerImplementation implements \Capell\LayoutBuilder\Contracts\WidgetAssetReferenceRepointer
{
public function repoint(\Illuminate\Database\Eloquent\Model $asset, int|string $fromAssetId, int|string $toAssetId): int
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\WidgetAssetReferenceRepointer::class, ExampleWidgetAssetReferenceRepointerImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetExtensionBatchPayloadResolverImplementation implements \Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionBatchPayloadResolver
{
/**
* Resolve public payloads for a batch keyed by opaque widget instance ID.
*
* @return array<string, Data>
*/
public function resolve(\Capell\LayoutBuilder\Data\WidgetExtensions\WidgetExtensionPayloadBatchData $batch): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionBatchPayloadResolver::class, ExampleWidgetExtensionBatchPayloadResolverImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetExtensionDependencyResolverImplementation implements \Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionDependencyResolver
{
/**
* Resolve stable content-graph dependency identifiers such as `media:123`.
*
* @return list<string>
*/
public function resolve(\Spatie\LaravelData\Data $input): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionDependencyResolver::class, ExampleWidgetExtensionDependencyResolverImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetExtensionStateUpcasterImplementation implements \Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionStateUpcaster
{
/**
* @param array<string, mixed> $state
* @return array<string, mixed>
*/
public function upcast(array $state, int $fromVersion, int $toVersion): array
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\WidgetExtensions\WidgetExtensionStateUpcaster::class, ExampleWidgetExtensionStateUpcasterImplementation::class);
<?php
declare(strict_types=1);
final class ExampleWidgetSnapshotLocatorCipherImplementation implements \Capell\LayoutBuilder\Contracts\WidgetSnapshots\WidgetSnapshotLocatorCipher
{
public function encrypt(string $plaintext): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
public function decrypt(string $ciphertext): string
{
throw new LogicException('Implement this package contract for the calling site.');
}
}
app()->bind(\Capell\LayoutBuilder\Contracts\WidgetSnapshots\WidgetSnapshotLocatorCipher::class, ExampleWidgetSnapshotLocatorCipherImplementation::class);
<?php
declare(strict_types=1);
$inputs = []; // Supply the arguments required by the action handle() method.
resolve(\Capell\LayoutBuilder\Actions\InstallLayoutBuilderPackageAction::class)->handle(...$inputs);
<?php
declare(strict_types=1);
$inputs = []; // Supply the arguments required by the action handle() method.
resolve(\Capell\LayoutBuilder\Actions\PruneLayoutBulkChangeRunsAction::class)->handle(...$inputs);
<?php
declare(strict_types=1);
$inputs = []; // Supply the arguments required by the action handle() method.
resolve(\Capell\LayoutBuilder\Actions\SetupLayoutBuilderPackageAction::class)->handle(...$inputs);