jump to navigation

Register head tags from helpers (2) March 28, 2006

Posted by rossoft in CakePHP.
trackback

Improved version of http://rossoft.wordpress.com/2006/03/23/register-javascript-css-files-from-helpers/ 

Some examples self-explanatory:

$head->register_js("test2");
$head->register_css("mycss2");
$head->register_css("mycss1",array('media'=>'print'));
$head->register_cssblock("    .modbox .el {display:none;}
                            .modbox .csl, .modbox .es {display:none;}
                            .modbox_e .el {display:none;}");
$head->register_jsblock('alert("hi!");');
$head->register_link(array(    'rel'=>'alternate',
                            'type'=>'text/xml',
                            'title'=>'General RSS 0.91',
                            'href'=>'http://www.elotrolado.net/temp/rss091.xml'));

$head->register_meta(array(    'http-equiv'=>'Content-Type',
                            'content'=>'text/html; charset=UTF-8'));

$head->register_raw('<script>alert("raw html");</script>');

Copy to /app/views/helpers/head.php

<?php
/**
 * Head Helper
 * Register <head> tags from helpers, then print them
 * in head through layout.
 * @author RosSoft
 * @license MIT
 * @version 0.2 
 */
class HeadHelper extends Helper
{
    var $helpers=array('html','javascript');
   
    var $_library; //static array of items to be included            

    function __construct()
    {
           static $library=array();  //for php4 compat
           $this->_library=& $library;
    }

    /**
     * Adds a css file to array
     * @param string $file CSS file to be included
     * @param string $param Array of htmlAttributes
     */
    function register_css($file,$htmlAttributes=null)
    {
        $this->_register(array($file,'css',$htmlAttributes));
    }
   
    /**
     * Adds an inline css block to array
     * @param string $css CSS tags to be included
     * @param string $param Array of htmlAttributes
     */
    function register_cssblock($css,$htmlAttributes=null)
    {
        $this->_register(array($css,'cssblock',$htmlAttributes));
    }
   
   
    /**
     * Adds a js file to array
     * @param string $file CSS file to be included
     * @param string $param Array of htmlAttributes
     */
    function register_js($file)
    {
        $this->_register(array($file,'js'));
    }
   
    /**
     * Adds a javascript block to array
     * @param string $javascript Javascript block to be included
     * @param string $param Array of htmlAttributes
     */
    function register_jsblock($javascript)
    {
        $this->_register(array($javascript,'jsblock'));
    }   
   
    /**
     * Adds a meta tag to array
     * @param array $htmlAttributes Array of html attributes of meta tag 
     */
    function register_meta($htmlAttributes)
    {
        $this->_register(array($htmlAttributes,'meta'));
    }
   
       
    /**
     * Adds a link tag to array
     * @param array $htmlAttributes Array of html attributes of meta tag 
     */
    function register_link($htmlAttributes)
    {
        $this->_register(array($htmlAttributes,'link'));
    }         
   
    /**
     * Adds a raw sequence of html tags to array
     * @param string $raw Sequence of html tags
     */
    function register_raw($raw)
    {
        $this->_register(array($raw,'raw'));
    }

    /**
     * Prints the html for all of the items registered
     * @return string
     */          
    function print_registered()
    {
        foreach ($this->_library as $l)
        {
            switch ($l[1])
            {
                case 'css':
                    echo $this->html->css($l[0],'stylesheet',$l[2]);   
                    break;
                case 'js':
                    echo $this->javascript->link($l[0]);
                    break;
                case 'jsblock':
                    echo $this->javascript->codeBlock($l[0]);
                    break;
                case 'meta':
                    echo "<meta " . $this->_parseAttributes($l[0]) . " />";
                    break;
                case 'link':
                    echo "<link " . $this->_parseAttributes($l[0]) . " />";
                    break;
                case 'raw':
                    echo $l[0];
                    break;
                case 'cssblock':
                    echo '<style type="text/css" ' .  $this->_parseAttributes($l[2]) . " ><!--{$l[0]}--></style>";
                    break;
                default:
                    die('Internal error on HeadHelper: Unknown type registered.');
            }
        }            
    }
   
   
    /**
     * Adds the item in the array if it doesn't already exist
     * @param array $item Item to be added
     * @access private
     */
    function _register($item)
    {
        if (! in_array($item,$this->_library))
        {
            $this->_library[]=$item;
        }                   
    }                                          
   
   
   
    /**
     * This is a copy of the same function in HtmlHelper
     * Returns a space-delimited string with items of the $options array. If a
     * key of $options array happens to be one of:
     *    + 'compact'
     *    + 'checked'
     *    + 'declare'
     *    + 'readonly'
     *    + 'disabled'
     *    + 'selected'
     *    + 'defer'
     *    + 'ismap'
     *    + 'nohref'
     *    + 'noshade'
     *    + 'nowrap'
     *    + 'multiple'
     *    + 'noresize'
     *
     * And its value is one of:
     *    + 1
     *    + true
     *    + 'true'
     *
     * Then the value will be reset to be identical with key's name.
     * If the value is not one of these 3, the parameter is not output.
     *
     * @param  array  $options      Array of options.
     * @param  array  $exclude      Array of options to be excluded.
     * @param  string $insertBefore String to be inserted before options.
     * @param  string $insertAfter  String to be inserted ater options.
     * @return string
     */
    function _parseAttributes($options, $exclude = null, $insertBefore = ' ',
    $insertAfter = null)
    {
        $minimizedAttributes = array(
        'compact',
        'checked',
        'declare',
        'readonly',
        'disabled',
        'selected',
        'defer',
        'ismap',
        'nohref',
        'noshade',
        'nowrap',
        'multiple',
        'noresize');

        if (!is_array($exclude))
        {
            $exclude = array();
        }

        if (is_array($options))
        {
            $out = array();

            foreach ($options as $key => $value)
            {
                if (!in_array($key, $exclude))
                {
                    if (in_array($key, $minimizedAttributes) && ($value === 1 ||
                    $value === true || $value === 'true' || in_array($value,
                    $minimizedAttributes)))
                    {
                        $value = $key;
                    }
                    elseif (in_array($key, $minimizedAttributes))
                    {
                        continue;
                    }
                    $out[] = "{$key}=\"{$value}\"";
                }
            }
            $out = join(' ', $out);
            return $out? $insertBefore.$out.$insertAfter: null;
        }
        else
        {
            return $options? $insertBefore.$options.$insertAfter: null;
        }
    }
    

}
          
?>

Comments»

1. Naonak - April 21, 2006

Bugs with php 4 :

Warning: in_array(): Wrong datatype for second argument in /home/iciservi/www/iciservices/app/views/helpers/head.php on line 147

And

Warning: Invalid argument supplied for foreach() in /home/iciservi/www/iciservices/app/views/helpers/head.php on line 108

2. Nao - April 21, 2006

I find : Hack method “__construct” for php 4 don’t work in helpers

So instead of method __construct :

function HeadHelper()
{
static $library = array(); //for php4 compat
$this->_library=& $library;
}

3. rossoft - May 16, 2006

I’ve talked with Nao and __construct() works in PHP4.

Note for readers: Don’t forget to include the HeadHelper in your AppController, and put this in your HEAD section of your layout:

if (isset($head)) echo $head->print_registered();

4. RosSoft » combobox helper (Editable Selectbox) - May 22, 2006

[...] 1. Copy this to /webroot/js/combobox/ 2. Copy the helpers HeadHelper, UtilHelper from this blog to helpers/ (search the blog) 3. Copy that code to helpers/combobox.php [...]

5. rossoft - May 25, 2006

If you haven’t readed the previous version, then put echo $head->print_registered() at of your layout

6. tariquesani - June 30, 2006

Thanks for all the hard work. I however like the syntax of previous version better rather than register_css register_js how about doing away with the register_ part and have just ‘css’ and ‘js’ etc

and the print_registered can be changed to something similarly shorter

7. rossoft - June 30, 2006

@tariquesani: thanks, that’s a good feedback

8. dave - July 13, 2006

i’d like to note that :

$head->register_meta

is also great for :
meta keywords
meta description
meta robots

Two questions, I always get an empty js tag in my html source, is that normal or am i missing something?
Is there anyway to clean up how the html is printed? all my meta tags end up inline, i’d like one per line.

9. edevil - July 15, 2006

Hi .. i was wondering if its possible to redirect to another page after a specific amount of time with this headHelper (without using javascript).

10. John Zimmerman - July 16, 2006

try the meta refresh tag using the register_meta

http://en.wikipedia.org/wiki/META_refresh

11. george - August 11, 2006

i´m also getting an empty

12. george - August 19, 2006

my last post was cut off, the issue is the same as mentioned by dave with an empty js tag.
i want to suggest further to put a newline \n after each echoed tag in print registered.

13. RosSoft » Updated packages in cakeforge - August 23, 2006

[...] Hi! I’ve been out because my internet connection at home was down Now I return with some improvements in the HeadHelper and CJS Templates. They’re in cakeforge (CJS Templates version 2.1) [...]

14. RosSoft » Updated packages in cakeforge - August 23, 2006

[...] Hi! I’ve been out because my internet connection at home was down Now I return with some improvements in the HeadHelper and CJS Templates. They’re in cakeforge (CJS Templates version 2.1) [...]

15. Tapter - September 26, 2006

Around line 210 in HeadHelper I changed the if to:
if ($this->cache)
{
if (count($cached['jsblock']) > 0)
//print cached jsblock
echo $this->_codeBlock(implode(”\n”, $cached['jsblock'])) . “\n”;
}
to avoid empty javascript blocks

16. Jippi - October 30, 2006

I have changed a few things in the HeadHelper - I needed to be able to have default css - but also custom css so i could make my own custom files without having to overwrite the old

http://bin.cakephp.org/saved/215

17. yyxveexops - March 18, 2007

naked european men pictures

18. Dani - May 2, 2007

nice post, well done!

19. Constant - June 1, 2007

Hi,

Version 0.5 of HeadHelper state that it require version > 0.20 of UtilHelper but on this blog I can only find version 0.1 ?

Where can I found it ?

Thanks

Constant

20. Charles - June 25, 2007

Great Post, explained in plain english, special thanks to Rossoft…..

21. Andrew Assarattanakul - June 26, 2007

UtilHelper can be found at: http://cakeforge.org/snippet/detail.php?type=snippet&id=57

22. JsCalendar Helper para CakePHP « Lo de Miguel - September 10, 2007

[...] en el layout. Googleando encontré que alguien ya había hecho algo para resolver este problema aquí. Hay que tocar el layout pero esto provee un Helper bastante bonito para lo que [...]

23. Juma Gull Arab - October 25, 2007

Simple Question,
How to add or minus two numbers in text box,
For Example I wanna to have two different text field and calculate that and show the Result in one text field.
text1 10 or any numbers var x
text2 20 or any numbers var y
Show result here text3 or Result 30.
that to make event by button of just focus.

Thanks in advance