Conditionally remove header/footer in Magento - php

I have a module page that can be accessed like
www.example.com/module/controller/action/id/10
I want something like this in my controller's action
$page = (int) Mage::app()->getRequest()->getParam('id');
if($page == '12')
{
$this->getLayout()->unsetBlock('header');
$this->getLayout()->unsetBlock('footer');
}
But above method doesn't work, I guess I'm passing wrong alias to unsetBlock method.
I know how to hide header/footer via layout xml but here I want to hide them in controller.
So basically I am searching an alternative for
<remove name="header"/>
<remove name="footer"/>

I found solution to my own question, sharing because it may help others.
1. Create a new layout handle for the page
// Namespace/Modulename/Model/Observer.php
Class Namespace_Modulename_Model_Observer extends Mage_Core_Model_Abstract
{
public function addAttributeSetHandle(Varien_Event_Observer $observer)
{
$page = (int) Mage::app()->getRequest()->getParam('id');
$handle = sprintf('modulename_controller_action_id_%s', $page);
$update = $observer->getEvent()->getLayout()->getUpdate();
$update->addHandle($handle);
}
}
2. Enable the observer in module's config.xml
// Namespace/Modulename/etc/config.xml
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<attributesethandle>
<class>Namespace_Modulename_Model_Observer</class>
<method>addAttributeSetHandle</method>
</attributesethandle>
</observers>
</controller_action_layout_load_before>
</events>
</frontend>
3. And then easily change the layout for the handle modulename_controller_action_id_12 in modules layout xml.
<modulename_controller_action_id_12>
<remove name="header"/>
<remove name="footer"/>
<reference name="root">
<action method="setTemplate">
<template>page/1column.phtml</template>
</action>
</reference>
</modulename_controller_action_id_12>

Related

Magento 2 : Add custom script just after head tag

i want to add custom script just after the start of head tag.
like.
<head>
<script>console.log("I'm loaded!");</script>
i tried to add code in default_head_blocks.xml
<referenceContainer name="head.additional">
<block class="Custom\Module\Block\Success" template="Custom_Module::success/head.phtml"/>
</referenceContainer>
=> output :
<script>console.log("I'm loaded!");</script>
</head>
this code are using add script before the end of head tag.
Please check Below code
Block => Custom/Module/Block/Onepage/Success.php
namespace Custom\Module\Block\Onepage;
use Magento\Framework\View\Element\Template;
class Success extends \Magento\Checkout\Block\Onepage\Success {
public function getOrder()
{
$objectManager =\Magento\Framework\App\ObjectManager::getInstance();
$helper = $objectManager->get('Custom\Module\Helper\Data');
$lastOrderId = $this->getOrderId();
if (empty($lastOrderId))
{
return null;
}
$orderData = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($this->getOrderId());
return $orderData;
}
}
Helper => Custom\Module\Helper\Data.php
namespace Custom\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* #param \Magento\Framework\App\Helper\Context $context
*/
protected $_request;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\Request\Http $request
) {
$this->_request = $request;
parent::__construct($context);
}
public function getConfigValue($value = '') {
return $this->scopeConfig
->getValue($value,\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
}
public function getTemplate()
{
if ($this->getConfigValue('custom_general/general/active') == 1) {
$template = 'Custom_Module::checkout/success.phtml';
} else {
$template = 'Magento_Checkout::success.phtml';
}
return $template;
}
}
di.xml => etc\di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/ObjectManager/etc/config.xsd">
<preference for="Magento\Checkout\Block\Onepage\Success" type="Custom\Module\Block\Onepage\Success"/>
</config>
Layout Xml => Custom/Module/view/frontend/layout/default.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="require.js">
<action method="setTemplate">
<argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
</action>
</referenceBlock>
</body>
</page>
Template => Custom/Module/view/frontend/templates/success/head.phtml
<script>
console.log("I'm loaded!");
</script>
Please help me and solve this issue
Thanks in advance.
I am not sure if this is the correct way or not, but I have got a lead.
By default magento 2 usees the root.phtml file to setup head content accordingly, which is located in vendor/magento/module-theme/view/base/templates/root.phtml (if it has not been overridden).
Here, the $requireJs variable is loaded first in the head block. The $requireJs variable is defined in the render method inside Page class -which is located in vendor/magento/framework/view/Result/Page.php.
In this file, $requireJs contains the require.js block. And the require.js block is defined in vendor/Magento/module-theme/view/frontend/layout/default.xml :
<block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::page/js/require_js.phtml" />
Solution
1) Copy require_js.phtml from vendor/magento/module-theme/view/frontend/templates/page/js to your theme app/design/frontend/{VENDOR}/{THEME_NAME}/Magento_Theme/templates/page/js/
2) Now you can add your script like this:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* #escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
UPDATE (Using Module)
Overriding the require.js block is not an elegant solution. if anyone has a good solution please answer. For now edit your layout xml:
<referenceBlock name="require.js">
<action method="setTemplate">
<argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
</action>
</referenceBlock>
and inside success/head.phtml add your code:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* #escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
I found a simple way of doing it that seems very reasonable, because it uses existing features in the adminhtml theme without any need to override/intercept anything.
Background
Like #sanchit-gupta mentioned, the root.phtml template is used as the basis to render both the frontend and adminhtml areas, and so is the associated class \Magento\Framework\View\Result\Page, which always looks for a block named head.additional before rendering.
This block exists in the frontend layouts by default, but unfortunately it doesn't exist in the adminhtml layout.
Solution
With that in mind, the current best way (as of 2.3.x) to add inline <scripts> to the adminhtml's <head> section is to add any head.additional block: it will be automatically rendered by the framework. It either has to be a ListText block so that it renders all it's children automatically, or a Template with a specified template file. I actually chose too nest my actual block inside the ListText block just to keep the same mechanism available as in the frontend area (i.e. for compatibility with other plugins that might be doing the same).
Example
In your custom module or theme, add a layout update that inserts the following block into the body of the page layout (which is just to do it the same way as it's done in Magento 2 core for the frontend area):
<body>
<block class="Magento\Framework\View\Element\Text\ListText" name="head.additional">
<block name="your_block" class="Magento\Framework\View\Element\Template" template="Your_Module::your/template.phtml" />
</block>
</body>
Done! Your template will render inside <head></head> – without any awkward overrides or "hacks".
What's more, if other modules also reference head.additional in the adminhtml area, they will be compatible with your code.

Magento Module Not Working : Adminhtml add tab to Product View

I'm having trouble getting a new module to work. To begin with I just want to add an additional tab to the Product Edit screen in the adminhtml. I want this tab to show underneath the standard "Custom Options" tab. I have my module showing up in the Configuration > Advanced > Advanced > Disable Module output section.
So here's what I have, seen any mistakes?
Path : app\etc\modules\ns>_CustomerHistory.xml
<?xml version="1.0"?>
<config>
<modules>
<<ns>_CustomerHistory>
<active>true</active>
<codePool>local</codePool>
</<ns>_CustomerHistory>
</modules>
</config>
Path: app\code\local\\CustomerHistory\etc\config.xml
<?xml version="1.0"?>
<config>
<modules>
<<ns>_CustomerHistory>
<version>0.1.0</version>
</<ns>_CustomerHistory>
</modules>
<global>
<blocks>
<CustomerHistory>
<class><ns>_CustomerHistory_Block</class>
</CustomerHistory>
</blocks>
<models>
<CustomerHistory>
<class><ns>_CustomerHistory_Model</class>
</CustomerHistory>
</models>
</global>
<adminhtml>
<layout>
<updates>
<CustomerHistory>
<file>CustomerHistory.xml</file>
</CustomerHistory>
</updates>
</layout>
</adminhtml>
</config>
Path : app\code\local\ns>\CustomerHistory\Block\Adminhtml\Product\Edit\Tab.php
<?php
class <ns>_CustomerHistory_Block_Adminhtml_Catalog_Product_Edit_Tab extends Mage_Adminhtml_Block_Widget
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
public function canShowTab()
{
return true;
}
public function getTabLabel()
{
return $this->_('Custom Tab');
}
public function getTabTitle()
{
return $this->_('Custom Tab');
}
public function isHidden()
{
return false;
}
public function getTabUrl()
{
return $this->getUrl('*/*/customtab', array('_current' => true));
}
public function getTabClass()
{
return 'ajax';
}
}
?>
Path : app\design\adminhtml\default\default\layout\CustomerHistory.xml
<?xml version="1.0"?>
<layout>
<adminhtml_catalog_product_edit>
<reference name="product_tabs">
<block type="CustomerHistory/adminhtml_catalog_product_edit_tab" name="custom_tab" template="CustomerHistory/catalog/product/edit/tab.phtml" />
<action method="addTab">
<name>Custom Tab</name>
<block>custom_tab</block>
</action>
</reference>
</adminhtml_catalog_product_edit>
</layout>
Path : app\design\adminhtml\default\default\template\CustomerHistory\catalog\product\edit\tab.phtml
<?php
/**
* Custom tab template
*/
?>
<div>
<h1>Hello</h1>
</div>
It goes without saying here, any help would be greatly appreciated!

Custom url in Magento

I want to create url like {base_url}/customize/{product_slug}.phtml
Could please help how to make this of url Magento?
Currently I have created "CustomizeController.php" file
<?php
class ProductCustomizer_ProductCustomizer_CustomizeController extends Mage_Core_Controller_Front_Action {
public function indexAction(){
echo 'test mamethode';
$product = Mage::getModel("productcustomizer/customizeproduct")->getProduct();
}
public function mamethodeAction(){
echo 'test mamethode';
}
}
and below code in config.xml file
<productcustomizer_customize_index>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
<reference name="content">
<block type="productcustomizer/customize" name="productcustomizer_customize" template="productcustomizer/customize.phtml"/>
</reference>
</productcustomizer_customize_index>
Please assign in $url_key to resolve the issue.
$rewrite = Mage::getModel('core/url_rewrite');
$rewrite->setStoreId($store_id) ->setIdPath('customize/'.$url_key) ->setRequestPath('customize/'.$url_key.'.html') ->setTargetPath('customize/index/action/id/'.$url_key) ->setIsSystem(true) ->save();
I have found solution you can set routing using config.xml file
<global>
<rewrite>
<productcustomizer_url>
<from><![CDATA[#^/customize/#]]></from>
<to><![CDATA[/productcustomizer/customize/index/product/]]></to>
<complete>1</complete>
</productcustomizer_url>
</rewrite>
<global>

Punching a hole through Magento Full Page Cache correctly

I have been pulling my hair out over trying to get a hole punched out for the price block on the product page. I have looked at numerous sources, including some from you good people at stackoverflow, but I have been getting a fatal error, so something is incorrect. Here are some sources that I used:
http://invisiblezero.net/magento-ee-punch-hole-in-full-page-cache/
http://www.kingletas.com/2012/09/how-does-magento-full-page-cache-works.html
Magento full page cache
Trying get dynamic content hole-punched through Magento's Full Page Cache
How to implement magento cache hole punching for shopping cart block
As you can see, I have been all over, and I have read more in addition to this but some of them conflict a litt, and I think that is where I have my issue, now let me post some code for you.
cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<SpecialPrice>
<block>catalog/product_price</block>
<name>product.pricing</name>
<placeholder>CATALOG_PRODUCT_PRICE</placeholder>
<container>MyStore_SpecialPrice_Model_Container_Cache</container>
<cache_lifetime>8640</cache_lifetime>
</SpecialPrice>
</placeholders>
</config>
cache.php
<?php
class MyStore_SpecialPrice_Model_Container_Cache extends Enterprise_PageCache_Model_Container_Abstract
{
/**
* Get customer identifier from cookies
*
* #return string
*/
protected function _getIdentifier()
{
return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}
/**
* Get cache identifier
*
* #return string
*/
protected function _getCacheId()
{
return 'CATALOG_PRODUCT_PRICE' . md5($this->_placeholder->getAttribute('cache_id') . $this->_getIdentifier());
}
/**
* Render block content
*
* #return string
*/
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template);
return $block->toHtml();
}
}
congig.xml
<?xml version="1.0"?>
<config>
<modules>
<MyStore_SpecialPrice>
<version>0.1.0</version>
</MyStore_SpecialPrice>
</modules>
<frontend>
<events>
<catalog_product_get_final_price>
<observers>
<MyStore_SpecialPrice_Model_Observer>
<class>MyStore_SpecialPrice_Model_Observer</class>
<method>setSpecialPrice</method>
</MyStore_SpecialPrice_Model_Observer>
</observers>
</catalog_product_get_final_price>
</events>
</frontend>
<admin>
<routers>
<SpecialPrice>
<use>admin</use>
<args>
<module>MyStore_SpecialPrice</module>
<frontName>SpecialPrice</frontName>
</args>
</SpecialPrice>
</routers>
</admin>
<global>
<models>
<SpecialPrice>
<class>MyStore_SpecialPrice_Model</class>
</SpecialPrice>
</models>
</global>
</config>
snippet from local.xml
<reference name="right">
<block type="catalog/product_price" name="product.pricing" template="catalog/product/product-price-block.phtml" before="-" >
Let me know if there is anything that jumps out to you.

How do I display a template to only specific product pages in Magento?

I have a parts configurator that I only want to have appear for a certain product SKU. In my catalog/product/view.html file I have included the following code:
<?php
if ($_product->getSku() == '10007-') {
echo $this->getLayout()->createBlock('cms/block')->setBlockId('partfinder_selector')->toHtml();
}
?>
Then, in the xml file for the configurator:
<catalog_product_view>
<reference name="content">
<block type="partfinder/selector" name="partfinder_selector" before="-" template="partfinder/selector.phtml"/>
</reference>
The issue is, with this setup, the configurator appears on all product pages. Do I have something wrong in my code, or is there a better method for what I am trying to accomplish. Any help would be appreciated.
Note, this solution doesn't require any 'configurator xml', so you can leave that out. You'll be able to use an if statement like in your example to select only the sku you want.
Create directories:
app/code/local/Partfinder/Selector/Block
app/code/local/Partfinder/Selector/etc
For your app/etc/modules as Partfinder_Selector.xml:
<config>
<modules>
<Partfinder_Selector>
<active>true</active>
<codePool>local</codePool>
</Partfinder_Selector>
</modules>
</config>
In your app/code/local/Partfinder/Selector/etc as config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Partfinder_Selector>
<version>0.1.0</version>
</Partfinder_Selector>
</modules>
<global>
<blocks>
<partfinderselector>
<class>Partfinder_Selector_Block</class>
</partfinderselector>
</blocks>
</global>
</config>
In your app/code/local/Partfinder/Selector/Block as Menu.php:
<?php
class Partfinder_Selector_Block_Menu extends Mage_Core_Block_Template
{
}
?>
In your app/design/pkgname/themename/template/Partfinder save a file called selector.phtml containing your block code.
In catalog/product/view.phtml:
<?php if ($_product->getSku() == "10007-"): ?>
<?php echo $this->getLayout()->createBlock('partfinderselector/menu')->setTemplate('partfinder/selector.phtml')->toHtml(); ?>
<?php endif; ?>
First, when you use echo $this->getLayout()->createBlock('cms/block')--setBlockId('partfinder_selector')->toHtml()
Magento tries to output the static block with the id partfinder_selector.
Second, <reference name="content"> refers to the content block which is a "core/text_list" which automatically outputs its children, so your block will be automatically output by the content block.
The solution would be, in your xml file use
<reference name="product.info"> instead of "content"
and use $this->getChildHtml('partfinder_selector') in catalog/product/view.html
You are require to follow below steps to do this:
1) - In the /Namespace/Module/etc/config.xml you have to write the following thing:
<config>
<modules>
<Namespace_Module>
<version>0.1.0</version>
</Namespace_Module>
</modules>
<global>
<helpers>
<module>
<class>>Namespace_Module_Helper</class>
</module>
<catalog>
<rewrite>
<product_view>Namespace_Module_Helper_View</product_view>
</rewrite>
</catalog>
</helpers>
</global>
</config>
2) - Register module in magento module list under app/etc/modules/Namespace_Module.xml
<config>
<modules>
<Namespace_Module>
<active>true</active>
<codePool>local</codePool>
<depends />
</Namespace_Module>
</modules>
</config>
3) - You have to create your file under /Namespace/Module/Helper/view.php.
Please find below code
class KNamespace_Module _Helper_View extends Mage_Catalog_Helper_Product_View
{
public function initProductLayout($product, $controller)
{
$design = Mage::getSingleton('catalog/design');
$settings = $design->getDesignSettings($product);
if ($settings->getCustomDesign()) {
$design->applyCustomDesign($settings->getCustomDesign());
}
$update = $controller->getLayout()->getUpdate();
$update->addHandle('default');
$controller->addActionLayoutHandles();
$update->addHandle('PRODUCT_TYPE_' . $product->getTypeId());
$update->addHandle('PRODUCT_' . $product->getId());
//update code
if(preg_match('/10007-/',$product->getSku())){$update->addHandle('PRODUCT_NEWLAYOUT');}
$controller->loadLayoutUpdates();
// Apply custom layout update once layout is loaded
$layoutUpdates = $settings->getLayoutUpdates();
if ($layoutUpdates) {
if (is_array($layoutUpdates)) {
foreach($layoutUpdates as $layoutUpdate) {
$update->addUpdate($layoutUpdate);
}
}
}
$controller->generateLayoutXml()->generateLayoutBlocks();
// Apply custom layout (page) template once the blocks are generated
if ($settings->getPageLayout()) {
$controller->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout());
}
$currentCategory = Mage::registry('current_category');
$root = $controller->getLayout()->getBlock('root');
if ($root) {
$controllerClass = $controller->getFullActionName();
if ($controllerClass != 'catalog-product-view') {
$root->addBodyClass('catalog-product-view');
}
$root->addBodyClass('product-' . $product->getUrlKey());
if ($currentCategory instanceof Mage_Catalog_Model_Category) {
$root->addBodyClass('categorypath-' . $currentCategory->getUrlPath())
->addBodyClass('category-' . $currentCategory->getUrlKey());
}
}
return $this;
}
}
add code in catalog.xml:-
partfinder/selector.phtml
Hope this will work for you. :)
Best of luck.
Jitendra Padmashali, KrishInc

Categories