mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
139 lines
3.3 KiB
PHP
139 lines
3.3 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace SilverStripe\View;
|
||
|
|
||
|
use SilverStripe\Core\Convert;
|
||
|
|
||
|
/**
|
||
|
* This trait can be applied to a ViewableData class to add the logic to render attributes in an SS template.
|
||
|
*
|
||
|
* When applying this trait to a class, you also need to add the following casting configuration.
|
||
|
* ```
|
||
|
* private static $casting = [
|
||
|
* 'AttributesHTML' => 'HTMLFragment',
|
||
|
* 'getAttributesHTML' => 'HTMLFragment',
|
||
|
* ];
|
||
|
* ```
|
||
|
*/
|
||
|
trait AttributesHTML
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* List of attributes to render on the frontend
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $attributes = [];
|
||
|
|
||
|
/**
|
||
|
* Set an HTML attribute
|
||
|
* @param $name
|
||
|
* @param $value
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function setAttribute($name, $value)
|
||
|
{
|
||
|
$this->attributes[$name] = $value;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve the value of an HTML attribute
|
||
|
* @param string $name
|
||
|
* @return mixed|null
|
||
|
*/
|
||
|
public function getAttribute($name)
|
||
|
{
|
||
|
$attributes = $this->getAttributes();
|
||
|
|
||
|
if (isset($attributes[$name])) {
|
||
|
return $attributes[$name];
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the default attributes when rendering this object.
|
||
|
*
|
||
|
* Called by `getAttributes()`
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
abstract protected function getDefaultAttributes(): array;
|
||
|
|
||
|
/**
|
||
|
* Allows customization through an 'updateAttributes' hook on the base class.
|
||
|
* Existing attributes are passed in as the first argument and can be manipulated,
|
||
|
* but any attributes added through a subclass implementation won't be included.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAttributes()
|
||
|
{
|
||
|
$defaultAttributes = $this->getDefaultAttributes();
|
||
|
|
||
|
$attributes = array_merge($defaultAttributes, $this->attributes);
|
||
|
|
||
|
if (method_exists($this, 'extend')) {
|
||
|
$this->extend('updateAttributes', $attributes);
|
||
|
}
|
||
|
|
||
|
return $attributes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Custom attributes to process. Falls back to {@link getAttributes()}.
|
||
|
*
|
||
|
* If at least one argument is passed as a string, all arguments act as excludes, by name.
|
||
|
*
|
||
|
* @param array $attributes
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getAttributesHTML($attributes = null)
|
||
|
{
|
||
|
$exclude = null;
|
||
|
|
||
|
if (is_string($attributes)) {
|
||
|
$exclude = func_get_args();
|
||
|
}
|
||
|
|
||
|
if (!$attributes || is_string($attributes)) {
|
||
|
$attributes = $this->getAttributes();
|
||
|
}
|
||
|
|
||
|
$attributes = (array) $attributes;
|
||
|
|
||
|
$attributes = array_filter($attributes, function ($v) {
|
||
|
return ($v || $v === 0 || $v === '0');
|
||
|
});
|
||
|
|
||
|
if ($exclude) {
|
||
|
$attributes = array_diff_key(
|
||
|
$attributes,
|
||
|
array_flip($exclude)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Create markup
|
||
|
$parts = [];
|
||
|
|
||
|
foreach ($attributes as $name => $value) {
|
||
|
if ($value === true) {
|
||
|
$value = $name;
|
||
|
} else {
|
||
|
if (is_scalar($value)) {
|
||
|
$value = (string) $value;
|
||
|
} else {
|
||
|
$value = json_encode($value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$parts[] = sprintf('%s="%s"', Convert::raw2att($name), Convert::raw2att($value));
|
||
|
}
|
||
|
|
||
|
return implode(' ', $parts);
|
||
|
}
|
||
|
}
|