I am trying to create my first Magento module which would allow an attribute (yes/no) on a product page to alter the styling of the grouped products options on a product view page.
I'm probably starting a little too deep here but this is my understanding of how to do this:
Create an attribute and assign to default attribute set (Alternative Group View alt_group_view).
Create an alternative grouped.phtml file in /template/catalog/product/view/type - groupedAlt.phtml
Create a basic module structure that initialises my module. I should really have the module create the attribute, but I havent a clue about that yet!!!
Then this is where I get stuck. Essentially I need to right the logic within the module file that looks for the attribute on the product - if its set I then need to code that tells the layout block presumably something that extends this:
<PRODUCT_TYPE_grouped translate="label" module="catalog">
<reference name="product.info">
<block type="catalog/product_view_type_grouped" name="product.info.grouped" as="product_type_data" template="catalog/product/view/type/grouped.phtml">
</reference>
</PRODUCT_TYPE_grouped translate="label" module="catalog">
Hopefully that makes sense to someone?
I'm not sure that I can realisticly acheive this as Im just starting with module development although I have quite a lot of knowledge with the frontend and admin areas of Magento.
Any advice would be much appreciated.
Regards,
Steve
You should handle this through an observer. The event to observe is :
controller_action_layout_generate_blocks_after
1°) In your module, in etc/config.xml, add your event handler :
<frontend>
<events>
<controller_action_layout_generate_blocks_after>
<observers>
<yourmodule_generate_blocks_after>
<type>singleton</type>
<class>mymodule/observer</class>
<method>generateBlocksAfter</method>
</yourmodule_generate_blocks_after>
</observers>
</controller_action_layout_generate_blocks_after>
</events>
</frontend>
Then create a Model named Observer.php in your Model directory (MyCompany/MyModule/Model/Observer.php)
In this model, add your generateBlocksAfter() method like this :
public function generateBlocksAfter($event)
{
$controller = $event->getAction();
//limit to the product view page
if($controller->getFullActionName() != 'catalog_product_view')
{
return;
}
$layout = $controller->getLayout();
$myblock = $layout->getBlock('product.info.grouped');
$_product = Mage::registry('current_product');
if ($_product->getAltGroupView()) {
$myblock->setTemplate('catalog/product/view/type/groupedalt.phtml');
}
}
And here you are.
Related
Hi i have an attribute that calculates the margin of an product, in all attribute sets. Question is how can i set a rule to prevent customer check out if the margin(or profit) of a cart is less than required?
You can create an observer for the event controller_action_predispatch_checkout_onepage_index - this will fire when the customer starts the onepage checkout process.
This can be achieved like so in your modules config.xml:
<events>
<controller_action_predispatch_checkout_onepage_index>
<observers>
<YOUR_MODULE_checkout_onepage_index>
<type>singleton</type>
<class>YOUR_MODULE_Model_Observer</class>
<method>calculateProductMargin</method>
</YOUR_MODULE_checkout_onepage_index>
</observers>
</controller_action_predispatch_checkout_onepage_index>
</events>
If you are unaware about how to create a module then look here
So in your app/code/local/YOUR/MODULE/Model/Observer.php:
class YOUR_MODULE_Model_Observer extends Varien_Event_Observer {
public function setStore($observer) {
// Your logic here
}
}
In here you can $cart = Mage::getModel('checkout/cart')->getQuote(); and loop through the cart items, calculate your product margin and _goBack() potentially if it fails your requirements.
Enjoy! I hope this helps.
The problem
I need to remove the category name or title from specific non-product category pages but can't find the reference or block names to remove it with layout updates. I have already found the code that I could override and comment out to remove the title from every category page but that won't work since I need the title on most category pages.
What I'm trying to do
In the past I've been able to turn on the template path hints with block names, spend a second researching and found a great way to remove a block. This is the kind of code I have used before:
<reference name="Mage_Page_Block_Html_Breadcrumbs">
<remove name="breadcrumbs"/>
</reference>
TL;DR
I just need a simple way to remove the category title name from specific categories. If my idea about update xml is junk I'll take any suggestions. Thanks for any help.
I'd start by creating a custom module, overriding the Mage_Catalog_Block_Category_View block and doing something like this:
In app/local/Yournamespace/Titlemodule/etc/config.xml
<config>
<!-- .... -->
<global>
<blocks>
<titlemodule>
<class>Yournamespace_Titlemodule_Block</class>
</titlemodule>
<catalog>
<rewrite>
<product_view>Yournamespace_Titlemodule_Block_Category_View</product_view>
</rewrite>
</catalog>
</blocks>
<!-- ... -->
</config>
and in app/local/Yournamespace/Titlemodule/Block/Category/View.php
class Yournamespace_Titlemodule_Block_Category_View extends Mage_Catalog_Block_Category_View
{
protected function _prepareLayout()
{
parent::_prepareLayout();
$category = $this->getCurrentCategory(); // if needed
$headBlock = $this->getLayout()->getBlock('head');
// custom logic here
$headBlock->setTitle($this->__('New title, or none'));
return $this;
}
}
It will give you plenty of possibilities running custom logic before manipulating any blocks on the page.
I would like to have the categories in magento made use of the attributes/filter.
Let say I have an attribute "CupAttr" which is a NOT used in layered navigation. Then I create a category called CupCat, and it uses the "CupAttr" to pull products to display them within the CupCat category.
is that possible? The reason why i want to do this is I want to minimize the maintenance of categorizing products.
Thanks
EDITED:
Amit's solution works perfectly, but that bring in another issue. the products showing in the list is different from the products can be filtered from the layered navigation.
I actually need to select all products for any category (because i won't add any products to any category, they are all blank), then i start filter the products for that specific category by attribute.
thanks again.
In this case,you can use magento event/observer.
Hook an observer on event catalog_block_product_list_collection.
Then using addAttributeToFilter('CupAttrAttibiteCode'); filter the collection by CupAttr.
config.xml code:
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<catalog_block_product_list_collection> <!-- event -->
<observers>
<xyz_catalog_block_product_list_collection>
<type>singleton</type>
<class>Xyz_Catalog_Model_Observer</class>
<method>apply_CupAttr_filter</method>
</xyz_catalog_block_product_list_collection>
</observers>
</catalog_block_product_list_collection>
</events>
</global>
</config>
Observer code location:
Create the directory structure - app/code/local/Xyz/Catalog/Model/Observer.php
First "CupAttr" which is used in prouct listing for use this attribute to filtering
<?php
class Xyz_Catalog_Model__Observer
{
public function __construct()
{
}
public function apply_CupAttr_filter($observer){
//apply filter when category is CupCat
if(Mage::registry('current_category') &&(Mage::registry('current_category')->getId()=='CupCatCatrgoryId') ):
$collection=$observer->getEvent()->getCollection();
$collection->addAttributeToFilter('CupAttrAttibiteCode','FilterExpression');
endif;
return $this;
}
}
I cant provide any code because that is part of the question, but I am sure if you guide me in the right direction I can paste the code from the files you tell me.
I enabled product reviews on my site:
However the product page title and the product review page title its the same and its giving me lots of duplicate pages for my SEO efforts.
examples:
normal page
http://www.theprinterdepo.com/hp-laser-p2015dn-printer-cb368a
same product review page
http://www.theprinterdepo.com/review/product/list/id/1133/
any idea?
thanks
I am not aware of any feature out of the box that allows you to specify different titles for product review pages. I could be wrong though?
So, that leaves two methods you can use to achieve this.
Core block override
Event/Observer
I would opt for option 2 here. Even with this option there are still various ways to achieve this. Here is one of them...
So, once you have created your module, you will need to declare the observer in your config.xml:
<?xml version="1.0"?>
<config>
<!-- other config xml -->
<frontend>
<events>
<controller_action_layout_render_before_review_product_list>
<observers>
<productmeta>
<class>YourCompany_YourModule_Model_Observer</class>
<method>controller_action_layout_render_before_review_product_list</method>
</productmeta>
</observers>
</controller_action_layout_render_before_review_product_list>
</events>
</frontend>
<!-- other config xml -->
</config>
Then your observer would be similar to this...
<?php
class YourCompany_YourModule_Model_Observer
{
/**
* #pram Varien_Event_Observer $observer
* #return void
*/
public function controller_action_layout_render_before_review_product_list(Varien_Event_Observer $observer)
{
$title = "Your new page title";
Mage::app()->getLayout()->getBlock('head')->setData('title', $title);
}
}
I'm working on an extension that will receive product information from Magento when saved and do custom processing on the product.
I've spent 2 days until now trying to figure out why Magento is not triggering the event "catalog_product_status_update".
Simply, I change product status by going to Catalog->Manage Products, then select one or more products and use the "Actions" field above the products grid to change product(s) status to "disabled".
When I do that, the product(s) status changes just fine, but the problem is that I don't receive the event for it.
Here's the code I use:
<?xml version="1.0"?>
<config>
<global>
<models>
<mage4ucustomredirect>
<class>Mage4u_Customredirect</class>
</mage4ucustomredirect>
</models>
<events>
<catalog_product_save_after>
<observers>
<abc>
<type>singleton</type>
<class>Mage4u_Customredirect_Model_Observer</class>
<method>on_catalog_product_save_after</method>
</abc>
</observers>
</catalog_product_save_after>
<catalog_product_status_update>
<observers>
<abc>
<type>singleton</type>
<class>Mage4u_Customredirect_Model_Observer</class>
<method>on_catalog_product_status_update</method>
</abc>
</observers>
</catalog_product_status_update>
</events>
</global>
</config>
And this is the observer:
class Mage4u_Customredirect_Model_Observer
{
public function on_catalog_product_status_update(Varien_Event_Observer $observer)
{
Mage::log( "on_catalog_product_status_update" );
}
public function on_catalog_product_save_after(Varien_Event_Observer $observer)
{
Mage::log( "on_catalog_product_save_after" );
}
}
?>
Strange enough, when I try to save a product manually, I receive the event "on_catalog_product_save_after" which tells me that my code is working fine, but it doesn't work for this "on_catalog_product_status_update" event.
Any help is appreciated!
NOTE: I'm using Magento v1.6.2.0
I believe your problem is that the update status option at the top of the grid doesn't use any models to achieve the task, it access the database directly. If you look at the updateAttributes method in Mage_Catalog_Model_Product_Action and Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Action respectively, you will see that no product or product_status model is loaded.
Unfortunately for you, at a quick glance I don't see any events that you can hook into to capture this. It might require rewriting of the model.
Your two observers have the same name "abc". This should be unique inside Magento observers list.
Try changing one of them to "abc1", refresh your cache and it should work.
This question was asked somewhere in 2012, but in more recent Magento versions, the mass action update for the product grid is processed by the catalog/product_action model its updateAttributes method:
Mage_Catalog_Model_Product_Action::updateAttributes()
An event is dispatched there:
Mage::dispatchEvent('catalog_product_attribute_update_before', array(
'attributes_data' => &$attrData,
'product_ids' => &$productIds,
'store_id' => &$storeId
));
attributes_data is a key-value list with data to be stored for product_ids in the store_id scope. In your observer for catalog_product_attribute_update_before you can check if the status attribute is being updated:
$event = $observer->getEvent();
$attributesData = $event->getData('attributes_data');
if (! isset($attributesData['status'])) {
// we are not updating the status
return;
}
// do something, for example - if the product will be disabled
if ($attributesData['status'] != Mage_Catalog_Model_Product_Status::STATUS_ENABLED) {
// api call
}
Hope this helps for anyone who tries to intercept a mass status update.