Repository navigation
Render craft\base\FieldInterface fields as craft\fieldlayoutelements\BaseNativeField
#17443
Replies: 3 comments 1 reply
|
Thinking about this more overnight… there should be a way to wrap a custom field in a native field layout element. Kinda like https://github.com/craftcms/cms/blob/5.x/src/fieldlayoutelements/CustomField.php does but with the mandatory flag. |
|
More thinking / experimenting… It is possible to wrap a field that implements Example: Define the native field: $event->fields[] = [
'class' => NativeCustomField::class,
'fieldClass' => [
'class' => PlainText::class,
'code' => true,
],
'label' => Craft::t('_kraftwerk', 'Key'),
'attribute' => 'key',
'required' => true,
'mandatory' => false,
];The The challenge here is making sure the field value is normalised on the element when loading from the DB… which would also need to be normalised through this field. I'm pretty sure that's how it's done for custom fields given elements have <?php
namespace newism\kraftwerk\fieldlayoutelements;
use craft\base\ElementInterface;
use craft\base\FieldInterface;
use craft\base\PreviewableFieldInterface;
use craft\base\ThumbableFieldInterface;
use craft\fieldlayoutelements\BaseNativeField;
class NativeCustomField extends BaseNativeField
{
private FieldInterface $_field;
public string $fieldClass = '';
public function __construct(array $config = [])
{
$field = \Craft::createObject($config['fieldClass']);
parent::__construct($config);
$this->setField($field);
}
/**
* Returns the custom field this layout field is based on.
*
* @return FieldInterface
*/
public function getField(): FieldInterface
{
return $this->_field;
}
public function setField(FieldInterface $field): void
{
$this->_field = $field;
$this->_field->handle = $this->attribute();
$this->_field->required = $this->required;
$this->_field->instructions = $this->instructions;
}
/**
* @inheritDoc
*/
protected function inputHtml(?ElementInterface $element = null, bool $static = false): ?string
{
$this->_field->static = $static;
$value = $this->_field->normalizeValue($this->value($element), $element);
if ($static) {
return $this->_field->getStaticHtml($value, $element);
}
return $this->_field->getInputHtml($value, $element);
}
protected function selectorIcon(): ?string
{
return $this->_field::icon();
}
protected function orientation(?ElementInterface $element = null, bool $static = false): string
{
return $this->_field->getOrientation($element);
}
/**
* @inheritdoc
*/
public function thumbable(): bool
{
return $this->_field instanceof ThumbableFieldInterface;
}
/**
* @inheritdoc
*/
public function previewable(): bool
{
return $this->_field instanceof PreviewableFieldInterface;
}
/**
* @inheritdoc
*/
public function thumbHtml(ElementInterface $element, int $size): ?string
{
$field = $this->getField();
if (!$field instanceof ThumbableFieldInterface) {
return null;
}
return $field->getThumbHtml($element->getFieldValue($field->handle), $element, $size);
}
/**
* @inheritdoc
*/
public function previewHtml(ElementInterface $element): string
{
$field = $this->getField();
if (!$field instanceof PreviewableFieldInterface) {
return '';
}
return $field->getPreviewHtml($field->normalizeValue($this->value($element), $element), $element);
}
} |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
@brandonkelly
While working through creating a new custom element I've been creating a lot of native fields. The pattern that keeps appearing is that these are basically re-implementations of custom fields.
Edit:
-The new Content Block field would be useful in my project but I don't know how to leverage the existing functionality.-
^ Content Block is probably too complex for this as it is its own element. Something like
Colormight be a better starting point.Is there a patter for creating native fields that work like custom fields?
All reactions