2

I added a <block> in page.xml in order to be able to load css files on some pages (not all) and in a particular place of the html <head>.

Using this trick, I can in CMS pages for example, order actions such as

<reference name="myownref">
<action method="addCss"><stylesheet>css/styles_home.css</stylesheet></action>
</reference>

It works, but It generates errors in log file :

2015-04-15T18:26:01+00:00 ERR (3): Notice: Undefined index: items  in .../magento/app/code/core/Mage/Page/Block/Html/Head.php on line 167
2015-04-15T18:26:01+00:00 ERR (3): Warning: Invalid argument supplied for foreach()  in .../magento/app/code/core/Mage/Page/Block/Html/Head.php on line 167

my modified page.xml :

     <block type="page/html_head" name="head" as="head">
                   ...
                    <action method="addJs"><script>mage/cookies.js</script></action>

                    <block type="page/js_cookie" name="js_cookies" template="page/js/cookie.phtml"/>

                    <!-- Remove items which the RWD package is not dependent upon -->
                    <action method="removeItem"><type>skin_js</type><name>js/ie6.js</name></action>

                    <!-- Add vendor dependencies -->
                    <action method="addItem"><type>skin_js</type><name>js/lib/jquery-1.10.2.min.js</name></action>
                  ...
                    <!-- Add stylesheets with no media queries for use in IE 8 and below -->
                    <action method="addItem"><type>skin_css</type><name>css/styles-ie8.css</name><params/><if><![CDATA[ (lte IE 8) & (!IEMobile)]]></if></action>
                    <action method="addItem"><type>skin_css</type><name>css/madisonisland-ie8.css</name><params/><if><![CDATA[ (lte IE 8) & (!IEMobile)]]></if></action>

                    <!-- Add stylesheets with media queries for use by modern browsers -->
                    <action method="addItem"><type>skin_css</type><name>css/styles.css</name><params/><if><![CDATA[<!--[if (gte IE 9) | (IEMobile)]><!-->]]></if></action>
                    <action method="addItem"><type>skin_css</type><name>css/madisonisland.css</name><params/><if><![CDATA[<!--[if (gte IE 9) | (IEMobile)]><!-->]]></if></action>

                    <!-- Add cutom css files -->
                    <action method="addItem"><type>skin_css</type><name>css/quote_form.css</name><params/></action>

<!-- MY CUSTOM BLOCK -->
                    <block type="page/html_head" name="myownref" as="myownref">

                    </block>

                    <!-- Sets viewport meta tag using text block -->
                    <block type="core/text" name="head.viewport">
                        <action method="setText"><text><![CDATA[<meta name="viewport" content="initial-scale=1.0, width=device-width" />]]>&#10;</text></action>
                    </block>
                </block>

Is it due to the fact that, on some page the block is empty, and that the for each loop crashes?

Is there a proper way to avoid this error?

Thanks for your help,

2
  • 1
    My guess is that you cannot have a page/html_head inside a page/html_head what is in you block? Apr 15 '15 at 20:02
  • Agreed with @DavidManners - maybe html_head has a method that calls back to its parent block?
    – pspahn
    Apr 15 '15 at 22:48
1

I believe you cannot add blocks in "head" section.

If you want to add css or any file in some cms pages, then just open the cms page and go to "Design" section and add following code:

<reference name="head">
     <action method="addCss"><stylesheet>css/styles_home.css</stylesheet></action>
</reference>

This will do the trick. Hope this will help.

PS if you want to add any phtml file, then you need to find the reference name of that block (for ex. header, breadcrumbs etc) and replace in place of "head" then add block.

1

Here you are adding a page/html_head block (myownref) inside another page/html_head block (head) and it is perfectly fine. But this is a rare example of how you cannot add such a page/html_head block as a child element of head block. In order to explain, let us have a look on the method Mage_Page_Block_Html_Head::getCssJsHtml().

public function getCssJsHtml()
{
    // separate items by types
    $lines  = array();
    foreach ($this->_data['items'] as $item) {
        if (!is_null($item['cond']) && !$this->getData($item['cond']) || !isset($item['name'])) {
            continue;
        }
        $if     = !empty($item['if']) ? $item['if'] : '';
        $params = !empty($item['params']) ? $item['params'] : '';
        switch ($item['type']) {
            case 'js':        // js/*.js
            case 'skin_js':   // skin/*/*.js
            case 'js_css':    // js/*.css
            case 'skin_css':  // skin/*/*.css
                $lines[$if][$item['type']][$params][$item['name']] = $item['name'];
                break;
            default:
                $this->_separateOtherHtmlHeadElements($lines, $if, $item['type'], $params, $item['name'], $item);
                break;
        }
    }

As you can see here, almost all code in this method comes inside the foreach loop. This foreach loop is the actual villain in your case. ie

foreach ($this->_data['items'] as $item) {
    ---
}

This foreach() loop has a small problem. It is required that $this->_data['items'] should be hold an array before invoking this method.

In normal case, for every page/html_head block, the above method will get invoked. In case of head block, in every page, this field is already filled with at least one item and hence no error will be produced. In your case, you have added myownref block inside head block and then you are using this block only in some pages to add js or css. So in those pages, where you didn't use your block will certainly raise the above error, coz $this->_data['items'] is not present.

So as per this definition, it is required that you need to use myownref block at least once in every page.

How can you resolve this ?

As I already stated, you need to use myownref block in every page. But this is not what you want to do. You need to include certain css, js files only in some pages. In that case, you can tackle the problem like this.

You should define your block like this.

 <block type="core/template" name="myownref" as="myownref" template="custom/special/jscss.phtml"></block>

Please note the type of block is core/template and it does not have the power of page/html_head block. Hence you cannot use addJs, addCss etc in this case. But you can include your css and js through the phtml file which is associated with this block. ie.

File : app\design\frontend\[package]\[theme]\template\custom/special/jscss.phtml

<!-- to add a js, you can use this code

    <script type="text/javascript" src="<?php echo $this->getSkinUrl('js/relative/path/tojs.js') ?>"></script> 
-->
<link rel="stylesheet" type="text/css" href="<?php echo $this->getSkinUrl('css/styles_home.css') ?>" />

It is done. Now wrapping these js and css using a proper condition now you can able to show them in certain pages only.

The most elegant solution here is making a small change in the method Mage_Page_Block_Html_Head::getCssJsHtml(). The modified change will looks like this.

if (isset($this->_data['items'])) {
     foreach ($this->_data['items'] as $item) {
         ---
     }
}

This way you can avoid the above error. But editing core files is big NO NO. The clean method is, you need to define your own custom block that should extend Mage_Page_Block_Html_Head class and then redefine the function getCssJsHtml() as I shown above. Then use your custom block as the type of your myownref block.

For you, I have created a custom extension which will provide you a custom block of type rkt_flexiblehead/page_html_head. This block can be used in the similar way that you have used in your case, but without any problem. For more details, have look on the extension.

Hope that makes sense

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.