I'm working on a custom module to display CMS content. I have a custom front controller which is working as expected. I'm able to call various front actions from the controller. I am using an existing template, which is also displaying as it should. I'm also loading a layout update xml file, from which I was able to remove the product menu, which I don't need, and add a reference block for my custom block's template file.
I know the correct template override file is loading, as I'm testing with the following:
<?php echo __FILE__ . " loaded <br>"; ?>
Which is echoing the correct filename.
However, when I call my custom block method from that same template file, I get nothing.
My module namespace/module is Cmpreshn/Projects. Following is what I have so far:
Config file in
app/code/local/Cmpreshn/Projects/etc/config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Cmpreshn_Projects>
<version>0.1.0</version>
</Cmpreshn_Projects>
</modules>
<frontend>
<routers>
<projects>
<use>standard</use>
<args>
<module>Cmpreshn_Projects</module>
<frontName>education</frontName>
</args>
</projects>
</routers>
<layout>
<updates>
<projects>
<file>projects.xml</file>
</projects>
</updates>
</layout>
</frontend>
<global>
<blocks>
<projects>
<class>Projects_Block_List</class>
</projects>
</blocks>
</global>
</config>
Front controller in
app/code/local/Cmpreshn/Projects/controllers/ProjectsController.php
<?php
class Cmpreshn_Projects_ProjectsController extends Mage_Core_Controller_Front_Action {
public function indexAction(){
$this->listAction();
}
public function listAction(){
echo "list action called<br>";
/* get request and save params to object */
$this->request = Mage::app()->getRequest();
/* layout overrides for this module in app/design/frontend/default/pmc1/layout/projects.xml */
$this->loadLayout();
/* use the education template */
$this->getLayout()->getBlock("root")->setTemplate("page/pmc_education.phtml");
/* render the layout */
$this->renderLayout();
}
}
XML updates in
app/design/frontend/default/pmc1/layout/projects.xml
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<projects_projects_list>
<remove name="top.menu"/>
<reference name="content">
<block type="page/html" name="page" template="cmpreshn/projects/list.phtml" />
</reference>
</projects_projects_list>
</layout>
Template overrides and call to custom block in
app/design/frontend/default/pmc1/template/cmpreshn/project/list.phtml
<?php echo __FILE__ . " loaded <br>"; ?>
<?php echo $this->getProjectsList(); ?>
Last but not least, my custom block class in
app/code/local/Cmpreshn/Proejcts/Block/List.php
<?php
class Cmpreshn_Projects_Block_List extends Mage_Core_Block_Template {
public function _construct() {
parent::__construct();
echo "projects list block constructor called<br>";
} // end constructor
public function getProjectsList() {
echo "getProjectsList called <br>";
return("getProjectsList called");
}
} // end class
As I mentioned previously, I am getting the output from the first line of my list.phtml template file, but no output from my custom block method, and no indication that my block is loading (no output from block _construct() method either )
Any help is appreciated. I'm ready to pull my eyes out over this...
I just observed your code and found the following errors:
Registeration of block in registering module file (config.xml) seems wrong.
<global>
<blocks>
<projects>
<class>Cmpreshn_Projects_Block</class> <!-- Not Projects_Block_List -->
</projects>
</blocks>
</global>
The type attribute is wrong in Block element of layout file (projects.xml). You should not call page/html instead you should call projects/list.
There might be more typos. but I could found the above two only. I hope this solves your problem.
change the block type to projects/list in your projects.XML file like this
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<projects_projects_list>
<remove name="top.menu"/>
<reference name="content">
<block type="projects/list" name="page" template="cmpreshn/projects/list.phtml/>
</reference>
</projects_projects_list>
</layout>
you may get the output now.
Related
Hi i just created custom module in magento and its frontend doesn't work.
The config file :
<?xml version="1.0"?>
<config>
<modules>
<Shareino_Sync>
<version>0.1.0</version>
</Shareino_Sync>
</modules>
<global>
<helpers>
<sync>
<class>Shareino_Sync_Helper</class>
</sync>
</helpers>
<blocks>
<sync>
<class>Shareino_Sync_Block</class>
</sync>
</blocks>
</global>
<frontend>
<routers>
<sync>
<use>standard</use>
<args>
<module>Shareino_Sync</module>
<frontName>shareinosync</frontName>
</args>
</sync>
</routers>
<layout>
<updates>
<sync>
<file>shareino_front.xml</file>
</sync>
</updates>
</layout>
</frontend>
</config>
The layout file :
# File in : app/design/frontend/default/default/layout/shareino_front.xml
<layout version="0.1.0">
<sync_index_index>
<reference name="content">
<block type="sync/sync" name="sync" template="sync_index.phtml" />
</reference>
</sync_index_index>
</layout>
And sync_index.phtml :
# file in app/design/frontend/default/default/template/sync_index.phtml
<h1>
Test Text
</h1>
I created a block that named Sync.php
class Shareino_Sync_Block_Sync extends Mage_Core_Block_Template
{
public function myfunction()
{
return "Hello tuts+ world";
}
}
At the end my controller :
class Shareino_Sync_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction(){
$this->loadLayout();
$this->renderLayout();
}
public function testAction(){
echo "index Action";
}
}
I think i done every think well , but when i load the action url in browser it doesn't my layout. please help me to know my wrong.
Check your current theme, maybe it is not default/default. If it is different, just place layout and templates under this theme. Or put it into base/default theme for compatibility with all themes.
Make sure the module is registered in app/etc/modules/Shareino_Sync.xml.
And the last, maybe your module is disabled for output. Goes to System->Configuration->Advanced->Advanced->Disable Module Output find your module and make sure it is enabled.
you should always put your module layout files AND template files under base/default the reason is because the fallback theme mechanism of Magento first look for those files in your_package/your_theme then under your_package/default then under base/default. So if you put those files under default/default and your package is not default those files will never be found
I have created one block inside my custom module but it's not working. My module is working fine but my block is not working when I call my block from footer.phtml file it shows 'Fatal error: Call to a member function setTemplate() on a non-object'. Actually I want to show some message in my frontend using my custom block.I have mentioned my code below
local/Monojit/Custom/controllers/IndexController.php
<?php
class Monojit_Custom_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
$this->loadLayout();
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'my_block_name_here',
array('template' => 'custom/test.phtml')
);
$this->getLayout()->getBlock('content')->append($block);
$this->renderLayout();
}
}
?>
local/Monojit/Custom/Block/Mycustomblock.php
<?php
class Monojit_Custom_Block_Mycustomblock extends Mage_Core_Block_Template
{
//public function _prepareLayout()
// {
// return parent::_prepareLayout();
// }
public function _construct() {
parent::_construct();
$this->setTemplate('custom/test.phtml');
}
public function getmessage()
{
$msg = "showing my custom block";
return $msg;
}
}
?>
local/Monojit/Custom/etc/config.xml
<config>
<global>
<modules>
<monojit_custom>
<version>0.1.0</version>
</monojit_custom>
</modules>
<blocks>
<custom>
<rewrite>
<custom>Monojit_Custom_Block_Mycustomblock</custom>
</rewrite>
</custom>
</blocks>
<helpers>
<custom>
<class>Monojit_Custom_Helper</class>
</custom>
</helpers>
</global>
<frontend>
<routers>
<custom>
<use>standard</use>
<args>
<module>Monojit_Custom</module>
<frontName>custom</frontName>
</args>
</custom>
</routers>
<layout>
<updates>
<custom>
<file>custom.xml</file>
</custom>
</updates>
</layout>
</frontend>
</config>
I have created one theme (copied modern theme) inside frontend/default/monojit Changed admin design configuration as well,created necessary folder as well inside skin.screenshot pic
design/frontend/default/monojit/template/custom/test.phtml
//want to fetch data from my block
<p>This is your custom block called programatically.</p>
localhost/magento/index.php/custom page shows my message correctly but when I call my block from footer.phtml page
<?php echo $this->getLayout()->createBlock('custom/mycustomblock')->setTemplate('custom/test.phtml')->toHtml(); ?>
It shows 'Fatal error: Call to a member function setTemplate() on a non-object' Do I need to create any layout.xml file? Please help me how can i fix my issue.thanks
Your block was not created, and createBlock return a non-object value. It happens because you don't specify custom namespace class prefix. Your block node in XML config should looks like
<blocks>
<custom>
<class>Monojit_Custom_Block</class>
</custom>
</blocks>
It means everything under custom namespace will be created with Monojit_Custom_Block prefix, so custom/mycustomblock => Monojit_Custom_Block_Mycustomblock.
But using createBlock is usually bad practice, it better to use layout files:
http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-4-magento-layouts-blocks-and-templates
http://www.magentocommerce.com/design_guide/articles/intro-to-layouts
try:
In layout/page.xml set your block, for Example:
<block type="page/html_footer" name="footer" as="footer" template="page/html/footer.phtml">
<block type="my_module/block_links" name="my_block_name" as="my_block_name" template="page/template/links.phtml"/>
</block>
Use code below in your phtml file
<?php echo $this->getChildHtml('my_block_name') ?>
I defined a custom block this way:
<frontend>
<layout>
<updates>
<categorylist module="mymodule">
<file>mymodule.xml</file>
</categorylist>
</updates>
</layout>
</frontend>
<global>
<blocks>
<categorylist>
<class>Alias_CategoryList_Block</class>
</categorylist>
</blocks>
</global>
Then I defined the block class this way
class Alias_CategoryList_Block_List extends Mage_Core_Block_Template
{
public $idCategory = NULL;
// Contructor
public function __construct()
{
echo $this->getData('categoryid');
}
}
and the layout this way:
<default translate="label">
<block type="categorylist/list" name="categorylist.list" output="toHtml" after="-" template="mymodule.phtml"/>
I put the block in a CMS this way:
{{block type="categorylist/list" categoryid="10"}}
But sadly the $this->getData('categoryid'); retrieves nothing.
Cannot figure out what's wrong ?
I tryed even $this->getCategoryid; but even nothing.
Anyone can help?
I'm using Magento 1.7
Would it be silly to add a view (phtml) template file that has
<?php echo $this->getCategoryId(); ?>
instead of trying to accomplish that in the constructor? Also then you wouldn't need your own code behind file you could just use core/template.
So your cms would be
{{block type="core/template" template="awesome.phtml" cateogryid="10"}}
The problem was that I assumed that the layout updates configuration will extend the code in the CMS but the code in the CMS should not have block name and template parameters for my purposes. So I fixed it declearing the template in the contructor and removing the layout updates in configuration (since I don't need the block to override existing blocks):
// Contructor
public function __construct()
{
$this->setTemplate('mymodule.xml');
}
I'm trying to have just a little "hello world" like module to learn how to make modules. I've got a fairly fresh install of Magento 1.7 on a Mac OSX 10.6 local server. I'm following Pierrefay's Turtorial and I cant get the block to display. I've been all over the web, but nothing has worked. The module's page just shows the default look with the 'dog' and the 'Back to School' ad. I've got Alan's Layoutviewer module. I'm currently in debug mode and emptying the cache like mad. I have already told Mag. not to cache anything,anyway. I've managed to reach the point where I'm not generating error messages (I'm also in debug mode and have execption.log and system.log pulled up).
My Controller:
<?php
class Nationwide_Cartonplugin_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction ()
{
$this->loadLayout();
$this->renderLayout();
//var_dump(Mage::getSingleton('core/layout')->getUpdate()->getHandles());
//exit("bailing early at ".__LINE__." in ".__FILE__);
//echo "Carton Exists";
//Mage::log(
// $this->getLayout()->getUpdate()->getHandles(),
// null, ‘layout.log’ );
//Mage::log(
// $this->getLayout()->getUpdate()->asString(),
// null, ‘layout.log’ );
}
public function mamethodeAction ()
{
echo 'test mymethod';
}
}
My Config:
<?xml version="1.0"?>
<config>
<modules>
<Nationwide_Cartonplugin>
<version>1.1.0</version>
</Nationwide_Cartonplugin>
</modules>
<global>
<blocks>
<cartonplugin>
<class>Nationwide_Cartonplugin_Block</class>
</cartonplugin>
</blocks>
</global>
<frontend>
<routers>
<cartonplugin>
<use>standard</use>
<args>
<module>Nationwide_Cartonplugin</module>
<frontName>carton</frontName>
</args>
</cartonplugin>
</routers>
<layout>
<updates>
<cartonplugin>
<file>carton.xml</file>
</cartonplugin>
</updates>
</layout>
</frontend>
</config>
My Layout: (frontend/default/nationwide/layout/carton.xml)(I'm using default & nationwide in the admin setup)
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="content">
</reference>
</default>
<cartonplugin_index_index>
<reference name="content">
<block output="toHtml" type="cartonplugin/myblock" name="myblock"
template="cartonplugin/cartondisplay.phtml"/>
</reference>
</cartonplugin_index_index>
</layout>
Uncomenting the references generate a "not valid template" error.
My Template: (frontend/default/nationwide/template/cartonplugin/cartondisplay.phtml)
<?php
//echo $this->methodcarblock();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello World</title>
<style type="text/css">
body {
background-color:#f00;
}
</style>
</head>
<body>
<div class="test1">
<?php echo $this->methodcarblock(); ?>
</div>
</body>
</html>
My block:
<?php
class Nationwide_Cartonplugin_Block_Myblock extends Mage_Core_Block_Template
{
public function methodcarblock()
{
return 'informations about my block !!';
}
}
It seems I follow everying on the web and nothing still works, other than echoing from the index action. I would greatly appreciate any help.
You are getting no errors when uncommenting because Magento just doesn't try to call the block :) So this a silent error...
Indeed, as says the error, Magento is trying to reach file frontend/base/default/template/cartonplugin/cartondisplay.phtml which means that your design configuration is (I guess) not correct if the file frontend/default/nationwide/template/cartonplugin/cartondisplay.phtml really exists.
So, are you sure your package / theme is correctly configured in the system configuration, design tab? Make sure that package is "default" and theme templates is "nationwide".
Something like the picture below is a good configuration to tell Magento to call templates that reside in frontend/default/nationwide/template/ instead of frontend/base/default/template/ (may need some fine tuning depending on your existing configuration and store views)
At a glance, change
<block type="cartonplugin/myblock" name="myblock" template="cartonplugin/cartondisplay.phtml"/>
to
<block output="toHtml" type="cartonplugin/myblock" name="myblock" template="cartonplugin/cartondisplay.phtml"/>
This is necessary because Mage_Core_Controller_Varien_Action::renderLayout() assumes an output block has been set as an entry point for rendering. Typically setting an output block and method is not necessary because the root block defined in page.xml is an output block.
I'm trying to add a content block to Magento, which should be visible on every side below the main content. I want to archive this with a custom extension, so I can copy this extension and it workes without touching core design files.
My extension includes the following layout update:
<default>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</default>
My problem is, that the attribute after="-" is not working. The block always showes up at the top of the content block. Seems before and after have no consequence.
If I move the block to i.e. footer, the attributes before and after are working fine.
How can I place my block at the bottom of block "content"
As far as I can see the problem is that you specify your block in the "default" layout handle while most of the content in the "content" block is added by other layout handles which are applied later. That's why the added dependencies in your XML registration file (mentioned by Fabian) are not helping.
Please consider these two options depending on your needs:
1. If you really want to include your block on all frontend pages
In your XML layout file (local.xml or a custom one), add a new layout handle:
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<!-- your other adjustments for default, category_product_view and so on go here -->
<add_my_block>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</add_my_block>
</layout>
Now you create an event observer to inject your layout handle into your layout:
<?php
class YourCompany_YourExtension_Model_Observer
{
/**
* Adds a block at the end of the content block.
*
* Uses the event 'controller_action_layout_load_before'.
*
* #param Varien_Event_Observer $observer
* #return YourCompany_YourExtension_Model_Observer
*/
public function addBlockAtEndOfMainContent(Varien_Event_Observer $observer)
{
$layout = $observer->getEvent()->getLayout()->getUpdate();
$layout->addHandle('add_my_block');
return $this;
}
}
Then you register the event observer in your XML extension configuration file (config.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<modules>
<YourCompany_YourExtension>
<version>0.0.1</version>
</YourCompany_YourExtension>
</modules>
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<mymod_add_block_at_end_of_main_content>
<type>singleton</type>
<class>mymod/observer</class>
<method>addBlockAtEndOfMainContent</method>
</mymod_add_block_at_end_of_main_content>
</observers>
</controller_action_layout_load_before>
</events>
<!-- declaring your layout xml etc. -->
</frontend>
<global>
<!-- declaring your block classes etc. -->
<models>
<mymod>
<class>YourCompany_YourExtension_Model</class>
</mymod>
</models>
</global>
</config>
Now your block should end up below the other blocks. I tested this successfully for the homepage, customer login page and category view page. If you have to exclude your block on a few pages, you can check in your event observer if the block should be excluded on that certain page.
2. If you want to include your block only on some pages
Add a layout handle to your XML layout file just as we did before but instead of creating and registering an event observer, just tell your XML layout file to use the custom layout handle in some areas:
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<catalog_category_default>
<update handle="add_my_block" />
</catalog_category_default>
<catalog_category_layered>
<update handle="add_my_block" />
</catalog_category_layered>
<cms_page>
<update handle="add_my_block" />
</cms_page>
<!-- and so on -->
<add_my_block>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</add_my_block>
</layout>