Browse Source

Merge pull request #3129 from AD7six/3.0-config-view

update View NS to use config, not settings
Andy Dawson 12 years ago
parent
commit
f3ecce5d63

+ 9 - 1
src/Core/InstanceConfigTrait.php

@@ -31,6 +31,13 @@ trait InstanceConfigTrait {
 	protected $_config = [];
 
 /**
+ * Whether the config property has already been configured with defaults
+ *
+ * @var bool
+ */
+	protected $_configInitialized = false;
+
+/**
  * ### Usage
  *
  * Reading the whole config:
@@ -63,8 +70,9 @@ trait InstanceConfigTrait {
  * @throws \Cake\Error\Exception When trying to set a key that is invalid
  */
 	public function config($key = null, $value = null) {
-		if ($this->_config === [] && $this->_defaultConfig) {
+		if (!$this->_configInitialized) {
 			$this->_config = $this->_defaultConfig;
+			$this->_configInitialized = true;
 		}
 
 		if (is_array($key) || func_num_args() === 2) {

+ 14 - 8
src/View/Helper.php

@@ -16,6 +16,7 @@ namespace Cake\View;
 
 use Cake\Core\App;
 use Cake\Core\Configure;
+use Cake\Core\InstanceConfigTrait;
 use Cake\Core\Object;
 use Cake\Core\Plugin;
 use Cake\Event\EventListener;
@@ -48,19 +49,21 @@ use Cake\Utility\Inflector;
  */
 class Helper extends Object implements EventListener {
 
+	use InstanceConfigTrait;
+
 /**
- * Settings for this helper.
+ * List of helpers used by this helper
  *
  * @var array
  */
-	public $settings = array();
+	public $helpers = array();
 
 /**
- * List of helpers used by this helper
+ * Default config for this helper.
  *
  * @var array
  */
-	public $helpers = array();
+	protected $_defaultConfig = [];
 
 /**
  * A helper lookup table used to lazy load helper objects.
@@ -141,14 +144,17 @@ class Helper extends Object implements EventListener {
  * Default Constructor
  *
  * @param View $View The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper.
+ * @param array $config Configuration settings for the helper.
  */
-	public function __construct(View $View, $settings = array()) {
+	public function __construct(View $View, $config = array()) {
 		$this->_View = $View;
 		$this->request = $View->request;
-		if ($settings) {
-			$this->settings = Hash::merge($this->settings, $settings);
+
+		if ($config) {
+			$config = Hash::merge($this->_defaultConfig, $config);
 		}
+		$this->config($config);
+
 		if (!empty($this->helpers)) {
 			$this->_helperMap = $View->Helpers->normalizeArray($this->helpers);
 		}

+ 48 - 54
src/View/Helper/FormHelper.php

@@ -62,17 +62,49 @@ class FormHelper extends Helper {
 	protected $_datetimeParts = ['year', 'month', 'day', 'hour', 'minute', 'second', 'meridian'];
 
 /**
- * Settings for the helper.
+ * Default config for the helper.
  *
  * @var array
  */
-	public $settings = [
+	protected $_defaultConfig = [
 		'errorClass' => 'form-error',
 		'typeMap' => [
 			'string' => 'text', 'datetime' => 'datetime', 'boolean' => 'checkbox',
 			'timestamp' => 'datetime', 'text' => 'textarea', 'time' => 'time',
 			'date' => 'date', 'float' => 'number', 'integer' => 'number',
 			'decimal' => 'number', 'binary' => 'file', 'uuid' => 'string'
+		],
+		'widgets' => [],
+		'registry' => null,
+		'templates' => [
+			'button' => '<button{{attrs}}>{{text}}</button>',
+			'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
+			'checkboxContainer' => '<div class="checkbox">{{input}}{{label}}</div>',
+			'dateWidget' => '{{month}}{{day}}{{year}}{{hour}}{{minute}}{{second}}{{meridian}}',
+			'error' => '<div class="error-message">{{content}}</div>',
+			'errorList' => '<ul>{{content}}</ul>',
+			'errorItem' => '<li>{{text}}</li>',
+			'file' => '<input type="file" name="{{name}}"{{attrs}}>',
+			'fieldset' => '<fieldset>{{content}}</fieldset>',
+			'formstart' => '<form{{attrs}}>',
+			'formend' => '</form>',
+			'hiddenblock' => '<div style="display:none;">{{content}}</div>',
+			'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}>',
+			'inputsubmit' => '<input type="{{type}}"{{attrs}}>',
+			'label' => '<label{{attrs}}>{{text}}</label>',
+			'legend' => '<legend>{{text}}</legend>',
+			'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>',
+			'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>',
+			'select' => '<select name="{{name}}"{{attrs}}>{{content}}</select>',
+			'selectMultiple' => '<select name="{{name}}[]" multiple="multiple"{{attrs}}>{{content}}</select>',
+			'radio' => '<input type="radio" name="{{name}}" value="{{value}}"{{attrs}}>',
+			'radioContainer' => '{{input}}{{label}}',
+			'textarea' => '<textarea name="{{name}}"{{attrs}}>{{value}}</textarea>',
+			'formGroup' => '{{label}}{{input}}',
+			'checkboxFormGroup' => '{{input}}{{label}}',
+			'groupContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>',
+			'groupContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>',
+			'submitContainer' => '<div class="submit">{{content}}</div>',
 		]
 	];
 
@@ -131,54 +163,18 @@ class FormHelper extends Helper {
 	protected $_contextProviders;
 
 /**
- * Default templates the FormHelper uses.
- *
- * @var array
- */
-	protected $_defaultTemplates = [
-		'button' => '<button{{attrs}}>{{text}}</button>',
-		'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
-		'checkboxContainer' => '<div class="checkbox">{{input}}{{label}}</div>',
-		'dateWidget' => '{{month}}{{day}}{{year}}{{hour}}{{minute}}{{second}}{{meridian}}',
-		'error' => '<div class="error-message">{{content}}</div>',
-		'errorList' => '<ul>{{content}}</ul>',
-		'errorItem' => '<li>{{text}}</li>',
-		'file' => '<input type="file" name="{{name}}"{{attrs}}>',
-		'fieldset' => '<fieldset>{{content}}</fieldset>',
-		'formstart' => '<form{{attrs}}>',
-		'formend' => '</form>',
-		'hiddenblock' => '<div style="display:none;">{{content}}</div>',
-		'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}>',
-		'inputsubmit' => '<input type="{{type}}"{{attrs}}>',
-		'label' => '<label{{attrs}}>{{text}}</label>',
-		'legend' => '<legend>{{text}}</legend>',
-		'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>',
-		'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>',
-		'select' => '<select name="{{name}}"{{attrs}}>{{content}}</select>',
-		'selectMultiple' => '<select name="{{name}}[]" multiple="multiple"{{attrs}}>{{content}}</select>',
-		'radio' => '<input type="radio" name="{{name}}" value="{{value}}"{{attrs}}>',
-		'radioContainer' => '{{input}}{{label}}',
-		'textarea' => '<textarea name="{{name}}"{{attrs}}>{{value}}</textarea>',
-		'formGroup' => '{{label}}{{input}}',
-		'checkboxFormGroup' => '{{input}}{{label}}',
-		'groupContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>',
-		'groupContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>',
-		'submitContainer' => '<div class="submit">{{content}}</div>',
-	];
-
-/**
  * Construct the widgets and binds the default context providers
  *
  * @param \Cake\View\View $View The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper.
+ * @param array $config Configuration settings for the helper.
  */
-	public function __construct(View $View, $settings = array()) {
-		$settings += ['widgets' => [], 'templates' => null, 'registry' => null];
-		parent::__construct($View, $settings);
+	public function __construct(View $View, $config = array()) {
+		parent::__construct($View, $config);
+
+		$config = $this->config();
 
-		$this->initStringTemplates($this->_defaultTemplates);
-		$this->widgetRegistry($settings['registry'], $settings['widgets']);
-		unset($this->settings['widgets'], $this->settings['registry']);
+		$this->widgetRegistry($config['registry'], $config['widgets']);
+		$this->config(['widgets' => null, 'registry' => null]);
 
 		$this->_addDefaultContextProviders();
 	}
@@ -193,7 +189,7 @@ class FormHelper extends Helper {
 	public function widgetRegistry(WidgetRegistry $instance = null, $widgets = []) {
 		if ($instance === null) {
 			if ($this->_registry === null) {
-				$this->_registry = new WidgetRegistry($this->_templater, $widgets);
+				$this->_registry = new WidgetRegistry($this->templater(), $widgets);
 			}
 			return $this->_registry;
 		}
@@ -293,7 +289,7 @@ class FormHelper extends Helper {
 		];
 
 		$this->_idPrefix = $options['idPrefix'];
-		$templater = $this->getTemplater();
+		$templater = $this->templater();
 
 		if (!empty($options['templates']) && is_array($options['templates'])) {
 			$templater->add($options['templates']);
@@ -941,7 +937,7 @@ class FormHelper extends Helper {
 		}
 
 		$internalType = $context->type($fieldName);
-		$map = $this->settings['typeMap'];
+		$map = $this->config('typeMap');
 		$type = isset($map[$internalType]) ? $map[$internalType] : 'text';
 		$fieldName = array_slice(explode('.', $fieldName), -1)[0];
 
@@ -1414,7 +1410,7 @@ class FormHelper extends Helper {
 		}
 
 		$out = $this->formatTemplate('formstart', [
-			'attrs' => $this->_templater->formatAttributes($formOptions)
+			'attrs' => $this->templater()->formatAttributes($formOptions)
 		]);
 		$out .= $this->hidden('_method', ['value' => $requestMethod]);
 		$out .= $this->_csrfField();
@@ -1517,7 +1513,7 @@ class FormHelper extends Helper {
 
 		$input = $this->formatTemplate('inputsubmit', [
 			'type' => $type,
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 		]);
 
 		return $this->formatTemplate('submitContainer', [
@@ -2098,7 +2094,7 @@ class FormHelper extends Helper {
 		unset($options['value'], $options['default']);
 
 		if ($context->hasError($field)) {
-			$options = $this->addClass($options, $this->settings['errorClass']);
+			$options = $this->addClass($options, $this->config('errorClass'));
 		}
 		if (!empty($options['disabled']) || $secure === static::SECURE_SKIP) {
 			return $options;
@@ -2242,9 +2238,7 @@ class FormHelper extends Helper {
  * @return void
  */
 	public function resetTemplates() {
-		$reflection = new \ReflectionClass($this);
-		$properties = $reflection->getDefaultProperties();
-		$this->templates($properties['_defaultTemplates']);
+		$this->templates($this->_defaultConfig['templates']);
 	}
 
 /**

+ 56 - 56
src/View/Helper/HtmlHelper.php

@@ -42,39 +42,41 @@ class HtmlHelper extends Helper {
 	public $response;
 
 /**
- * Default templates the helper users.
+ * Default config for this class
  *
  * @var array
  */
-	protected $_defaultTemplates = [
-		'meta' => '<meta{{attrs}}/>',
-		'metalink' => '<link href="{{url}}"{{attrs}}/>',
-		'link' => '<a href="{{url}}"{{attrs}}>{{content}}</a>',
-		'mailto' => '<a href="mailto:{{url}}"{{attrs}}>{{content}}</a>',
-		'image' => '<img src="{{url}}"{{attrs}}/>',
-		'tableheader' => '<th{{attrs}}>{{content}}</th>',
-		'tableheaderrow' => '<tr{{attrs}}>{{content}}</tr>',
-		'tablecell' => '<td{{attrs}}>{{content}}</td>',
-		'tablerow' => '<tr{{attrs}}>{{content}}</tr>',
-		'block' => '<div{{attrs}}>{{content}}</div>',
-		'blockstart' => '<div{{attrs}}>',
-		'blockend' => '</div>',
-		'tag' => '<{{tag}}{{attrs}}>{{content}}</{{tag}}>',
-		'tagstart' => '<{{tag}}{{attrs}}>',
-		'tagend' => '</{{tag}}>',
-		'tagselfclosing' => '<{{tag}}{{attrs}}/>',
-		'para' => '<p{{attrs}}>{{content}}</p>',
-		'parastart' => '<p{{attrs}}>',
-		'css' => '<link rel="{{rel}}" href="{{url}}"{{attrs}}/>',
-		'style' => '<style{{attrs}}>{{content}}</style>',
-		'charset' => '<meta http-equiv="Content-Type" content="text/html; charset={{charset}}" />',
-		'ul' => '<ul{{attrs}}>{{content}}</ul>',
-		'ol' => '<ol{{attrs}}>{{content}}</ol>',
-		'li' => '<li{{attrs}}>{{content}}</li>',
-		'javascriptblock' => '<script{{attrs}}>{{content}}</script>',
-		'javascriptstart' => '<script>',
-		'javascriptlink' => '<script src="{{url}}"{{attrs}}></script>',
-		'javascriptend' => '</script>'
+	protected $_defaultConfig = [
+		'templates' => [
+			'meta' => '<meta{{attrs}}/>',
+			'metalink' => '<link href="{{url}}"{{attrs}}/>',
+			'link' => '<a href="{{url}}"{{attrs}}>{{content}}</a>',
+			'mailto' => '<a href="mailto:{{url}}"{{attrs}}>{{content}}</a>',
+			'image' => '<img src="{{url}}"{{attrs}}/>',
+			'tableheader' => '<th{{attrs}}>{{content}}</th>',
+			'tableheaderrow' => '<tr{{attrs}}>{{content}}</tr>',
+			'tablecell' => '<td{{attrs}}>{{content}}</td>',
+			'tablerow' => '<tr{{attrs}}>{{content}}</tr>',
+			'block' => '<div{{attrs}}>{{content}}</div>',
+			'blockstart' => '<div{{attrs}}>',
+			'blockend' => '</div>',
+			'tag' => '<{{tag}}{{attrs}}>{{content}}</{{tag}}>',
+			'tagstart' => '<{{tag}}{{attrs}}>',
+			'tagend' => '</{{tag}}>',
+			'tagselfclosing' => '<{{tag}}{{attrs}}/>',
+			'para' => '<p{{attrs}}>{{content}}</p>',
+			'parastart' => '<p{{attrs}}>',
+			'css' => '<link rel="{{rel}}" href="{{url}}"{{attrs}}/>',
+			'style' => '<style{{attrs}}>{{content}}</style>',
+			'charset' => '<meta http-equiv="Content-Type" content="text/html; charset={{charset}}" />',
+			'ul' => '<ul{{attrs}}>{{content}}</ul>',
+			'ol' => '<ol{{attrs}}>{{content}}</ol>',
+			'li' => '<li{{attrs}}>{{content}}</li>',
+			'javascriptblock' => '<script{{attrs}}>{{content}}</script>',
+			'javascriptstart' => '<script>',
+			'javascriptlink' => '<script src="{{url}}"{{attrs}}></script>',
+			'javascriptend' => '</script>'
+		]
 	];
 
 /**
@@ -128,13 +130,11 @@ class HtmlHelper extends Helper {
  * Using the `templates` option you can redefine the tag HtmlHelper will use.
  *
  * @param View $View The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper.
+ * @param array $config Configuration settings for the helper.
  */
-	public function __construct(View $View, $settings = array()) {
-		parent::__construct($View, $settings);
+	public function __construct(View $View, $config = array()) {
+		parent::__construct($View, $config);
 		$this->response = $this->_View->response ?: new Response();
-
-		$this->initStringTemplates($this->_defaultTemplates);
 	}
 
 /**
@@ -243,17 +243,17 @@ class HtmlHelper extends Helper {
 			if (isset($options['rel']) && $options['rel'] === 'icon') {
 				$out = $this->formatTemplate('metalink', [
 					'url' => $options['link'],
-					'attrs' => $this->_templater->formatAttributes($options, ['block', 'link'])
+					'attrs' => $this->templater()->formatAttributes($options, ['block', 'link'])
 				]);
 				$options['rel'] = 'shortcut icon';
 			}
 			$out .= $this->formatTemplate('metalink', [
 				'url' => $options['link'],
-				'attrs' => $this->_templater->formatAttributes($options, ['block', 'link'])
+				'attrs' => $this->templater()->formatAttributes($options, ['block', 'link'])
 			]);
 		} else {
 			$out = $this->formatTemplate('meta', [
-				'attrs' => $this->_templater->formatAttributes($options, ['block', 'type'])
+				'attrs' => $this->templater()->formatAttributes($options, ['block', 'type'])
 			]);
 		}
 
@@ -346,7 +346,7 @@ class HtmlHelper extends Helper {
 		}
 		return $this->formatTemplate('link', [
 			'url' => $url,
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 			'content' => $title
 		]);
 	}
@@ -422,14 +422,14 @@ class HtmlHelper extends Helper {
 
 		if ($options['rel'] == 'import') {
 			$out = $this->formatTemplate('style', [
-				'attrs' => $this->_templater->formatAttributes($options, ['rel', 'block']),
+				'attrs' => $this->templater()->formatAttributes($options, ['rel', 'block']),
 				'content' => '@import url(' . $url . ');',
 			]);
 		} else {
 			$out = $this->formatTemplate('css', [
 				'rel' => $options['rel'],
 				'url' => $url,
-				'attrs' => $this->_templater->formatAttributes($options, ['rel', 'block']),
+				'attrs' => $this->templater()->formatAttributes($options, ['rel', 'block']),
 			]);
 		}
 
@@ -502,7 +502,7 @@ class HtmlHelper extends Helper {
 		}
 		$out = $this->formatTemplate('javascriptlink', [
 			'url' => $url,
-			'attrs' => $this->_templater->formatAttributes($options, ['block', 'once']),
+			'attrs' => $this->templater()->formatAttributes($options, ['block', 'once']),
 		]);
 
 		if (empty($options['block'])) {
@@ -537,7 +537,7 @@ class HtmlHelper extends Helper {
 		unset($options['safe']);
 
 		$out = $this->formatTemplate('javascriptblock', [
-			'attrs' => $this->_templater->formatAttributes($options, ['block']),
+			'attrs' => $this->templater()->formatAttributes($options, ['block']),
 			'content' => $script
 		]);
 
@@ -702,12 +702,12 @@ class HtmlHelper extends Helper {
 			}
 			$result .= $this->formatTemplate('li', [
 				'content' => $elementContent,
-				'attrs' => $this->_templater->formatAttributes($options)
+				'attrs' => $this->templater()->formatAttributes($options)
 			]);
 		}
 		return $this->formatTemplate('ul', [
 			'content' => $result,
-			'attrs' => $this->_templater->formatAttributes($ulOptions)
+			'attrs' => $this->templater()->formatAttributes($ulOptions)
 		]);
 	}
 
@@ -777,7 +777,7 @@ class HtmlHelper extends Helper {
 
 		$image = $this->formatTemplate('image', [
 			'url' => $path,
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 		]);
 
 		if ($url) {
@@ -805,18 +805,18 @@ class HtmlHelper extends Helper {
 		foreach ($names as $arg) {
 			if (!is_array($arg)) {
 				$out[] = $this->formatTemplate('tableheader', [
-					'attrs' => $this->_templater->formatAttributes($thOptions),
+					'attrs' => $this->templater()->formatAttributes($thOptions),
 					'content' => $arg
 				]);
 			} else {
 				$out[] = $this->formatTemplate('tableheader', [
-					'attrs' => $this->_templater->formatAttributes(current($arg)),
+					'attrs' => $this->templater()->formatAttributes(current($arg)),
 					'content' => key($arg)
 				]);
 			}
 		}
 		return $this->formatTemplate('tablerow', [
-			'attrs' => $this->_templater->formatAttributes($trOptions),
+			'attrs' => $this->templater()->formatAttributes($trOptions),
 			'content' => implode(' ', $out)
 		]);
 	}
@@ -868,13 +868,13 @@ class HtmlHelper extends Helper {
 					$cellOptions['class'] = 'column-' . ++$i;
 				}
 				$cellsOut[] = $this->formatTemplate('tablecell', [
-					'attrs' => $this->_templater->formatAttributes($cellOptions),
+					'attrs' => $this->templater()->formatAttributes($cellOptions),
 					'content' => $cell
 				]);
 			}
 			$opts = $count % 2 ? $oddTrOptions : $evenTrOptions;
 			$out[] = $this->formatTemplate('tablerow', [
-				'attrs' => $this->_templater->formatAttributes($opts),
+				'attrs' => $this->templater()->formatAttributes($opts),
 				'content' => implode(' ', $cellsOut),
 			]);
 		}
@@ -909,7 +909,7 @@ class HtmlHelper extends Helper {
 			$tag = 'tag';
 		}
 		return $this->formatTemplate($tag, [
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 			'tag' => $name,
 			'content' => $text,
 		]);
@@ -961,7 +961,7 @@ class HtmlHelper extends Helper {
 			$tag = 'parastart';
 		}
 		return $this->formatTemplate($tag, [
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 			'content' => $text,
 		]);
 	}
@@ -1046,7 +1046,7 @@ class HtmlHelper extends Helper {
 				$source['src'] = $this->assetUrl($source['src'], $options);
 				$sourceTags .= $this->formatTemplate('tagselfclosing', [
 					'tag' => 'source',
-					'attrs' => $this->_templater->formatAttributes($source)
+					'attrs' => $this->templater()->formatAttributes($source)
 				]);
 			}
 			unset($source);
@@ -1103,7 +1103,7 @@ class HtmlHelper extends Helper {
 		}
 		$items = $this->_nestedListItem($list, $options, $itemOptions, $tag);
 		return $this->formatTemplate($tag, [
-			'attrs' => $this->_templater->formatAttributes($options),
+			'attrs' => $this->templater()->formatAttributes($options),
 			'content' => $items
 		]);
 	}
@@ -1132,7 +1132,7 @@ class HtmlHelper extends Helper {
 				$itemOptions['class'] = $itemOptions['odd'];
 			}
 			$out .= $this->formatTemplate('li', [
-				'attrs' => $this->_templater->formatAttributes($itemOptions, ['even', 'odd']),
+				'attrs' => $this->templater()->formatAttributes($itemOptions, ['even', 'odd']),
 				'content' => $item
 			]);
 			$index++;

+ 18 - 7
src/View/Helper/NumberHelper.php

@@ -31,6 +31,15 @@ use Cake\View\View;
 class NumberHelper extends Helper {
 
 /**
+ * Default config for this class
+ *
+ * @var mixed
+ */
+	protected $_defaultConfig = [
+		'engine' => 'Cake\Utility\Number'
+	];
+
+/**
  * Cake\Utility\Number instance
  *
  * @var \Cake\Utility\Number
@@ -46,17 +55,19 @@ class NumberHelper extends Helper {
  *            The class needs to be placed in the `Utility` directory.
  *
  * @param View $View The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper
+ * @param array $config Configuration settings for the helper
  * @throws \Cake\Error\Exception When the engine class could not be found.
  */
-	public function __construct(View $View, $settings = array()) {
-		$settings = Hash::merge(array('engine' => 'Cake\Utility\Number'), $settings);
-		parent::__construct($View, $settings);
-		$engineClass = App::classname($settings['engine'], 'Utility');
+	public function __construct(View $View, $config = array()) {
+		parent::__construct($View, $config);
+
+		$config = $this->config();
+
+		$engineClass = App::classname($config['engine'], 'Utility');
 		if ($engineClass) {
-			$this->_engine = new $engineClass($settings);
+			$this->_engine = new $engineClass($config);
 		} else {
-			throw new Error\Exception(sprintf('Class for %s could not be found', $settings['engine']));
+			throw new Error\Exception(sprintf('Class for %s could not be found', $config['engine']));
 		}
 	}
 

+ 48 - 55
src/View/Helper/PaginatorHelper.php

@@ -30,7 +30,9 @@ class PaginatorHelper extends Helper {
 	use StringTemplateTrait;
 
 /**
- * Holds the default options for pagination links
+ * Defualt config for this class
+ *
+ * Options: Holds the default options for pagination links
  *
  * The values that may be specified are:
  *
@@ -41,46 +43,33 @@ class PaginatorHelper extends Helper {
  * - `model` The name of the model.
  * - `escape` Defines if the title field for the link should be escaped (default: true).
  *
- * @var array
- */
-	public $options = [];
-
-/**
- * The default templates used by PaginatorHelper.
+ * Templates: the templates used by this class
  *
  * @var array
  */
-	protected $_defaultTemplates = [
-		'nextActive' => '<li class="next"><a rel="next" href="{{url}}">{{text}}</a></li>',
-		'nextDisabled' => '<li class="next disabled"><span>{{text}}</span></li>',
-		'prevActive' => '<li class="prev"><a rel="prev" href="{{url}}">{{text}}</a></li>',
-		'prevDisabled' => '<li class="prev disabled"><span>{{text}}</span></li>',
-		'counterRange' => '{{start}} - {{end}} of {{count}}',
-		'counterPages' => '{{page}} of {{pages}}',
-		'first' => '<li class="first"><a href="{{url}}">{{text}}</a></li>',
-		'last' => '<li class="last"><a href="{{url}}">{{text}}</a></li>',
-		'number' => '<li><a href="{{url}}">{{text}}</a></li>',
-		'current' => '<li class="active"><span>{{text}}</span></li>',
-		'ellipsis' => '<li class="ellipsis">...</li>',
-		'sort' => '<a href="{{url}}">{{text}}</a>',
-		'sortAsc' => '<a class="asc" href="{{url}}">{{text}}</a>',
-		'sortDesc' => '<a class="desc" href="{{url}}">{{text}}</a>',
-		'sortAscLocked' => '<a class="asc locked" href="{{url}}">{{text}}</a>',
-		'sortDescLocked' => '<a class="desc locked" href="{{url}}">{{text}}</a>',
+	protected $_defaultConfig = [
+		'options' => [],
+		'templates' => [
+			'nextActive' => '<li class="next"><a rel="next" href="{{url}}">{{text}}</a></li>',
+			'nextDisabled' => '<li class="next disabled"><span>{{text}}</span></li>',
+			'prevActive' => '<li class="prev"><a rel="prev" href="{{url}}">{{text}}</a></li>',
+			'prevDisabled' => '<li class="prev disabled"><span>{{text}}</span></li>',
+			'counterRange' => '{{start}} - {{end}} of {{count}}',
+			'counterPages' => '{{page}} of {{pages}}',
+			'first' => '<li class="first"><a href="{{url}}">{{text}}</a></li>',
+			'last' => '<li class="last"><a href="{{url}}">{{text}}</a></li>',
+			'number' => '<li><a href="{{url}}">{{text}}</a></li>',
+			'current' => '<li class="active"><span>{{text}}</span></li>',
+			'ellipsis' => '<li class="ellipsis">...</li>',
+			'sort' => '<a href="{{url}}">{{text}}</a>',
+			'sortAsc' => '<a class="asc" href="{{url}}">{{text}}</a>',
+			'sortDesc' => '<a class="desc" href="{{url}}">{{text}}</a>',
+			'sortAscLocked' => '<a class="asc locked" href="{{url}}">{{text}}</a>',
+			'sortDescLocked' => '<a class="desc locked" href="{{url}}">{{text}}</a>',
+		]
 	];
 
 /**
- * Constructor
- *
- * @param View $View The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper.
- */
-	public function __construct(View $View, $settings = []) {
-		parent::__construct($View, $settings);
-		$this->initStringTemplates($this->_defaultTemplates);
-	}
-
-/**
  * Before render callback. Overridden to merge passed args with URL options.
  *
  * @param \Cake\Event\Event $event The event instance.
@@ -88,7 +77,10 @@ class PaginatorHelper extends Helper {
  * @return void
  */
 	public function beforeRender($event, $viewFile) {
-		$this->options['url'] = array_merge($this->request->params['pass'], $this->request->query);
+		$this->config(
+			'options.url',
+			array_merge($this->request->params['pass'], $this->request->query)
+		);
 	}
 
 /**
@@ -151,7 +143,7 @@ class PaginatorHelper extends Helper {
 			);
 			unset($options[$model]);
 		}
-		$this->options = array_filter(array_merge($this->options, $options));
+		$this->_config['options'] = array_filter(array_merge($this->config('options'), $options));
 	}
 
 /**
@@ -237,7 +229,7 @@ class PaginatorHelper extends Helper {
 		$text = $options['escape'] ? h($text) : $text;
 
 		if (!$enabled) {
-			return $this->_templater->format($template, [
+			return $this->templater()->format($template, [
 				'text' => $text,
 			]);
 		}
@@ -248,7 +240,7 @@ class PaginatorHelper extends Helper {
 			['page' => $paging['page'] + $options['step']]
 		);
 		$url = $this->url($url, $options['model']);
-		return $this->_templater->format($template, [
+		return $this->templater()->format($template, [
 			'url' => $url,
 			'text' => $text,
 		]);
@@ -397,7 +389,7 @@ class PaginatorHelper extends Helper {
 			'text' => $options['escape'] ? h($title) : $title,
 			'url' => $this->url($url, $options['model']),
 		];
-		return $this->_templater->format($template, $vars);
+		return $this->templater()->format($template, $vars);
 	}
 
 /**
@@ -418,8 +410,9 @@ class PaginatorHelper extends Helper {
 			'direction' => $paging['direction'],
 		];
 
-		if (!empty($this->options['url'])) {
-			$url = array_merge($this->options['url'], $url);
+		$defaultUrl = $this->config('options.url');
+		if ($defaultUrl) {
+			$url = array_merge($defaultUrl, $url);
 		}
 		$url = array_merge(array_filter($url), $options);
 
@@ -551,7 +544,7 @@ class PaginatorHelper extends Helper {
 				break;
 			default:
 				$template = 'counterCustom';
-				$this->_templater->add([$template => $options['format']]);
+				$this->templater()->add([$template => $options['format']]);
 		}
 		$map = [
 			'page' => $paging['page'],
@@ -562,7 +555,7 @@ class PaginatorHelper extends Helper {
 			'end' => $end,
 			'model' => strtolower(Inflector::humanize(Inflector::tableize($options['model'])))
 		];
-		return $this->_templater->format($template, $map);
+		return $this->templater()->format($template, $map);
 	}
 
 /**
@@ -612,7 +605,7 @@ class PaginatorHelper extends Helper {
 		}
 
 		$out = '';
-		$ellipsis = $this->_templater->format('ellipsis', []);
+		$ellipsis = $this->templater()->format('ellipsis', []);
 
 		if ($options['modulus'] && $params['pageCount'] > $options['modulus']) {
 			$half = intval($options['modulus'] / 2);
@@ -642,10 +635,10 @@ class PaginatorHelper extends Helper {
 					'text' => $i,
 					'url' => $this->url(['page' => $i], $options['model']),
 				];
-				$out .= $this->_templater->format('number', $vars);
+				$out .= $this->templater()->format('number', $vars);
 			}
 
-			$out .= $this->_templater->format('current', [
+			$out .= $this->templater()->format('current', [
 				'text' => $params['page'],
 				'url' => $this->url(['page' => $params['page']], $options['model']),
 			]);
@@ -656,7 +649,7 @@ class PaginatorHelper extends Helper {
 					'text' => $i,
 					'url' => $this->url(['page' => $i], $options['model']),
 				];
-				$out .= $this->_templater->format('number', $vars);
+				$out .= $this->templater()->format('number', $vars);
 			}
 
 			if ($end != $params['page']) {
@@ -664,7 +657,7 @@ class PaginatorHelper extends Helper {
 					'text' => $i,
 					'url' => $this->url(['page' => $end], $options['model']),
 				];
-				$out .= $this->_templater->format('number', $vars);
+				$out .= $this->templater()->format('number', $vars);
 			}
 
 			$out .= $options['after'];
@@ -682,7 +675,7 @@ class PaginatorHelper extends Helper {
 
 			for ($i = 1; $i <= $params['pageCount']; $i++) {
 				if ($i == $params['page']) {
-					$out .= $this->_templater->format('current', [
+					$out .= $this->templater()->format('current', [
 						'text' => $params['page'],
 						'url' => $this->url(['page' => $params['page']], $options['model']),
 					]);
@@ -691,7 +684,7 @@ class PaginatorHelper extends Helper {
 						'text' => $i,
 						'url' => $this->url(['page' => $i], $options['model']),
 					];
-					$out .= $this->_templater->format('number', $vars);
+					$out .= $this->templater()->format('number', $vars);
 				}
 			}
 
@@ -740,14 +733,14 @@ class PaginatorHelper extends Helper {
 
 		if (is_int($first) && $params['page'] >= $first) {
 			for ($i = 1; $i <= $first; $i++) {
-				$out .= $this->_templater->format('number', [
+				$out .= $this->templater()->format('number', [
 					'url' => $this->url(['page' => $i], $options['model']),
 					'text' => $i
 				]);
 			}
 		} elseif ($params['page'] > 1 && is_string($first)) {
 			$first = $options['escape'] ? h($first) : $first;
-			$out .= $this->_templater->format('first', [
+			$out .= $this->templater()->format('first', [
 				'url' => $this->url(['page' => 1], $options['model']),
 				'text' => $first
 			]);
@@ -793,14 +786,14 @@ class PaginatorHelper extends Helper {
 
 		if (is_int($last) && $params['page'] <= $lower) {
 			for ($i = $lower; $i <= $params['pageCount']; $i++) {
-				$out .= $this->_templater->format('number', [
+				$out .= $this->templater()->format('number', [
 					'url' => $this->url(['page' => $i], $options['model']),
 					'text' => $i
 				]);
 			}
 		} elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
 			$last = $options['escape'] ? h($last) : $last;
-			$out .= $this->_templater->format('last', [
+			$out .= $this->templater()->format('last', [
 				'url' => $this->url(['page' => $params['pageCount']], $options['model']),
 				'text' => $last
 			]);

+ 5 - 16
src/View/Helper/SessionHelper.php

@@ -31,28 +31,17 @@ class SessionHelper extends Helper {
 	use StringTemplateTrait;
 
 /**
- * Default templates to use.
+ * Default config for this class
  *
  * @var array
  */
-	protected $_defaultTemplates = [
-		'flash' => '<div id="{{key}}-message" class="{{class}}">{{message}}</div>'
+	protected $_defaultConfig = [
+		'templates' => [
+			'flash' => '<div id="{{key}}-message" class="{{class}}">{{message}}</div>'
+		]
 	];
 
 /**
- * Construct the helper and sets up templates
- *
- * @param \Cake\View\View $view The View this helper is being attached to.
- * @param array $settings Configuration settings for the helper.
- */
-	public function __construct(View $view, $settings = []) {
-		$settings += ['templates' => null];
-		parent::__construct($view, $settings);
-
-		$this->initStringTemplates($this->_defaultTemplates);
-	}
-
-/**
  * Used to read a session values set in a controller for a key or return values for all keys.
  *
  * In your view: `$this->Session->read('Controller.sessKey');`

+ 22 - 26
src/View/Helper/StringTemplateTrait.php

@@ -30,26 +30,6 @@ trait StringTemplateTrait {
 	protected $_templater;
 
 /**
- * Initializes the StringTemplate class and loads templates
- *
- * @param array $templates
- * @param string $templateClass Class name of the template class to instantiate
- * @return void
- */
-	public function initStringTemplates($templates = [], $templateClass = '\Cake\View\StringTemplate') {
-		$this->_templater = new $templateClass($templates);
-		if (empty($this->settings['templates'])) {
-			return;
-		}
-		if (is_string($this->settings['templates'])) {
-			$this->_templater->load($this->settings['templates']);
-		}
-		if (is_array($this->settings['templates'])) {
-			$this->_templater->add($this->settings['templates']);
-		}
-	}
-
-/**
  * Get/set templates to use.
  *
  * @param string|null|array $templates null or string allow reading templates. An array
@@ -58,9 +38,10 @@ trait StringTemplateTrait {
  */
 	public function templates($templates = null) {
 		if ($templates === null || is_string($templates)) {
-			return $this->_templater->get($templates);
+			return $this->templater()->get($templates);
 		}
-		return $this->_templater->add($templates);
+
+		return $this->templater()->add($templates);
 	}
 
 /**
@@ -71,15 +52,30 @@ trait StringTemplateTrait {
  * @return string
  */
 	public function formatTemplate($name, $data) {
-		return $this->_templater->format($name, $data);
+		return $this->templater()->format($name, $data);
 	}
 
 /**
- * Returns the template engine object
+ * templater
  *
- * @return StringTemplate
+ * @return void
  */
-	public function getTemplater() {
+	public function templater() {
+		if (empty($this->_templater)) {
+			$class = $this->config('templateClass') ?: '\Cake\View\StringTemplate';
+			$this->_templater = new $class;
+
+			$templates = $this->config('templates');
+
+			if ($templates) {
+				if (is_string($templates)) {
+					$this->_templater->load($templates);
+				} else {
+					$this->_templater->add($templates);
+				}
+			}
+		}
+
 		return $this->_templater;
 	}
 

+ 17 - 7
src/View/Helper/TextHelper.php

@@ -39,6 +39,15 @@ class TextHelper extends Helper {
 	public $helpers = array('Html');
 
 /**
+ * Default config for this class
+ *
+ * @var array
+ */
+	protected $_defaultConfig = [
+		'engine' => 'Cake\Utility\String'
+	];
+
+/**
  * An array of md5sums and their contents.
  * Used when inserting links into text.
  *
@@ -62,17 +71,18 @@ class TextHelper extends Helper {
  *            The class needs to be placed in the `Utility` directory.
  *
  * @param View $View the view object the helper is attached to.
- * @param array $settings Settings array Settings array
+ * @param array $config Settings array Settings array
  * @throws \Cake\Error\Exception when the engine class could not be found.
  */
-	public function __construct(View $View, $settings = array()) {
-		$settings = Hash::merge(array('engine' => 'Cake\Utility\String'), $settings);
-		parent::__construct($View, $settings);
-		$engineClass = App::classname($settings['engine'], 'Utility');
+	public function __construct(View $View, $config = array()) {
+		parent::__construct($View, $config);
+
+		$config = $this->config();
+		$engineClass = App::classname($config['engine'], 'Utility');
 		if ($engineClass) {
-			$this->_engine = new $engineClass($settings);
+			$this->_engine = new $engineClass($config);
 		} else {
-			throw new Error\Exception(sprintf('Class for %s could not be found', $settings['engine']));
+			throw new Error\Exception(sprintf('Class for %s could not be found', $config['engine']));
 		}
 	}
 

+ 19 - 9
src/View/Helper/TimeHelper.php

@@ -35,6 +35,15 @@ class TimeHelper extends Helper {
 	use StringTemplateTrait;
 
 /**
+ * Default config for this class
+ *
+ * @var array
+ */
+	protected $_defaultConfig = [
+		'engine' => 'Cake\Utility\Time'
+	];
+
+/**
  * Cake\Utility\Time instance
  *
  * @var \Cake\Utility\Time
@@ -50,19 +59,20 @@ class TimeHelper extends Helper {
  *            The class needs to be placed in the `Utility` directory.
  *
  * @param View $View the view object the helper is attached to.
- * @param array $settings Settings array
+ * @param array $config Settings array
  * @throws \Cake\Error\Exception When the engine class could not be found.
  */
-	public function __construct(View $View, $settings = array()) {
-		$settings = Hash::merge(array('engine' => 'Cake\Utility\Time'), $settings);
-		parent::__construct($View, $settings);
-		$engineClass = App::classname($settings['engine'], 'Utility');
+	public function __construct(View $View, $config = array()) {
+		parent::__construct($View, $config);
+
+		$config = $this->config();
+
+		$engineClass = App::classname($config['engine'], 'Utility');
 		if ($engineClass) {
-			$this->_engine = new $engineClass($settings);
+			$this->_engine = new $engineClass($config);
 		} else {
-			throw new Error\Exception(sprintf('Class for %s could not be found', $settings['engine']));
+			throw new Error\Exception(sprintf('Class for %s could not be found', $config['engine']));
 		}
-		$this->initStringTemplates();
 	}
 
 /**
@@ -349,7 +359,7 @@ class TimeHelper extends Helper {
 			$relativeDate = sprintf(
 				'<%s%s>%s</%s>',
 				$element['tag'],
-				$this->_templater->formatAttributes($element, array('tag')),
+				$this->templater()->formatAttributes($element, array('tag')),
 				$relativeDate,
 				$element['tag']
 			);

+ 11 - 33
src/View/StringTemplate.php

@@ -15,6 +15,7 @@
 namespace Cake\View;
 
 use Cake\Configure\Engine\PhpConfig;
+use Cake\Core\InstanceConfigTrait;
 use Cake\Core\Plugin;
 use Cake\Error;
 
@@ -27,6 +28,11 @@ use Cake\Error;
  */
 class StringTemplate {
 
+	use InstanceConfigTrait {
+		config as add;
+		config as get;
+	}
+
 /**
  * List of attributes that can be made compact.
  *
@@ -39,11 +45,11 @@ class StringTemplate {
 	);
 
 /**
- * The templates this instance holds.
+ * The default templates this instance holds.
  *
  * @var array
  */
-	protected $_templates = [
+	protected $_defaultConfig = [
 		'attribute' => '{{name}}="{{value}}"',
 		'compactAttribute' => '{{name}}="{{value}}"',
 	];
@@ -53,10 +59,8 @@ class StringTemplate {
  *
  * @param array $templates A set of templates to add.
  */
-	public function __construct(array $templates = null) {
-		if ($templates) {
-			$this->add($templates);
-		}
+	public function __construct(array $config = null) {
+		$this->config($config);
 	}
 
 /**
@@ -76,39 +80,13 @@ class StringTemplate {
 	}
 
 /**
- * Add one or more template strings.
- *
- * @param array $templates The templates to add.
- * @return void
- */
-	public function add(array $templates) {
-		$this->_templates = array_merge($this->_templates, $templates);
-	}
-
-/**
- * Get one or all templates.
- *
- * @param string $name Leave null to get all templates, provide a name to get a single template.
- * @return string|array|null Either the template(s) or null
- */
-	public function get($name = null) {
-		if ($name === null) {
-			return $this->_templates;
-		}
-		if (!isset($this->_templates[$name])) {
-			return null;
-		}
-		return $this->_templates[$name];
-	}
-
-/**
  * Remove the named template.
  *
  * @param string $name The template to remove.
  * @return void
  */
 	public function remove($name) {
-		unset($this->_templates[$name]);
+		$this->config($name, null);
 	}
 
 /**

+ 3 - 2
tests/TestCase/View/Helper/FormHelperTest.php

@@ -1610,6 +1610,7 @@ class FormHelperTest extends TestCase {
 				'groupContainerError' => '<div class="input {{type}}{{required}} error">{{content}}</div>'
 			]
 		]);
+
 		$expected = [
 			'div' => ['class' => 'input text error'],
 			'label' => ['for' => 'article-title'],
@@ -5811,10 +5812,10 @@ class FormHelperTest extends TestCase {
  */
 	public function testResetTemplates() {
 		$this->Form->templates(['input' => '<input>']);
-		$this->assertEquals('<input>', $this->Form->getTemplater()->get('input'));
+		$this->assertEquals('<input>', $this->Form->templater()->get('input'));
 
 		$this->assertNull($this->Form->resetTemplates());
-		$this->assertNotEquals('<input>', $this->Form->getTemplater()->get('input'));
+		$this->assertNotEquals('<input>', $this->Form->templater()->get('input'));
 	}
 
 }

+ 49 - 22
tests/TestCase/View/Helper/StringTemplateTraitTest.php

@@ -14,11 +14,29 @@
  */
 namespace Cake\Test\TestCase\View\Helper;
 
+use Cake\Core\InstanceConfigTrait;
 use Cake\TestSuite\TestCase;
 use Cake\View\Helper\StringTemplate;
 use Cake\View\Helper\StringTemplateTrait;
 
 /**
+ * TestStringTemplate
+ *
+ */
+class TestStringTemplate {
+
+	use InstanceConfigTrait;
+	use StringTemplateTrait;
+
+/**
+ * _defaultConfig
+ *
+ * @var array
+ */
+	protected $_defaultConfig = [];
+}
+
+/**
  * StringTemplateTraitTest class
  *
  */
@@ -31,7 +49,7 @@ class StringTemplateTraitTest extends TestCase {
  */
 	public function setUp() {
 		parent::setUp();
-		$this->Template = $this->getObjectForTrait('\Cake\View\Helper\StringTemplateTrait');
+		$this->Template = new TestStringTemplate;
 	}
 
 /**
@@ -43,14 +61,17 @@ class StringTemplateTraitTest extends TestCase {
 		$templates = [
 			'text' => '<p>{{text}}</p>',
 		];
-		$this->Template->initStringTemplates($templates);
+		$this->Template->templates($templates);
 
-		$result = $this->Template->templates(null);
-		$this->assertEquals($result, [
-			'attribute' => '{{name}}="{{value}}"',
-			'compactAttribute' => '{{name}}="{{value}}"',
-			'text' => '<p>{{text}}</p>'
-		]);
+		$this->assertEquals(
+			[
+				'attribute' => '{{name}}="{{value}}"',
+				'compactAttribute' => '{{name}}="{{value}}"',
+				'text' => '<p>{{text}}</p>'
+			],
+			$this->Template->templates(),
+			'newly added template should be inlcuded in template list'
+		);
 	}
 
 /**
@@ -59,17 +80,20 @@ class StringTemplateTraitTest extends TestCase {
  * @return void
  */
 	public function testInitStringTemplatesArrayForm() {
-		$this->Template->settings['templates'] = [
-			'text' => '<p>{{text}}</p>',
-		];
-		$this->Template->initStringTemplates();
+		$this->Template->config(
+			'templates.text',
+			'<p>{{text}}</p>'
+		);
 
-		$result = $this->Template->templates(null);
-		$this->assertEquals($result, [
-			'attribute' => '{{name}}="{{value}}"',
-			'compactAttribute' => '{{name}}="{{value}}"',
-			'text' => '<p>{{text}}</p>'
-		]);
+		$this->assertEquals(
+			[
+				'attribute' => '{{name}}="{{value}}"',
+				'compactAttribute' => '{{name}}="{{value}}"',
+				'text' => '<p>{{text}}</p>'
+			],
+			$this->Template->templates(),
+			'Configured templates should be included in template list'
+		);
 	}
 
 /**
@@ -81,11 +105,14 @@ class StringTemplateTraitTest extends TestCase {
 		$templates = [
 			'text' => '<p>{{text}}</p>',
 		];
-		$this->Template->initStringTemplates($templates);
+		$this->Template->templates($templates);
 		$result = $this->Template->formatTemplate('text', [
 			'text' => 'CakePHP'
 		]);
-		$this->assertEquals($result, '<p>CakePHP</p>');
+		$this->assertEquals(
+			'<p>CakePHP</p>',
+			$result
+		);
 	}
 
 /**
@@ -97,8 +124,8 @@ class StringTemplateTraitTest extends TestCase {
 		$templates = [
 			'text' => '<p>{{text}}</p>',
 		];
-		$this->Template->initStringTemplates($templates);
-		$result = $this->Template->getTemplater();
+		$this->Template->templates($templates);
+		$result = $this->Template->templater();
 		$this->assertInstanceOf('\Cake\View\StringTemplate', $result);
 	}
 

+ 2 - 2
tests/TestCase/View/HelperTest.php

@@ -135,7 +135,7 @@ class TestHelper extends Helper {
  *
  * @var array
  */
-	public $settings = array(
+	protected $_defaultConfig = array(
 		'key1' => 'val1',
 		'key2' => array('key2.1' => 'val2.1', 'key2.2' => 'val2.2')
 	);
@@ -211,7 +211,7 @@ class HelperTest extends TestCase {
 			'key2' => array('key2.1' => 'val2.1', 'key2.2' => 'newval'),
 			'key3' => 'val3'
 		);
-		$this->assertEquals($expected, $Helper->settings);
+		$this->assertEquals($expected, $Helper->config());
 	}
 
 /**