Custom Components
Confetti makes it quick and easy to create custom components. This allows you to build your own CMS by combining reusable components. The simplest way to create a component is to copy an existing one and modify it.
A component consists of at least three files. Let’s create a ColorComponent for example. The key file will be the pkg/your-organization/color/ColorComponent.php file. Later on, you can create a your-organization/color/input.blade.php file for the admin input view and a your-organization/color repository to share the package between projects.
We start with an empty ColorComponent class:
<?php
declare(strict_types=1);
namespace YourOrganization\Color;
use ConfettiCms\Foundation\Helpers\ComponentStandard;
class ColorComponent extends ComponentStandard
{
}Several methods are mandatory in the component class:
The type() method defines the type of the component.
public function type(): string
{
return 'color';
}This allows you to use the component in your Blade views as follows:
<div style="background-color: {{ $banner->color('background_color') }}">Paint this</div>The get() method retrieves the saved value, which may not always be a string. To handle other data types, you can override the __toString() method to convert the returned value into a usable format.
public function get(): ?string
{
// Retrieve the saved value
$value = $this->contentStore->findOneData($this->parentContentId, $this->relativeContentId);
if ($value !== null) {
return $value;
}
return '#ffffff';
}Because the __toString() method calls the get() method, you don't need to use the ->get() method in your Blade file.
This method returns the full path to the Blade file used for the admin input view.
public function getViewAdminInput(): string
{
return __DIR__ . '/input.blade.php';
}This method returns the full path to the MJS file used for the admin preview view. All files in the public directory of your package are automatically published through the webserver.
public static function getViewAdminPreview(): string
{
return getPkgDir() . '/public/preview.mjs';
}You can also create "decoration" methods. These allow you to add options to your component in the view (HTML for the front-end).
public function default(string $default): self
{
$this->setDecoration(__FUNCTION__, get_defined_vars());
return $this;
}This enables usage like:
<div style="background-color: {{ $banner->color('background_color')->default('#ff0000') }}">Paint this red!</div>Decorations can be read in both PHP and JavaScript.
You can read decorations in the get() method:
public function get(): ?string
{
// Retrieve the saved value
$value = $this->contentStore->findOneData($this->parentContentId, $this->relativeContentId);
if ($value !== null) {
return $value;
}
return $this->getDecoration('default', 'default') ?? '#ffffff';
}Decorations can also be read in the JavaScript preview file:
constructor(id, value, component) {
this.id = id;
this.value = value || component.decorations.default?.default || null;
}After copying a composer.json from another package, you can run composer update to generate the autoloader automatically. This allows you to reuse and share the component across multiple projects. See Reuse Packages.