I'm trying to pull in a system configuration value to a layout file. I figured the only way to do this was to create a function in my Data.php helper and then use the function in the layout xml. For some reason, it doesn't work.
public function getStoreVar() {
return Mage::getStoreConfig('path/to/var');
}
Then in the xml I have something like
<block type="my/module" template="path/to/template.phtml">
<config_id helper="module/getStoreVar" />
</block>
I have a Mage::log on the getStoreVar function and can see that it isn't even being called. What am I missing?
Just figured out what I was doing wrong. Realized the code I was referencing to do this, addLink, had the helper inside an action tag with the helper on an argument for the action method. Using a method from my block class fixed it for me. For example:
<action method="setStorVar">
<var helper="module/getStoreVar" />
</action>
Related
I have a custom category attribute that i want to add to the body class. As far as I could find out what people do is
Override the CategoryController and add something like $root->addBodyClass($category->getMyAttribute()); But I don't want to override core classes...
In the admin panel they add something like <reference name=”root”><action method=”addBodyClass”><className>caravan-motorhome-lighting</className></action></reference> to each and every category not using the attribute itself but adding the class directly. As I already have an attribute, I surely don't want do clone it and add the class this way.
So what my favourite solution would be is some layout update I can add to the local.xml that says
<reference name=”root”>
<action method=”addBodyClass”>
<className>
get value of my custom attribute here dynamically
</className>
</action>
</reference>
Does anyone have an idea how this could work or another idea that I didn't even think of?
You can use a really cool feature of Magento layout XML to achieve this. You'll need a module to achieve it. Either create a module specifically for this or use a theme module if you have one — this is up to you to decide what you think is best.
I'll show you an example where I'll add a class containing the ID of the category to the body tag:
In my layout XML, I'm going to add via the catalog_category_default handle. This way, I can use Mage::registry('current_category') later to retrieve the current category. So, in your layout XML do something similar to this:
<catalog_category_default>
<reference name="root">
<action method="addBodyClass">
<className helper="mymodule/my_helper/getCategoryClass" />
</action>
</reference>
</catalog_category_default>
This attribute is the important part: helper="mymodule/my_helper/getCategoryClass". This is equivalent to calling Mage::helper('mymodule/my_helper')->getCategoryClass(); in code.
Whatever is returned from that function will be used as the value for the <className> node. You may want to use a different helper that you deem more appropriate, this is up to you to decide.
Carrying on the with the example, here's the function:
public function getCategoryClass() {
return 'category-id-' . Mage::registry('current_category')->getId();
}
You'll want to change the code so that it retrieves the value of your attribute. e.g getMyAttribute() on the category returned by Mage::registry('current_category').
Also, you'll need to ensure that the return is something that is suitable as a CSS class. In this example we don't need to do anything as the ID will always be just number which will be appended to category-id-. If the value of your attribute is not always going to be safe you might want to consider using something like this
I am working on a custom module which takes product images from external server. I have overridden a few functions to get the required result.
But I have to override base/default/template/catalog/product/view/media.phtml inside my custom module.
I tried to do this from default/layout/MY_MODULE.xml but that did not work for me.
How do I override the media.phtml inside default/MY_MODULE.
I think calling setTemplate method is not the right way to override template file in your case. For me it looks a bit redundant and unclear: you are assigning template to block and the immediately reassign it with action. I would do this way:
<catalog_product_view>
<reference name="product.info">
<block type="catalog/product_view_media" name="product.info.media" as="media" template="MY-MODULE/catalog/product/view/media.phtml" />
</reference>
</catalog_product_view>
I think you could also reference to product.info.media directly and call setTemplate action there
I currently have this:
<block type="core/text" name="top.address" as="topAddress">
<action method="addText"><text>PO BOX 1124, Rockdale, Sydney, NSW 2216, Australia</text></action>
</block>
But, when I need to update address, I have to do it manually here in the layout file. I want to pull address from store config ( general/store_information/address ) so, I can update everywhere on the site from one location easily.
I guess it can be done directly on the template like this:
<?php echo Mage::getStoreConfig('general/store_information/address') ?>
But I want to try with layout, is it possible?
Thanks.
My answer might be to oudated, but I faced with such problem just now I found an alternative way to solve it:
In layout you can specify core/text block and set its text via helper. You can use any suitable reference.
<reference name="before_body_end">
<block type="core/text" name="some.config">
<action method="addText">
<text helper="module_name/data/getSomeConfig" />
</action>
</block>
</reference>
Declare getSomeConfig function in the helper:
public function getSomeConfig()
{
return Mage::getStoreConfig('your_config_path');
}
In a such way you can even pass some dynamic data into javascript code.
Short answer - no. There is no functionality for it. That's not to say that it couldn't be done. There is an attribute that you can use on an action tag - ifconfig. It looks to see if a system config flag is set, and if it returns true, then it will proceed with the action. You could override or extend Mage/Core/Model/Layout.php to add that functionality.
There are a number of options to this problem, though.
You can use templates, like you mentioned.
If you are wanting to avoid a template, you can create a block that extends Mage_Core_Block_Text and specify the _toHtml method, with the code that you provided.
The best: I would see creating a generic block in a generic module that is used to pull system config requests and output them as text. You could either have it be a custom action/method, or send along an attribute value, which will end up in the data array for the block, which you could then lookup in _toHtml.
I need to add a JS file conditionally and programmatically inside a block file. I tried with these codes:
if (Mage::getStoreConfig('mymodule/settings/enable')) {
$this->getLayout()->getBlock('head')->addJs('path-to-file/file1.js');
} else {
$this->getLayout()->getBlock('head')->addJs('path-to-file/file2.js');
}
However, regardless of what the setting is, none of this file is loaded. I even tried to eliminate the condition and explicitly load one file only, but it still doesn't work. What have I done wrong here?
The issue here is likely one of processing order. My guess is that your PHP code is being evaluated after the head block has been rendered. While your code is successfully updating the head block class instance, it's happening after output has been generated from that instance.
The better solution will be to add the addJs() calls in layout XML so that they will be processed prior to rendering. It would be nice if there were an ifnotconfig attribute, but for now you can use a helper.
Create a helper class with a method which returns the script path based on the config settings, then use this as the return argument.
<?php
class My_Module_Helper_Class extends Mage_Core_Helper_Abstract
{
public function getJsBasedOnConfig()
{
if (Mage::getStoreConfigFlag('mymodule/settings/enable')) {
return 'path-to-file/file1.js';
}
else {
return 'path-to-file/file2.js';
}
}
}
Then in layout XML:
<?xml version="1.0"?>
<layout>
<default>
<reference name="head">
<action method="addJs">
<file helper="classgroup/class/getJsBasedOnConfig" />
<!-- i.e. Mage::helper('module/helper')->getJsBasedOnConfig() -->
</action>
</reference>
</default>
</layout>
$this->getLayout()->getBlock('head')->addJs('path');
Its the right code, search if your path is right.
I know this was asked a long time ago, but in case somebody is looking for this, I would suggest to use this in your local.xml:
<layout>
<default>
<reference name="head">
<action ifconfig="path/to/config" method="addJs">
<script>pathto/file.js</script>
</action>
</reference>
</default>
</layout>
Of course this is for JS files located in /js/ folder. Use the appropriate method if you want to add skin_js or skin_css.
PS. Tested on CE 1.9
I'm having a very peculiar problem.
I created a module which has it's own layout xml, and in the correct handle has a
<reference name="product_list">
<action method="setTemplate"><template>rebates/product/list.phtml</template></action>
</reference>
to update to use the correct template.
I also rewrote the module to use my block class Company_Module_Block_List extends Mage_Catalog_Block_Product_List.
I am using Alan Storms commerecebug, so I know the block is being used. Also I looked at the page layout xml using ?showLayout and I see that the setTemplate method is being called.
When I call
public function _construct(){
parent::_construct();
echo $this->getTemplate();
}
in the Block, the correct template shows up, but if I create
protected function _toHtml(){
parent::_toHtml();
echo $this->getTemplate();
}
It reverts to the old template?
I ended up adding a
function _beforeToHtml(){
$this->setTemplate('my_template.phtml');
}
I don't like it, but it works, and the module is not dependent on other layouts working....