Magento use custom widget descriptor not working

I find that I can add my own layout layouts using this script:

$this->getLayout()->getUpdate()->addHandle('myhandle'); 

Then I checked out the Alan Storm Layout viewers: http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz

? ShowLayout = pens

Pens for this request

  • Default
  • cms_page
  • STORE_default
  • THEME_frontend_default_default
  • cms_index_index
  • page_two_columns_left
  • customer_logged_out
  • myhandle

There was my handle, but my custom xml layout was not used.

Here is my xml:

 <?xml version="1.0"?> <layout version="0.1.0"> <myhandle> <reference name="head"> <action method="addJs"><script>test/your.js</script></action> </reference> </myhandle> </layout> 

This works fine, so the xml file loads:

 <?xml version="1.0"?> <layout version="0.1.0"> <default> <reference name="head"> <action method="addJs"><script>test/your.js</script></action> </reference> </default> </layout> 

What happened? Why is this not working?

If this is not the case, how to add custom CSS and javascript for the page where the widget was used?

Update: Here's what might come close to a solution:

If I add this code after adding a new handle to the page:

 $this->getLayout()->getUpdate()->fetchPackageLayoutUpdates('myhandle'); $this->getLayout()->generateXml(); 

After that, calling "index.php? ShowLayout = page" writes the processing code in xml, but the page does not use it.

+4
source share
2 answers

The long and short of this - you really don't want to introduce layouts. It gets quite complicated (complicated enough so that I can't go through it fast enough to respond to a stack overflow), but

  • If you add your descriptor before you call $ this-> loadLayout () from the controller, it is too soon.

  • If you add your descriptor after calling $ this-> loadLayout (), it's too late.

In this experiment, try changing the loadLayout method in the base Action Controller

 File: app/code/core/Mage/Core/Controller/Varien/Action.php public function loadLayout($handles=null, $generateBlocks=true, $generateXml=true) { // if handles were specified in arguments load them first if (false!==$handles && ''!==$handles) { $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default'); } //YOUR NEW CALL HERE $this->getLayout()->getUpdate()->addHandle('myhandle'); ... 

This should work and apply your layout. Now Bad Idea will do it in production, I just mention it to show you that pens need to be added to a very specific process of rendering a temporary layout. As the ultimate programmer, it’s actually your task not to embed layouts of layouts.

The layout system is for the layer that lies between the designers and the raw PHP system code. Since you can explicitly write PHP code, I would just directly inject your javascript into the preliminary rendering of the header block.

  //from a controller, but could be modified to be used elsewhere //also pseudo code $this->getLayout()->getBlock('header')->append( $this->getLayout() ->createBlock('core/text', 'some-unique-name') ->setText('<script type="text/javascript" src="/foo/baz/bar.js"></script>') ); 
+7
source

If you want to add a new descriptor, the best solution is probably to add a descriptor with an observer. If you have a module with its own URL, it already has a unique descriptor.

Create a module that calls the correct handle.

Create your etc / config.xml file

 <?xml version="1.0" encoding="UTF-8"?> <config> <modules> <Ho_AttributeSetHandle> <version>0.1.0</version> </Ho_AttributeSetHandle> </modules> <global> <events> <controller_action_layout_load_before> <observers> <attributesethandle> <class>Ho_AttributeSetHandle_Model_Observer</class> <method>addAttributeSetHandle</method> </attributesethandle> </observers> </controller_action_layout_load_before> </events> </global> </config> 

In my case, the code is Model / Observer.php:

 <?php class Ho_AttributeSetHandle_Model_Observer { /** * Converts attribute set name of current product to nice name ([a-z0-9_]+). * Adds layout handle PRODUCT_ATTRIBUTE_SET_<attribute_set_nicename> after * PRODUCT_TYPE_<product_type_id> handle * * Event: controller_action_layout_load_before * * @param Varien_Event_Observer $observer */ public function addAttributeSetHandle(Varien_Event_Observer $observer) { $product = Mage::registry('current_product'); /** * Return if it is not product page */ if (!($product instanceof Mage_Catalog_Model_Product)) { return; } $attributeSet = Mage::getModel('eav/entity_attribute_set')->load($product->getAttributeSetId()); /* Convert attribute set name to alphanumeric + underscore string */ $niceName = strpos($product->formatUrlKey($attributeSet->getAttributeSetName()), '-') !== FALSE ? str_replace('-', '_', $product->formatUrlKey($attributeSet->getAttributeSetName())) : $product->formatUrlKey($attributeSet->getAttributeSetName()); $niceName = strpos($niceName, ' ') !== FALSE ? str_replace(' ', '_', $product->formatUrlKey($niceName)) : $niceName; /* @var $update Mage_Core_Model_Layout_Update */ $update = $observer->getEvent()->getLayout()->getUpdate(); $handles = $update->getHandles(); // Store all handles in a variable $update->resetHandles(); // Remove all handles /** * Rearrange layout handles to ensure PRODUCT_ATTRIBUTE_SET_<attribute_set> * handle is added last */ foreach ($handles as $handle) { $update->addHandle($handle); if ($handle == 'PRODUCT_TYPE_' . $product->getTypeId()) { $update->addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName); } } } } 

Remember to create the application / etc / modules / Ho _AttributeSetHandle.xml:

 <config> <modules> <Ho_AttributeSetHandle> <active>true</active> <codePool>local</codePool> </Ho_AttributeSetHandle> </modules> </config> 
+2
source

All Articles