mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #10033 from creative-commoners/pulls/4/attributeshtml-trait
API Add an AttributesHTML trait
This commit is contained in:
commit
2d4b93883b
@ -20,6 +20,7 @@ use SilverStripe\ORM\FieldType\DBHTMLText;
|
|||||||
use SilverStripe\ORM\ValidationResult;
|
use SilverStripe\ORM\ValidationResult;
|
||||||
use SilverStripe\Security\NullSecurityToken;
|
use SilverStripe\Security\NullSecurityToken;
|
||||||
use SilverStripe\Security\SecurityToken;
|
use SilverStripe\Security\SecurityToken;
|
||||||
|
use SilverStripe\View\AttributesHTML;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
use SilverStripe\View\ViewableData;
|
use SilverStripe\View\ViewableData;
|
||||||
|
|
||||||
@ -66,10 +67,10 @@ use SilverStripe\View\ViewableData;
|
|||||||
*/
|
*/
|
||||||
class Form extends ViewableData implements HasRequestHandler
|
class Form extends ViewableData implements HasRequestHandler
|
||||||
{
|
{
|
||||||
|
use AttributesHTML;
|
||||||
use FormMessage;
|
use FormMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default form Name property
|
|
||||||
*/
|
*/
|
||||||
const DEFAULT_NAME = 'Form';
|
const DEFAULT_NAME = 'Form';
|
||||||
|
|
||||||
@ -816,33 +817,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function getDefaultAttributes(): array
|
||||||
* @param string $name
|
|
||||||
* @param string $value
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setAttribute($name, $value)
|
|
||||||
{
|
|
||||||
$this->attributes[$name] = $value;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getAttribute($name)
|
|
||||||
{
|
|
||||||
if (isset($this->attributes[$name])) {
|
|
||||||
return $this->attributes[$name];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getAttributes()
|
|
||||||
{
|
{
|
||||||
$attrs = [
|
$attrs = [
|
||||||
'id' => $this->FormName(),
|
'id' => $this->FormName(),
|
||||||
@ -860,53 +835,9 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
$attrs['class'] .= ' validationerror';
|
$attrs['class'] .= ' validationerror';
|
||||||
}
|
}
|
||||||
|
|
||||||
$attrs = array_merge($attrs, $this->attributes);
|
|
||||||
|
|
||||||
return $attrs;
|
return $attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the attributes of the form tag - used by the templates.
|
|
||||||
*
|
|
||||||
* @param array $attrs 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.
|
|
||||||
*
|
|
||||||
* @return string HTML attributes, ready for insertion into an HTML tag
|
|
||||||
*/
|
|
||||||
public function getAttributesHTML($attrs = null)
|
|
||||||
{
|
|
||||||
$exclude = (is_string($attrs)) ? func_get_args() : null;
|
|
||||||
|
|
||||||
$attrs = $this->getAttributes();
|
|
||||||
|
|
||||||
// Remove empty
|
|
||||||
$attrs = array_filter((array)$attrs, function ($value) {
|
|
||||||
return ($value || $value === 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove excluded
|
|
||||||
if ($exclude) {
|
|
||||||
$attrs = array_diff_key($attrs, array_flip($exclude));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare HTML-friendly 'method' attribute (lower-case)
|
|
||||||
if (isset($attrs['method'])) {
|
|
||||||
$attrs['method'] = strtolower($attrs['method']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create markup
|
|
||||||
$parts = [];
|
|
||||||
foreach ($attrs as $name => $value) {
|
|
||||||
if ($value === true) {
|
|
||||||
$value = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parts[] = sprintf('%s="%s"', Convert::raw2att($name), Convert::raw2att($value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode(' ', $parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function FormAttributes()
|
public function FormAttributes()
|
||||||
{
|
{
|
||||||
return $this->getAttributesHTML();
|
return $this->getAttributesHTML();
|
||||||
|
@ -13,6 +13,7 @@ use SilverStripe\ORM\DataObjectInterface;
|
|||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||||
use SilverStripe\ORM\ValidationResult;
|
use SilverStripe\ORM\ValidationResult;
|
||||||
|
use SilverStripe\View\AttributesHTML;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +42,7 @@ use SilverStripe\View\SSViewer;
|
|||||||
*/
|
*/
|
||||||
class FormField extends RequestHandler
|
class FormField extends RequestHandler
|
||||||
{
|
{
|
||||||
|
use AttributesHTML;
|
||||||
use FormMessage;
|
use FormMessage;
|
||||||
|
|
||||||
/** @see $schemaDataType */
|
/** @see $schemaDataType */
|
||||||
@ -214,17 +216,6 @@ class FormField extends RequestHandler
|
|||||||
*/
|
*/
|
||||||
protected $smallFieldHolderTemplate;
|
protected $smallFieldHolderTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* All attributes on the form field (not the field holder).
|
|
||||||
*
|
|
||||||
* Partially determined based on other instance properties.
|
|
||||||
*
|
|
||||||
* @see getAttributes()
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $attributes = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data type backing the field. Represents the type of value the
|
* The data type backing the field. Represents the type of value the
|
||||||
* form expects to receive via a postback. Should be set in subclasses.
|
* form expects to receive via a postback. Should be set in subclasses.
|
||||||
@ -659,59 +650,7 @@ class FormField extends RequestHandler
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function getDefaultAttributes(): array
|
||||||
* Set an HTML attribute on the field element, mostly an input tag.
|
|
||||||
*
|
|
||||||
* Some attributes are best set through more specialized methods, to avoid interfering with
|
|
||||||
* built-in behaviour:
|
|
||||||
*
|
|
||||||
* - 'class': {@link addExtraClass()}
|
|
||||||
* - 'title': {@link setDescription()}
|
|
||||||
* - 'value': {@link setValue}
|
|
||||||
* - 'name': {@link setName}
|
|
||||||
*
|
|
||||||
* Caution: this doesn't work on most fields which are composed of more than one HTML form
|
|
||||||
* field.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param string $value
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setAttribute($name, $value)
|
|
||||||
{
|
|
||||||
$this->attributes[$name] = $value;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an HTML attribute defined by the field, or added through {@link setAttribute()}.
|
|
||||||
*
|
|
||||||
* Caution: this doesn't work on all fields, see {@link setAttribute()}.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getAttribute($name)
|
|
||||||
{
|
|
||||||
$attributes = $this->getAttributes();
|
|
||||||
|
|
||||||
if (isset($attributes[$name])) {
|
|
||||||
return $attributes[$name];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()
|
|
||||||
{
|
{
|
||||||
$attributes = [
|
$attributes = [
|
||||||
'type' => $this->getInputType(),
|
'type' => $this->getInputType(),
|
||||||
@ -729,67 +668,9 @@ class FormField extends RequestHandler
|
|||||||
$attributes['aria-required'] = 'true';
|
$attributes['aria-required'] = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
$attributes = array_merge($attributes, $this->attributes);
|
|
||||||
|
|
||||||
$this->extend('updateAttributes', $attributes);
|
|
||||||
|
|
||||||
return $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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a version of a title suitable for insertion into an HTML attribute.
|
* Returns a version of a title suitable for insertion into an HTML attribute.
|
||||||
*
|
*
|
||||||
|
138
src/View/AttributesHTML.php
Normal file
138
src/View/AttributesHTML.php
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<?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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user