Jason Posit
Jason Posit

Reputation: 1323

No Frills Magento Layout: createBlock throws exception "Invalid block type"

I am running Magento 1.7.0.2 (on Ubuntu Linux 12.04 LTS).

I am trying to get a section of Magento code inspired by Alan Storm's No Frills Magento Layout book section 1.8. First of all I think Mage_Core_Template_Block of that section should read Mage_Core_Block_Template.

But more importantly my call to $block = $layout->createBlock('foo_bar/hello') is returning false and throwing an exception in exception.log because it is prefixing foo with Mage thus referencing an object called Mage_Foo_Bar_Block_Hello which does not exist instead of returnin an object of type Foo_Bar_Block_Hello which is what I'm after. Here are the contents of my customization files and the triggering URL:


URL triggering the error:

http:// localhost/magpractice/helloworld/index/layout/

/var/www/magpractice/app/code/local/Alanstormdotcom/Helloworld/controllers/IndexController.php

<?php

class Alanstormdotcom_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {

  function layoutAction() {

    $layout = Mage::getSingleton('core/layout');
    $block = $layout->createBlock('alanstormdotcom_helloworld/hello', 'root');
    var_dump($block);
    echo $block->toHtml();

  }

}

?>

/var/www/magpractice/app/code/local/Alanstormdotcom/Helloworld/Block/Hello.php

<?php
class Alanstormdotcom_Helloworld_Block_Hello extends Mage_Core_Block_Template {

  public function _construct() {

    $this->setTemplate('helloworld.phtml');
    return parent::_construct();

  }

  public function _beforeToHtml() {

    $block_1 = new Mage_Core_Block_Text();
    $block_1->setText('The first sentence.');
    $this->setChild('the_first', $block_1);

  }

  public function fetchTitle() {
    return 'Hello Fancy World!';
  }

}
?>

/var/www/magpractice/app/code/local/Alanstormdotcom/Helloworld/etc/config.xml

<config>
  <modules>
    <Alanstormdotcom_Helloworld>
      <version>0.1.0</version>
    </Alanstormdotcom_Helloworld>
  </modules>
  <frontend>
    <routers>
      <helloworld>
        <use>standard</use>
        <args>
          <module>Alanstormdotcom_Helloworld</module>
          <frontName>helloworld</frontName>
        </args>
      </helloworld>
    </routers>
  </frontend>
</config>

Here are the contents of /var/www/magpractice/var/log :

2013-06-11T12:42:56+00:00 ERR (3):
exception 'Mage_Core_Exception' with message 'Invalid block type: Mage_Alanstormdotcom_Helloworld_Block_Hello' in /var/www/magpractice/app/Mage.php:594
Stack trace:
#0 /var/www/magpractice/app/code/core/Mage/Core/Model/Layout.php(495): Mage::throwException('Invalid block t...')
#1 /var/www/magpractice/app/code/core/Mage/Core/Model/Layout.php(437): Mage_Core_Model_Layout->_getBlockInstance('alanstormdotcom...', Array)
#2 /var/www/magpractice/app/code/local/Alanstormdotcom/Helloworld/controllers/IndexController.php(38): Mage_Core_Model_Layout->createBlock('alanstormdotcom...', 'root')
#3 /var/www/magpractice/app/code/core/Mage/Core/Controller/Varien/Action.php(419): Alanstormdotcom_Helloworld_IndexController->layoutAction()
#4 /var/www/magpractice/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('layout')
#5 /var/www/magpractice/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#6 /var/www/magpractice/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#7 /var/www/magpractice/app/Mage.php(683): Mage_Core_Model_App->run(Array)
#8 /var/www/magpractice/index.php(88): Mage::run('', 'store')
#9 {main}

Can someone kindly point out where I have gone wrong in my code or state how magento 1.7.0.2 possibly deviates somehow in what is described in the alan storm nofrills magento layout documentation (which apart from this has been an excellent book)?

Thanks.

Upvotes: 1

Views: 1357

Answers (2)

Alana Storm
Alana Storm

Reputation: 166086

There's no differences in 1.7.0.2 that wold impact your code — your config.xml is missing its <blocks/> section.

You're instantiating a block named alanstormdotcom_helloworld/hello. That's a group name of alanstormdotcom_helloworld, and a class name of hello.

However, your module doesn't have a blocks configuration section. Without this section, Magento doesn't know what PHP class name to use for blocks in the alanstormdotcom_helloworld group. Since it doesn't know, it assumes your block is part of the Mage core and taskes a guess at a name (Mage_Alanstormdotcom_Helloworld_Block_Hello).

Look at how the working modules configure their <blocks/> section. That should get you pointed in the right direction.

Without checking my work, your configuration should look something like this

<config>
    <!-- ... -->
    <global>
        <!-- ... -->
         <blocks>
            <alanstormdotcom_helloworld>
                <class>Alanstormdotcom_Helloworld_Block</class>
            </alanstormdotcom_helloworld>
        </blocks>
    </global>
</config>

If you're still having trouble, try tracing the code back to where Magento creates a class name from the class alias (alanstormdotcom_helloworld/hello). Beside solving yoru problem, this is always a good exernice for new Magento programmers.

Upvotes: 3

blmage
blmage

Reputation: 4214

Your config.xml file is incomplete. It should rather look like this :

<config>
  <modules>
    <Alanstormdotcom_Helloworld>
      <version>0.1.0</version>
    </Alanstormdotcom_Helloworld>
  </modules>
  <!-- Missing blocks and helpers definition here: -->
  <global>
    <blocks>
        <helloworld>
            <class>Alanstormdotcom_Helloworld_Block</class>
        </helloworld>
    </blocks>
    <helpers>
        <helloworld>
            <class>Alanstormdotcom_Helloworld_Block</class>
        </helloworld>
    </helpers>
  </global>
  <frontend>
    <routers>
      <helloworld>
        <use>standard</use>
        <args>
          <module>Alanstormdotcom_Helloworld</module>
          <frontName>helloworld</frontName>
        </args>
      </helloworld>
    </routers>
  </frontend>
</config>

Upvotes: 3

Related Questions