Browse Source

Merge pull request #2659 from markstory/3.0-multi-checkbox

3.0 multi checkbox
José Lorenzo Rodríguez 12 years ago
parent
commit
6321ee2b4f

+ 1 - 2
src/View/Helper/StringTemplateTrait.php

@@ -37,8 +37,7 @@ trait StringTemplateTrait {
  * @return void
  */
 	public function initStringTemplates($templates = [], $templateClass = '\Cake\View\StringTemplate') {
-		$this->_templater = new $templateClass();
-		$this->_templater->add($templates);
+		$this->_templater = new $templateClass($templates);
 		if (isset($this->settings['templates'])) {
 			$this->_templater->load($this->settings['templates']);
 		}

+ 184 - 0
src/View/Input/MultiCheckbox.php

@@ -0,0 +1,184 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         CakePHP(tm) v3.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\View\Input;
+
+use Cake\Utility\Inflector;
+
+/**
+ * Input widget class for generating multiple checkboxes.
+ *
+ */
+class MultiCheckbox {
+
+/**
+ * Template instance to use.
+ *
+ * @var Cake\View\StringTemplate
+ */
+	protected $_templates;
+
+/**
+ * Render multi-checkbox widget.
+ *
+ * @param Cake\View\StringTemplate $templates
+ */
+	public function __construct($templates) {
+		$this->_templates = $templates;
+	}
+
+/**
+ * Render multi-checkbox widget.
+ *
+ * Data supports the following options.
+ *
+ * - `name` The name attribute of the inputs to create.
+ *   `[]` will be appended to the name.
+ * - `options` An array of options to create checkboxes out of.
+ * - `val` Either a string/integer or array of values that should be
+ *   checked. Can also be a complex options set.
+ * - `disabled` Either a boolean or an array of checkboxes to disable.
+ * - `escape` Set to false to disable HTML escaping.
+ * - `options` An associative array of value=>labels to generate options for.
+ *
+ * ### Options format
+ *
+ * The options option can take a variety of data format depending on
+ * the complexity of HTML you want generated.
+ *
+ * You can generate simple options using a basic associative array:
+ *
+ * {{{
+ * 'options' => ['elk' => 'Elk', 'beaver' => 'Beaver']
+ * }}}
+ *
+ * If you need to define additional attributes on your option elements
+ * you can use the complex form for options:
+ *
+ * {{{
+ * 'options' => [
+ *   ['value' => 'elk', 'text' => 'Elk', 'data-foo' => 'bar'],
+ * ]
+ * }}}
+ *
+ * This form **requires** that both the `value` and `text` keys be defined.
+ * If either is not set options will not be generated correctly.
+ *
+ * @param array $data
+ * @return string
+ */
+	public function render($data) {
+		$data += [
+			'name' => '',
+			'escape' => true,
+			'options' => [],
+			'disabled' => null,
+			'val' => null,
+		];
+		$out = [];
+		foreach ($data['options'] as $key => $val) {
+			$checkbox = [
+				'value' => $key,
+				'text' => $val,
+			];
+			if (is_array($val) && isset($val['text'], $val['value'])) {
+				$checkbox = $val;
+			}
+			$checkbox['name'] = $data['name'];
+			$checkbox['escape'] = $data['escape'];
+
+			if ($this->_isSelected($key, $data['val'])) {
+				$checkbox['checked'] = true;
+			}
+			if ($this->_isDisabled($key, $data['disabled'])) {
+				$checkbox['disabled'] = true;
+			}
+			if (empty($checkbox['id'])) {
+				$checkbox['id'] = mb_strtolower(Inflector::slug($checkbox['name'] . $checkbox['value'], '-'));
+			}
+
+			$out[] = $this->_renderInput($checkbox);
+		}
+		return implode('', $out);
+	}
+
+/**
+ * Render a single checkbox & wrapper.
+ *
+ * @return string
+ */
+	protected function _renderInput($checkbox) {
+		$input = $this->_templates->format('checkbox', [
+			'name' => $checkbox['name'] . '[]',
+			'value' => $checkbox['escape'] ? h($checkbox['value']) : $checkbox['value'],
+			'attrs' => $this->_templates->formatAttributes(
+				$checkbox,
+				['name', 'value', 'text']
+			)
+		]);
+
+		$labelAttrs = [
+			'for' => $checkbox['id'],
+			'escape' => $checkbox['escape']
+		];
+		$label = $this->_templates->format('label', [
+			'text' => $checkbox['escape'] ? h($checkbox['text']) : $checkbox['text'],
+			'input' => $input,
+			'attrs' => $this->_templates->formatAttributes($labelAttrs)
+		]);
+
+		return $this->_templates->format('checkboxContainer', [
+			'label' => $label,
+			'input' => $input
+		]);
+	}
+
+/**
+ * Helper method for deciding what options are selected.
+ *
+ * @param string $key The key to test.
+ * @param array|string|null The selected values.
+ * @return boolean
+ */
+	protected function _isSelected($key, $selected) {
+		if ($selected === null) {
+			return false;
+		}
+		$isArray = is_array($selected);
+		if (!$isArray) {
+			return (string)$key === (string)$selected;
+		}
+		$strict = !is_numeric($key);
+		return in_array((string)$key, $selected, $strict);
+	}
+
+/**
+ * Helper method for deciding what options are disabled.
+ *
+ * @param string $key The key to test.
+ * @param array|null The disabled values.
+ * @return boolean
+ */
+	protected function _isDisabled($key, $disabled) {
+		if ($disabled === null || $disabled === false) {
+			return false;
+		}
+		if ($disabled === true) {
+			return true;
+		}
+		$strict = !is_numeric($key);
+		return in_array((string)$key, $disabled, $strict);
+	}
+
+}

+ 1 - 2
src/View/Input/Radio.php

@@ -15,7 +15,6 @@
 namespace Cake\View\Input;
 
 use Cake\Utility\Inflector;
-use Cake\View\StringTemplate;
 use Traversable;
 
 /**
@@ -134,7 +133,7 @@ class Radio {
 		$radio['name'] = $data['name'];
 
 		if (empty($radio['id'])) {
-			$radio['id'] = Inflector::slug($radio['name'] . '_' . $radio['value']);
+			$radio['id'] = mb_strtolower(Inflector::slug($radio['name'] . '_' . $radio['value'], '-'));
 		}
 
 		if (isset($data['val']) && strval($data['val']) === strval($radio['value'])) {

+ 0 - 1
src/View/Input/SelectBox.php

@@ -14,7 +14,6 @@
  */
 namespace Cake\View\Input;
 
-use Cake\View\StringTemplate;
 use Traversable;
 
 /**

+ 11 - 0
src/View/StringTemplate.php

@@ -49,6 +49,17 @@ class StringTemplate {
 	];
 
 /**
+ * Constructor.
+ *
+ * @param array $templates A set of templates to add.
+ */
+	public function __construct(array $templates = null) {
+		if ($templates) {
+			$this->add($templates);
+		}
+	}
+
+/**
  * Load a config file containing templates.
  *
  * Template files should define a `$config` variable containing

+ 6 - 2
tests/TestCase/View/Input/CheckboxTest.php

@@ -23,13 +23,17 @@ use Cake\View\StringTemplate;
  */
 class CheckboxTest extends TestCase {
 
+/**
+ * setup method.
+ *
+ * @return void
+ */
 	public function setUp() {
 		parent::setUp();
 		$templates = [
 			'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
 		];
-		$this->templates = new StringTemplate();
-		$this->templates->add($templates);
+		$this->templates = new StringTemplate($templates);
 	}
 
 /**

+ 294 - 0
tests/TestCase/View/Input/MultiCheckboxTest.php

@@ -0,0 +1,294 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         CakePHP(tm) v3.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\View\Input;
+
+use Cake\TestSuite\TestCase;
+use Cake\View\Input\MultiCheckbox;
+use Cake\View\StringTemplate;
+
+/**
+ * MultiCheckbox test case.
+ */
+class MultiCheckboxTest extends TestCase {
+
+/**
+ * setup method.
+ *
+ * @return void
+ */
+	public function setUp() {
+		parent::setUp();
+		$templates = [
+			'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
+			'label' => '<label{{attrs}}>{{text}}</label>',
+			'checkboxContainer' => '<div class="checkbox">{{input}}{{label}}</div>',
+		];
+		$this->templates = new StringTemplate($templates);
+	}
+
+/**
+ * Test render simple option sets.
+ *
+ * @return void
+ */
+	public function testRenderSimple() {
+		$input = new MultiCheckbox($this->templates);
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				1 => 'CakePHP',
+				2 => 'Development',
+			]
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 1,
+				'id' => 'tags-id-1',
+			]],
+			['label' => ['for' => 'tags-id-1']],
+			'CakePHP',
+			'/label',
+			'/div',
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 2,
+				'id' => 'tags-id-2',
+			]],
+			['label' => ['for' => 'tags-id-2']],
+			'Development',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+	}
+
+/**
+ * Test render complex and additional attributes.
+ *
+ * @return void
+ */
+	public function testRenderComplex() {
+		$input = new MultiCheckbox($this->templates);
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				['value' => '1', 'text' => 'CakePHP', 'data-test' => 'val'],
+				['value' => '2', 'text' => 'Development', 'class' => 'custom'],
+			]
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 1,
+				'id' => 'tags-id-1',
+				'data-test' => 'val',
+			]],
+			['label' => ['for' => 'tags-id-1']],
+			'CakePHP',
+			'/label',
+			'/div',
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 2,
+				'id' => 'tags-id-2',
+				'class' => 'custom',
+			]],
+			['label' => ['for' => 'tags-id-2']],
+			'Development',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+	}
+
+/**
+ * Test render escpaing options.
+ *
+ * @return void
+ */
+	public function testRenderEscaping() {
+		$input = new MultiCheckbox($this->templates);
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				'>' => '>>',
+			]
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => '&gt;',
+				'id' => 'tags-id',
+			]],
+			['label' => ['for' => 'tags-id']],
+			'&gt;&gt;',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+	}
+
+/**
+ * Test render selected checkboxes.
+ *
+ * @return void
+ */
+	public function testRenderSelected() {
+		$input = new MultiCheckbox($this->templates);
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				1 => 'CakePHP',
+				'1x' => 'Development',
+			],
+			'val' => [1],
+			'disabled' => false
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 1,
+				'id' => 'tags-id-1',
+				'checked' => 'checked'
+			]],
+			['label' => ['for' => 'tags-id-1']],
+			'CakePHP',
+			'/label',
+			'/div',
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => '1x',
+				'id' => 'tags-id-1x',
+			]],
+			['label' => ['for' => 'tags-id-1x']],
+			'Development',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+
+		$data['val'] = 1;
+		$result = $input->render($data);
+		$this->assertTags($result, $expected);
+
+		$data['val'] = '1';
+		$result = $input->render($data);
+		$this->assertTags($result, $expected);
+	}
+
+/**
+ * Test render disabled checkboxes.
+ *
+ * @return void
+ */
+	public function testRenderDisabled() {
+		$input = new MultiCheckbox($this->templates);
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				1 => 'CakePHP',
+				'1x' => 'Development',
+			],
+			'disabled' => true,
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 1,
+				'id' => 'tags-id-1',
+				'disabled' => 'disabled'
+			]],
+			['label' => ['for' => 'tags-id-1']],
+			'CakePHP',
+			'/label',
+			'/div',
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => '1x',
+				'id' => 'tags-id-1x',
+				'disabled' => 'disabled'
+			]],
+			['label' => ['for' => 'tags-id-1x']],
+			'Development',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+
+		$data['disabled'] = ['1', '1x'];
+		$this->assertTags($result, $expected);
+
+		$data = [
+			'name' => 'Tags[id]',
+			'options' => [
+				1 => 'CakePHP',
+				'1x' => 'Development',
+			],
+			'disabled' => [1]
+		];
+		$result = $input->render($data);
+		$expected = [
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => 1,
+				'id' => 'tags-id-1',
+				'disabled' => 'disabled'
+			]],
+			['label' => ['for' => 'tags-id-1']],
+			'CakePHP',
+			'/label',
+			'/div',
+			['div' => ['class' => 'checkbox']],
+			['input' => [
+				'type' => 'checkbox',
+				'name' => 'Tags[id][]',
+				'value' => '1x',
+				'id' => 'tags-id-1x',
+			]],
+			['label' => ['for' => 'tags-id-1x']],
+			'Development',
+			'/label',
+			'/div',
+		];
+		$this->assertTags($result, $expected);
+	}
+
+}

+ 40 - 36
tests/TestCase/View/Input/RadioTest.php

@@ -24,6 +24,11 @@ use Cake\View\StringTemplate;
  */
 class RadioTest extends TestCase {
 
+/**
+ * setup method.
+ *
+ * @return void
+ */
 	public function setUp() {
 		parent::setUp();
 		$templates = [
@@ -31,8 +36,7 @@ class RadioTest extends TestCase {
 			'label' => '<label{{attrs}}>{{text}}</label>',
 			'radioContainer' => '{{input}}{{label}}',
 		];
-		$this->templates = new StringTemplate();
-		$this->templates->add($templates);
+		$this->templates = new StringTemplate($templates);
 	}
 
 /**
@@ -52,18 +56,18 @@ class RadioTest extends TestCase {
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => 'r',
-				'id' => 'Crayons_color_r'
+				'id' => 'crayons-color-r'
 			]],
-			['label' => ['for' => 'Crayons_color_r']],
+			['label' => ['for' => 'crayons-color-r']],
 			'Red',
 			'/label',
 			['input' => [
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => 'b',
-				'id' => 'Crayons_color_b'
+				'id' => 'crayons-color-b'
 			]],
-			['label' => ['for' => 'Crayons_color_b']],
+			['label' => ['for' => 'crayons-color-b']],
 			'Black',
 			'/label',
 		];
@@ -134,18 +138,18 @@ class RadioTest extends TestCase {
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => '',
-				'id' => 'Crayons_color'
+				'id' => 'crayons-color'
 			]],
-			['label' => ['for' => 'Crayons_color']],
+			['label' => ['for' => 'crayons-color']],
 			'empty',
 			'/label',
 			['input' => [
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => 'r',
-				'id' => 'Crayons_color_r'
+				'id' => 'crayons-color-r'
 			]],
-			['label' => ['for' => 'Crayons_color_r']],
+			['label' => ['for' => 'crayons-color-r']],
 			'Red',
 			'/label',
 		];
@@ -158,18 +162,18 @@ class RadioTest extends TestCase {
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => '',
-				'id' => 'Crayons_color'
+				'id' => 'crayons-color'
 			]],
-			['label' => ['for' => 'Crayons_color']],
+			['label' => ['for' => 'crayons-color']],
 			'Choose one',
 			'/label',
 			['input' => [
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => 'r',
-				'id' => 'Crayons_color_r'
+				'id' => 'crayons-color-r'
 			]],
-			['label' => ['for' => 'Crayons_color_r']],
+			['label' => ['for' => 'crayons-color-r']],
 			'Red',
 			'/label',
 		];
@@ -193,12 +197,12 @@ class RadioTest extends TestCase {
 		];
 		$result = $radio->render($data);
 		$expected = [
-			['label' => ['for' => 'Crayons_color_r']],
+			['label' => ['for' => 'crayons-color-r']],
 			['input' => [
 				'type' => 'radio',
 				'name' => 'Crayons[color]',
 				'value' => 'r',
-				'id' => 'Crayons_color_r'
+				'id' => 'crayons-color-r'
 			]],
 			'Red',
 			'/label',
@@ -225,31 +229,31 @@ class RadioTest extends TestCase {
 		$result = $radio->render($data);
 		$expected = [
 			['input' => [
-				'id' => 'Versions_ver_1',
+				'id' => 'versions-ver-1',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1',
 				'checked' => 'checked'
 			]],
-			['label' => ['for' => 'Versions_ver_1']],
+			['label' => ['for' => 'versions-ver-1']],
 			'one',
 			'/label',
 			['input' => [
-				'id' => 'Versions_ver_1x',
+				'id' => 'versions-ver-1x',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1x'
 			]],
-			['label' => ['for' => 'Versions_ver_1x']],
+			['label' => ['for' => 'versions-ver-1x']],
 			'one x',
 			'/label',
 			['input' => [
-				'id' => 'Versions_ver_2',
+				'id' => 'versions-ver-2',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '2'
 			]],
-			['label' => ['for' => 'Versions_ver_2']],
+			['label' => ['for' => 'versions-ver-2']],
 			'two',
 			'/label',
 		];
@@ -275,23 +279,23 @@ class RadioTest extends TestCase {
 		$result = $radio->render($data);
 		$expected = [
 			['input' => [
-				'id' => 'Versions_ver_1',
+				'id' => 'versions-ver-1',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1',
 				'disabled' => 'disabled'
 			]],
-			['label' => ['for' => 'Versions_ver_1']],
+			['label' => ['for' => 'versions-ver-1']],
 			'one',
 			'/label',
 			['input' => [
-				'id' => 'Versions_ver_1x',
+				'id' => 'versions-ver-1x',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1x',
 				'disabled' => 'disabled'
 			]],
-			['label' => ['for' => 'Versions_ver_1x']],
+			['label' => ['for' => 'versions-ver-1x']],
 			'one x',
 			'/label',
 		];
@@ -301,22 +305,22 @@ class RadioTest extends TestCase {
 		$result = $radio->render($data);
 		$expected = [
 			['input' => [
-				'id' => 'Versions_ver_1',
+				'id' => 'versions-ver-1',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1',
 				'disabled' => 'disabled'
 			]],
-			['label' => ['for' => 'Versions_ver_1']],
+			['label' => ['for' => 'versions-ver-1']],
 			'one',
 			'/label',
 			['input' => [
-				'id' => 'Versions_ver_1x',
+				'id' => 'versions-ver-1x',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1x',
 			]],
-			['label' => ['for' => 'Versions_ver_1x']],
+			['label' => ['for' => 'versions-ver-1x']],
 			'one x',
 			'/label',
 		];
@@ -342,13 +346,13 @@ class RadioTest extends TestCase {
 		$result = $radio->render($data);
 		$expected = [
 			['input' => [
-				'id' => 'Versions_ver_1',
+				'id' => 'versions-ver-1',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1',
 			]],
 			['input' => [
-				'id' => 'Versions_ver_1x',
+				'id' => 'versions-ver-1x',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1x',
@@ -370,21 +374,21 @@ class RadioTest extends TestCase {
 		$result = $radio->render($data);
 		$expected = [
 			['input' => [
-				'id' => 'Versions_ver_1',
+				'id' => 'versions-ver-1',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1',
 			]],
-			['label' => ['class' => 'my-class', 'for' => 'Versions_ver_1']],
+			['label' => ['class' => 'my-class', 'for' => 'versions-ver-1']],
 			'one',
 			'/label',
 			['input' => [
-				'id' => 'Versions_ver_1x',
+				'id' => 'versions-ver-1x',
 				'name' => 'Versions[ver]',
 				'type' => 'radio',
 				'value' => '1x',
 			]],
-			['label' => ['class' => 'my-class', 'for' => 'Versions_ver_1x']],
+			['label' => ['class' => 'my-class', 'for' => 'versions-ver-1x']],
 			'one x',
 			'/label',
 		];

+ 6 - 2
tests/TestCase/View/Input/SelectBoxTest.php

@@ -23,6 +23,11 @@ use Cake\View\StringTemplate;
  */
 class SelectBoxTest extends TestCase {
 
+/**
+ * setup method.
+ *
+ * @return void
+ */
 	public function setUp() {
 		parent::setUp();
 		$templates = [
@@ -31,8 +36,7 @@ class SelectBoxTest extends TestCase {
 			'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>',
 			'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>',
 		];
-		$this->templates = new StringTemplate();
-		$this->templates->add($templates);
+		$this->templates = new StringTemplate($templates);
 	}
 
 /**

+ 1 - 2
tests/TestCase/View/Input/TextTest.php

@@ -28,8 +28,7 @@ class TextTest extends TestCase {
 		$templates = [
 			'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}>',
 		];
-		$this->templates = new StringTemplate();
-		$this->templates->add($templates);
+		$this->templates = new StringTemplate($templates);
 	}
 
 /**

+ 13 - 0
tests/TestCase/View/StringTemplateTest.php

@@ -31,6 +31,19 @@ class StringTemplateTest extends TestCase {
 	}
 
 /**
+ * Test adding templates through the constructor.
+ *
+ * @return void
+ */
+	public function testConstructorAdd() {
+		$templates = [
+			'link' => '<a href="{{url}}">{{text}}</a>'
+		];
+		$template = new StringTemplate($templates);
+		$this->assertEquals($templates['link'], $template->get('link'));
+	}
+
+/**
  * test adding templates.
  *
  * @return void