You can do this without changing core files, you need to create an observer that will create a new layout handle based on the attribute. Then you can create a layout update for that handle to change the template used for the product view page.
The following code is based on the article from http://magebase.com/magento-tutorials/creating-custom-layout-handles/
Module init file app/etc/modules/Example_AttributeHandle.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Example_AttributeHandle>
<active>true</active>
<codePool>local</codePool>
</Example_AttributeHandle>
</modules>
</config>
Module configuration: app/code/local/Example/AttributeHandle/etc/config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Example_AttributeHandle>
<version>0.1.0</version>
</Example_AttributeHandle>
</modules>
<global>
<events>
<controller_action_layout_load_before>
<observers>
<attributesethandle>
<class>Example_AttributeHandle_Model_Observer</class>
<method>addAttributeHandle</method>
</attributesethandle>
</observers>
</controller_action_layout_load_before>
</events>
</global>
</config>
Observer file: app/code/local/Example/AttributeHandle/Model/Observer.php
<?php
class Example_AttributeHandle_Model_Observer
{
/**
* Converts attribute value of current product to nice name ([a-z0-9_]+).
* Adds layout handle PRODUCT_ATTRIBUTE_<attribute>_<value> after
* PRODUCT_TYPE_<product_type_id> handle
*
* Event: controller_action_layout_load_before
*
* @param Varien_Event_Observer $observer
*/
public function addAttributeHandle(Varien_Event_Observer $observer)
{
$product = Mage::registry('current_product');
/**
* Return if it is not product page
*/
if (!($product instanceof Mage_Catalog_Model_Product)) {
return;
}
$attributeName = 'myattribute';
/**
* Convert attribute value to alphanumeric + underscore string
*/
$niceName = str_replace('-', '_', $product->formatUrlKey($product->getData($attributeName)));
/* @var $update Mage_Core_Model_Layout_Update */
$update = $observer->getEvent()->getLayout()->getUpdate();
$update->addHandle('PRODUCT_ATTRIBUTE_'.$attributeName.'_' . $niceName);
}
}
Replace the $attributeName value with the attribute that you would like to use. When the attribute is dropdown, it will use the numeric value of the selected option. Also this will not work for multiselect attributes.
Now you can change the product view template with the following code in your local.xml to select an other template when the product attribute myattribute has the value demotxt:
<PRODUCT_ATTRIBUTE_myattribute_demotxt>
<reference name="product.info">
<action method="setTemplate"><template>my/custom/product/view.phtml</template></action>
</reference>
</PRODUCT_ATTRIBUTE_myattribute_demotxt>
Hope that this info is helpful, I did not had the option to test it completly.
In Magento, the renderers are defined under checkout_cart_item_renderers.xml
, there's several of them:
app/code/Magento/Checkout/view/frontend/layout/checkout_cart_item_renderers.xml
for default and simple products renderers
app/code/Magento/Bundle/view/frontend/layout/checkout_cart_item_renderers.xml
for bundle products renderers
app/code/Magento/Catalog/view/frontend/layout/checkout_cart_item_renderers.xml
for virtual products renderers
app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_item_renderers.xml
for configurable products renderers
app/code/Magento/Grouped/view/frontend/layout/checkout_cart_item_renderers.xml
for grouped products renderers
app/code/Magento/GiftMessage/view/frontend/layout/checkout_cart_item_renderers.xml
this one is special as it adds extra block for the gift message feature to the different renderers
app/code/Magento/Wishlist/view/frontend/layout/checkout_cart_item_renderers.xml
this one is special too as it adds extra block for the wishlist feature to the different renderers
After checking those renderers, you can find which renderer you want to override.
As you said, you want to override the simple product renderer which is a Magento\Checkout\Block\Cart\Item\Renderer
.
If you want to override the entire block you should use the Magento 2 preferences:
In your module, you can create a di.xml
file under the etc
folder with the following content:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Checkout\Block\Cart\Item\Renderer" type="Vendor\ModuleName\Block\Checkout\Cart\Item\Renderer" />
</config>
Then you need to create the app/code/Vendor/Module/Block/Checkout/Cart/Item/Renderer.php
class with the following content:
<?php
namespace Vendor\Module\Block\Checkout\Cart\Item;
class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer
{
public function theFunctionYouWantToRewrite()
{
// Do your custom stuff
}
}
However, if you want to work on the method levels and not on the entire class level, you should use plugins
As it can be very specific, it's hard for me to give you an example but you can find useful resources about plugins here:
Best Answer
@Dmync In order to accomplish this the basic answer is "it depends." The first question that would need to be answered is "What do you want to override?" This question is too broad.
If you're trying to override some template(s) that are in place by default for product view then you can need to track down the templates you want to override. You can do so by either of the following:
vendor/magento/module-catalog/view/frontend/layout/catalog_product_view.xml
and track down all the template files that are explicitly assigned here, as well as all other templates included via<update>
layout instruction update docsOnce you know which templates you want to update, then you can follow the general ideas within this page to create the correct module structure. Basically if you're creating a module to perform these actions then you'll need a structure like:
app/code/<Vendor>/<module>/view/frontend/Magento_Catalog/templates
and then you'd continue to refer to the structure ofMagento_Catalog
for it's folder hierarchy...and you'd add that into your module...soIf you're wanting to override
vendor/magento/module-catalog/view/frontend/templates/product/view/form.phtml
then you'd createapp/code/<Vendor>/<Module>/view/frontend/Magento_Catalog/templates/product/view/form.phtml
. Then you could do your customizations there..again, refer to the templates customization doc I linked.If you're trying to do this via a theme. Using the above example....you'd create
app/design/frontend/<Vendor>/<theme>/Magento_Catalog/product/view/form.phtml
and perform whatever customizations you'd like in that template.So which ever way you go about it, either creating a custom module or a custom design theme, and if you're simply modifying the template content, you're going to need to recreate the target module (in this case Magento_Catalog) in your own custom module/theme (using the correct directory hierarchies...as it's slightly different between module/theme).
If you're interested in modifying css then look here for info on overriding css.
If you need to modify some of the page's layout xml files to rearrange elements, remove elements, add elements, etc...look here to get started.
As you can see, there's a lot that can take place in simply "Overriding product view page."