Is there a way in magento to create a block and call its toHtml() method without having to load the entire layout object.
For example, in one of my ajax controllers i want to send a certain block as json output and i am not interested in any other blocks but i am forced to do the following:
$this->loadLayout();
$this->getLayout()->getBlock('my_block_name')->toHtml();
Which loads the entire layout which seems unnecessary.
I just accomplished this like so:
In my layout XML for my module:
<mymodule_ajax_action>
<block type="core/template_facade" name="root" template="path/to/template/file.phtml"/>
</mymodule_ajax_action>
By naming the block "root", it replaced the entire layout with just this template file.
So in my controller:
public function actionAction() {
$this->loadLayout();
$this->renderLayout();
}
returns just that block.
You can try the following:
$layout = Mage::getSingleton('core/layout');
$html = $layout
->createBlock('module/block_type')
->setTemplate('template/file.phtml')
->toHtml();
From your code, it looks as though you are in a controller so you could shorten the code a little to the following (absolutely no difference in functionality, simply 1 less line of code)...
$html = $this->getLayout()
->createBlock('module/block_type')
->setTemplate('template/file.phtml')
->toHtml();
Related
I'm just ramping up with Magento and somethings that appear rather intuitive on the surface, don't seem to be working as expected. Here is a very basic template example that I am trying to get working at a "hello world" level before digging deeper.
In the "header" block definition in my page.xml layout I have the following block included:
<block type="core/text_list" name="helloRob" as="helloRob" template="page/html/hellorob.phtml" />
Then, in my header.phtml file, I have added...
<?php echo $this->getChildHtml('helloRob'); ?>
The contents of the hellorob.phtml file are:
<h1>Hello Rob</h1>
Yet, when displaying the page, I don't get the expected H1 element output in the header. If I remove the "getChildHtml" call and replace it with the actual HTML, then it displays the H1. So I know that my custom header.phtml file is getting loaded. I've also been able to confirm that I am adding my block to the correct layout XML file, because when I comment out another block in the same file, the commented out block no longer appears on my page.
I've checked over the code looking for something obvious, like a typo. I've also checked for any naming conflicts -- hence "helloRob" rather than "helloWorld".
I feel like I am missing something incredibly obvious, like looking for your glasses only to find them on top of your head.
Any help -- with the code -- not my glasses -- would be appreciated!
--Rob
The problem here is your understanding of block types. Blocks in Magento do different things, the one you've used here core/text_list serves a specific purpose. You can view what a block does by looking at it's code Block file, core/text_list is located in app/code/core/Mage/Core/Block/Text/List.php
protected function _toHtml()
{
$this->setText('');
foreach ($this->getSortedChildren() as $name) {
$block = $this->getLayout()->getBlock($name);
if (!$block) {
Mage::throwException(Mage::helper('core')->__('Invalid block: %s', $name));
}
$this->addText($block->toHtml());
}
return parent::_toHtml();
}
As you can see it's purpose is to just print out child blocks. This block type is used for text menus' and as blocks purely as containers for other blocks.
As you are looking for a block to just print the contents of a template so type="core/template" will do just fine, it's _toHtml() method is
protected function _toHtml()
{
if (!$this->getTemplate()) {
return '';
}
$html = $this->renderView();
return $html;
}
I'm programming an ajax extension to Magento and I'm having trouble when I try to make checkout/cart work with it.
I want to reload the entire block, including the item and also the cart totals after a change in any product in the cart.
I've modified the layout as many sites said and I can't get the checkout/cart block render well.
My two solutions were:
1° Tryed to update the layout via an xml file, and I get a false in $block_cart.
I've a class
Mati_Ajax_CartController extends Mage_Checkout_CartController
{
...
public function updateShoppingCartAction()
{
...
$block_cart = $this->getLayout()->getBlock('checkout/cart');
...
}
}
and a xml file (which I'm sure i'ts being loaded beacause the js pointed there is loading)
<checkout_cart_updateshoppingcart>
<update handle="checkout_cart_index" />
</checkout_cart_updateshoppingcart>
2° Tryed to create the block
public function updateShoppingCartAction()
{
...
$block_cart = $this->getLayout()->getBlockSingleton('checkout/cart')->setTemplate("checkout/cart.phtml")->toHtml();
...
}
And here I get the block, but when the template executes $this->getChildHtml('totals');
It gets a false anwer, so the webpage has some differences with the previousone
Does anybody knows how to make this work ?
In your first attempt just append ->toHtml();
Alternatively you could have included that as a command in the xml output="toHtml"
Check how the checkout/onepage/review functions if you are looking for advice.
There they access the response object and then set the body of the response to the html variable, in your case $block_cart
The key was in the xml file
<ajax_cart_updateshoppingcart>
<update handle="checkout_cart_index" />
</ajax_cart_updateshoppingcart>
In Magento CE 1.5.1, why is getLogoAlt not available for the content section though it is available for the header section?
Inside the content section of the home page, my theme's home.phtml has
<h1 class="no-display"><?php echo $this->getLogoAlt() ?></h1>
which outputs as
<h1 class="no-display"></h1>
But header.phtml,
<h4><strong><?php echo $this->getLogoAlt() ?></strong></h4>
properly outputs as
<h4><strong>Buy widgets here!</strong></h4>
Puzzled...
The "header section" is a block added with the following layout update XML
<block type="page/html_head" name="head" as="head">
The block's type is page/html_head, which translated to the class Mage_Page_Block_Html_Header. If you look at the class definition, you can see the header.phtml template being set.
#File: app/code/core/Mage/Page/Block/Html/Header.php
public function _construct()
{
$this->setTemplate('page/html/header.phtml');
}
When you use $this->someMethod() from a template, you're calling a method on the template's block class. Each template "belongs" to a block. If we look at the header class again
#File: app/code/core/Mage/Page/Block/Html/Header.php
public function getLogoAlt()
{
if (empty($this->_data['logo_alt'])) {
$this->_data['logo_alt'] = Mage::getStoreConfig('design/header/logo_alt');
}
return $this->_data['logo_alt'];
}
we can see the definition of getLogoAlt.
The other template you mentioned, home.phtml, is added with the following layout update xml
<block type="core/template" name="default_home_page" template="cms/default/home.phtml"/>
Its block is a core/template block, which translates to Mage_Core_Block_Template. This block does not have a getLogoAlt method. However, like all blocks, it does have Magento's magic getters and setters. You can "set" and "get" data properties on Magento blocks like this
$this->setFooBar('setting a value for the foo_bar data property');
echo $this->getFooBar();
even if the block doesn't have those methods defined. So, this means you can call getLogoAlt on any block without an error being thrown, but only the header block is going to return a value. If you want that value in any template, you can just call
$logo_alt = Mage::getStoreConfig('design/header/logo_alt');
at the top of your template, and then use $logo_alt wherever you'd like.
I'm trying to add a link to one of my blocks to a specific action of one of my controllers. Looking through the class docs and googling didn't resolve something useful. (maybe I just used the wrong search queries).
My Controller has two actions:
indexAction() and exportAction()
Now, in one of my blocks I wand to add link to exportAction(). I've found the method addLink() but this doesn't work.
Maybe anyone knows how to do that ? Or could point me to the right resources on the net ?
Regards, Alex
Block Example:
<?php
class Polyvision_Tempest_Block_Adminhtml_View extends Mage_Adminhtml_Block_Template
{
public function __construct()
{
parent::__construct();
}
protected function _toHtml()
{
$html = "whatever";
return $html;
}
}
?>
Your question isn't clear/complete.
A block renders HTML, either through a phtml template or through PHP code. To add an HTML link, you just render a html anchor tag with an href
//via PHP
protected function _toHtml()
{
$html = 'My Link';
return $html;
}
//via phtml template
#your block
class Polyvision_Tempest_Block_Adminhtml_View extends Mage_Adminhtml_Block_Template
{
protected function _construct()
{
$this->setTemplate('path/to/from/template/folder/as/basetemplate.phtml');
}
}
#your template
My Link';
The addLink method is a special method that only applies to certain types of blocks. When you call it it add links information to the block's data properties. Then, it's _toHtml method or phtml template has been written such that it loops over the stored data to output links. It doesn't apply to general blocks, which is what makes your question confusing.
Hope that helps!
I set a view variable in someAction function like this:
$this->view->type = "some type";
When I access this variable inside layout script like this:
<?php echo $this->type ?>
it prints nothing. What's wrong?
My application.ini settings related to layout
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.layout.layout = "layout" ; changed 'default' to 'layout'
Edit
This thread suggests the alternate solution, but looking for solution to above problem. And this was working in Zend 1.6.2. I just upgraded to 1.10 and it stopped working.
Edit
If I set this view var inside any _init Bootstrap function, it works.
If you want to assign something to your layout you have to go an other way:
// get the layout instance
$layout = Zend_Layout::getMvcInstance();
// assign fooBar as Name to the layout
$layout->name = 'fooBar';
I believe the layout view object and the action view object are separate instances of the Zend_View class.
I think this is the correct way to pass variables from the controller to the layout:
/**
* Controller action
*/
public function indexAction()
{
$this->_helper->layout()->assign('myName', 'John Doe');
}
and then in your layout script you can access the variables by referencing the layout object like this:
<html>
<body>
<?php echo $this->layout()->myName; ?>
</body>
</html>
Do you have the following entry in your application.ini file?
resources.view[] =
So, you can initialize the view with no options and use it through:
<?php echo $this->type ?>