Updating HtmlHelper to allow custom blocks.

Adding tests for blocks.
Adding missing tests.
This commit is contained in:
mark_story 2011-09-15 21:10:22 -04:00
parent 7854f9dd52
commit 82139fe8f6
3 changed files with 102 additions and 23 deletions

View file

@ -655,11 +655,34 @@ class HtmlHelperTest extends CakeTestCase {
); );
$this->assertTags($result, $expected); $this->assertTags($result, $expected);
$this->View->expects($this->any()) }
/**
* test that script() works with blocks.
*
* @return void
*/
public function testScriptWithBlocks() {
$this->View->expects($this->at(0))
->method('append') ->method('append')
->with('script', $this->matchesRegularExpression('/script_in_head.js/')); ->with('script', $this->matchesRegularExpression('/script_in_head.js/'));
$this->View->expects($this->at(1))
->method('append')
->with('script', $this->matchesRegularExpression('/bool_false.js/'));
$this->View->expects($this->at(2))
->method('append')
->with('headScripts', $this->matchesRegularExpression('/second_script.js/'));
$result = $this->Html->script('script_in_head', array('inline' => false)); $result = $this->Html->script('script_in_head', array('inline' => false));
$this->assertNull($result); $this->assertNull($result);
$result = $this->Html->script('bool_false', false);
$this->assertNull($result);
$result = $this->Html->script('second_script', array('block' => 'headScripts'));
$this->assertNull($result);
} }
/** /**
@ -1249,12 +1272,25 @@ class HtmlHelperTest extends CakeTestCase {
$this->assertTags($result, array('meta' => array('name' => 'ROBOTS', 'content' => 'ALL'))); $this->assertTags($result, array('meta' => array('name' => 'ROBOTS', 'content' => 'ALL')));
$this->View->expects($this->any()) }
/**
* Test the inline and block options for meta()
*/
public function testMetaWithBlocks() {
$this->View->expects($this->at(0))
->method('append') ->method('append')
->with('meta', $this->matchesRegularExpression('/^<meta/')); ->with('meta', $this->stringContains('ROBOTS'));
$this->View->expects($this->at(1))
->method('append')
->with('metaTags', $this->stringContains('favicon.ico'));
$result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'), null, array('inline' => false)); $result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'), null, array('inline' => false));
$this->assertNull($result); $this->assertNull($result);
$result = $this->Html->meta('icon', 'favicon.ico', array('block' => 'metaTags'));
$this->assertNull($result);
} }
/** /**

View file

@ -218,9 +218,24 @@ class HtmlHelper extends AppHelper {
/** /**
* Creates a link to an external resource and handles basic meta tags * Creates a link to an external resource and handles basic meta tags
* *
* Create a meta tag that is output inline:
*
* `$this->Html->meta('icon', 'favicon.ico');
*
* Append the meta tag to `$scripts_for_layout`:
*
* `$this->Html->meta('description', 'A great page', array('inline' => false));`
*
* Append the meta tag to custom view block:
*
* `$this->Html->meta('description', 'A great page', array('block' => 'metaTags'));`
*
* ### Options * ### Options
* *
* - `inline` Whether or not the link element should be output inline, or in scripts_for_layout. * - `inline` Whether or not the link element should be output inline. Set to false to
* have the meta tag included in `$scripts_for_layout`, and appended to the 'meta' view block.
* - `block` Choose a custom block to append the meta tag to. Using this option
* will override the inline option.
* *
* @param string $type The title of the external resource * @param string $type The title of the external resource
* @param mixed $url The address of the external resource or string for content attribute * @param mixed $url The address of the external resource or string for content attribute
@ -230,7 +245,10 @@ class HtmlHelper extends AppHelper {
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::meta * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::meta
*/ */
public function meta($type, $url = null, $options = array()) { public function meta($type, $url = null, $options = array()) {
$inline = isset($options['inline']) ? $options['inline'] : true; $options += array('inline' => true, 'block' => null);
if (!$options['inline'] && empty($options['block'])) {
$options['block'] = __FUNCTION__;
}
unset($options['inline']); unset($options['inline']);
if (!is_array($type)) { if (!is_array($type)) {
@ -268,20 +286,20 @@ class HtmlHelper extends AppHelper {
if (isset($options['link'])) { if (isset($options['link'])) {
if (isset($options['rel']) && $options['rel'] === 'icon') { if (isset($options['rel']) && $options['rel'] === 'icon') {
$out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); $out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
$options['rel'] = 'shortcut icon'; $options['rel'] = 'shortcut icon';
} else { } else {
$options['link'] = $this->url($options['link'], true); $options['link'] = $this->url($options['link'], true);
} }
$out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); $out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
} else { } else {
$out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('type'), ' ', ' ')); $out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('block', 'type'), ' ', ' '));
} }
if ($inline) { if (empty($options['block'])) {
return $out; return $out;
} else { } else {
$this->_View->append('meta', $out); $this->_View->append($options['block'], $out);
} }
} }
@ -377,9 +395,16 @@ class HtmlHelper extends AppHelper {
* *
* `$this->Html->css('styles.css', null, array('inline' => false));` * `$this->Html->css('styles.css', null, array('inline' => false));`
* *
* Add the stylesheet to a custom block:
*
* `$this->Html->css('styles.css', null, array('block' => 'layoutCss'));`
*
* ### Options * ### Options
* *
* - `inline` If set to false, the generated tag appears in the head tag of the layout. Defaults to true * - `inline` If set to false, the generated tag will be appended to the 'css' block,
* and included in the `$scripts_for_layout` layout variable. Defaults to true.
* - `block` Set the name of the block link/style tag will be appended to. This overrides the `inline`
* option.
* *
* @param mixed $path The name of a CSS style sheet or an array containing names of * @param mixed $path The name of a CSS style sheet or an array containing names of
* CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot * CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot
@ -390,13 +415,18 @@ class HtmlHelper extends AppHelper {
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::css * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::css
*/ */
public function css($path, $rel = null, $options = array()) { public function css($path, $rel = null, $options = array()) {
$options += array('inline' => true); $options += array('block' => null, 'inline' => true);
if (!$options['inline'] && empty($options['block'])) {
$options['block'] = __FUNCTION__;
}
unset($options['inline']);
if (is_array($path)) { if (is_array($path)) {
$out = ''; $out = '';
foreach ($path as $i) { foreach ($path as $i) {
$out .= "\n\t" . $this->css($i, $rel, $options); $out .= "\n\t" . $this->css($i, $rel, $options);
} }
if ($options['inline']) { if (empty($options['block'])) {
return $out . "\n"; return $out . "\n";
} }
return; return;
@ -433,10 +463,10 @@ class HtmlHelper extends AppHelper {
$out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' ')); $out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' '));
} }
if ($options['inline']) { if (empty($options['block'])) {
return $out; return $out;
} else { } else {
$this->_View->append(__FUNCTION__, $out); $this->_View->append($options['block'], $out);
} }
} }
@ -461,10 +491,17 @@ class HtmlHelper extends AppHelper {
* *
* `$this->Html->script('styles.js', null, array('inline' => false));` * `$this->Html->script('styles.js', null, array('inline' => false));`
* *
* Add the script file to a custom block:
*
* `$this->Html->script('styles.js', null, array('block' => 'bodyScript'));`
*
* ### Options * ### Options
* *
* - `inline` - Whether script should be output inline or into scripts_for_layout. * - `inline` Whether script should be output inline or into `$scripts_for_layout`. When set to false,
* - `once` - Whether or not the script should be checked for uniqueness. If true scripts will only be * the script tag will be appended to the 'script' view block as well as `$scripts_for_layout`.
* - `block` The name of the block you want the script appended to. Leave undefined to output inline.
* Using this option will override the inline option.
* - `once` Whether or not the script should be checked for uniqueness. If true scripts will only be
* included once, use false to allow the same script to be included more than once per request. * included once, use false to allow the same script to be included more than once per request.
* *
* @param mixed $url String or array of javascript files to include * @param mixed $url String or array of javascript files to include
@ -478,13 +515,18 @@ class HtmlHelper extends AppHelper {
list($inline, $options) = array($options, array()); list($inline, $options) = array($options, array());
$options['inline'] = $inline; $options['inline'] = $inline;
} }
$options = array_merge(array('inline' => true, 'once' => true), $options); $options = array_merge(array('block' => null, 'inline' => true, 'once' => true), $options);
if (!$options['inline'] && empty($options['block'])) {
$options['block'] = __FUNCTION__;
}
unset($options['inline']);
if (is_array($url)) { if (is_array($url)) {
$out = ''; $out = '';
foreach ($url as $i) { foreach ($url as $i) {
$out .= "\n\t" . $this->script($i, $options); $out .= "\n\t" . $this->script($i, $options);
} }
if ($options['inline']) { if (empty($options['block'])) {
return $out . "\n"; return $out . "\n";
} }
return null; return null;
@ -507,13 +549,13 @@ class HtmlHelper extends AppHelper {
$url = str_replace(JS_URL, 'cjs/', $url); $url = str_replace(JS_URL, 'cjs/', $url);
} }
} }
$attributes = $this->_parseAttributes($options, array('inline', 'once'), ' '); $attributes = $this->_parseAttributes($options, array('block', 'once'), ' ');
$out = sprintf($this->_tags['javascriptlink'], $url, $attributes); $out = sprintf($this->_tags['javascriptlink'], $url, $attributes);
if ($options['inline']) { if (empty($options['block'])) {
return $out; return $out;
} else { } else {
$this->_View->append(__FUNCTION__, $out); $this->_View->append($options['block'], $out);
} }
} }

View file

@ -536,7 +536,8 @@ class View extends Object {
* block will create the block. * block will create the block.
* *
* Calling append() without a value will create a new capturing * Calling append() without a value will create a new capturing
* block that needs to be finished with View::end() * block that needs to be finished with View::end(). The content
* of the new capturing context will be added to the existing block context.
* *
* @param string $name Name of the block * @param string $name Name of the block
* @param string $value The content for the block. * @param string $value The content for the block.