In magento the following page layouts are defined by default: empty, one_column, two_columns_left, two_columns_right and three_columns.
I would like to remove two_columns_left, two_columns_right for my layout, since the user can choose it in CMS and product design section, but it doesn't work.
How do I change an XML configuration file to accomplish this?
I found that I can remove it from the app/core/community/Mage/Page/etc/config.xml, but I would like to do this without change any core source, to be updateable.
I stumbled across this question looking for something similar and want to share my implementation. Maybe it is helpful for someone out there.
The following will remove the empty, 2_columns_right and 3_columns layouts from the list of available templates. Just change the remove_layouts directive in the config.xml below to remove whatever you want to remove.
I created a module (in fact the very first module I've ever built for magento) and placed the following in the file app/etc/modules/Labor_Templates.xml:
<?xml version="1.0"?>
<!--
/**
* This module changes the available templates. Only "1 column" and
* "2 column-left" will be available.
*/
-->
<config>
<modules>
<Labor_Templates>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Page />
</depends>
</Labor_Templates>
</modules>
</config>
Next, we need a config.xml found in /app/code/local/Labor/Templates/etc:
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Overrides the config to only allow "1 column" and "2 column left" layouts.
*/
-->
<config>
<modules>
<Labor_Templates>
<version>1.0.0</version>
</Labor_Templates>
</modules>
<global>
<models>
<template>
<class>Labor_Templates_Model</class>
</template>
<page>
<rewrite>
<config>Labor_Templates_Model_Config</config>
</rewrite>
</page>
</models>
<page>
<remove_layouts>
<layouts>empty,two_columns_right,three_columns</layouts>
</remove_layouts>
</page>
</global>
</config>
Notice, that I've added the remove_layouts directive. Finally we write our own Labor_Templates_Model_Config class:
<?php
/**
* Overrides the Overrides the core module Mage_Page_Model_Config in order to
* remove unused template layouts. This is done by handling remove_layout
* directives.
*/
class Labor_Templates_Model_Config extends Mage_Page_Model_Config {
const XML_PATH_PAGE_REMOVE_LAYOUTS = 'global/page/remove_layouts';
/**
* Initialize page layouts list
*
* #return Labor_Templates_Model_Config
*/
protected function _initPageLayouts()
{
parent::_initPageLayouts();
return $this->_removePageLayouts(self::XML_PATH_PAGE_REMOVE_LAYOUTS);
}
/**
* Removes page layouts found in the remove_layouts XML directive
*
* #return Labor_Templates_Model_Config
*/
protected function _removePageLayouts($xmlPath)
{
if (!Mage::getConfig()->getNode($xmlPath) || !is_array($this->_pageLayouts)) {
return $this;
}
foreach (explode(',', (string)Mage::getConfig()->getNode($xmlPath)->children()->layouts) as $toRemove) {
unset($this->_pageLayouts[$toRemove]);
}
return $this;
}
}
Works and tested with Magento 1.7.0.
Because the root layouts are parsed from config XML, and due to the way in which config XML is merged together, your simplest option (as you've surmised) is to edit app/core/community/Mage/Page/etc/config.xml.
If you are really concerned with not editing core files - always a legitimate & fun endeavor - you could create a module that can handle remove_layout directives, which you could add in your module's config under the same xpath. The class you would be rewriting is Mage_Page_Model_Config - see the _appendPageLayouts() and getPageLayouts() methods.
Related
I have an external website which allows a customer to design a product, then uses an HTML form to post this data. I need to take this information and add this product (with custom options) to the customer's cart in our Magento website, but I'm not sure how to go about this.
I tried something simple at first using URL redirect, but Magento 1.9.X no longer supports adding to cart like this:
$cart_url = "website.com/checkout/cart/add/product=" . $product_id . "&qty=1" //Include custom options somehow
<form action=<?php echo $cart_url?>>
<input type="hidden" value="pid"> product id </input>
<input type="hidden" value="option1"> custom option 1</input>
</form>
Doing research shows that I can also add an item with custom options through either writing a custom Controller or Events/Observers to add the item, but as I'm new to Magento I'm not sure how to trigger events and observer functions from outside of Magento.
Any help to point me in the right direction would be appreciated.
You will have to create a custom module in magento.
Create a file app/etc/MyExtension_AddProductFromUrl.xml
<config>
<modules>
<MyExtension_AddProductFromUrl>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Checkout/>
</depends>
</MyExtension_AddProductFromUrl>
</modules>
</config>
Create a file app/code/local/MyExtension/AddProductFromUrl/etc/config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<MyExtension_AddProductFromUrl>
<version>0.1.0</version>
</MyExtension_AddProductFromUrl>
</modules>
<frontend>
<routers>
<checkout>
<args>
<modules>
<MyExtension_AddProductFromUrl before="Mage_Checkout">MyExtension_AddProductFromUrl</MyExtension_AddProductFromUrl>
</modules>
</args>
</checkout>
</routers>
</frontend>
</config>
Create a file app/code/local/MyExtension/AddProductFromUrl/controllers/CartController.php
<?php
require_once 'Mage/Checkout/controllers/CartController.php';
class MyExtension_AddProductFromUrl_Checkout_CartController extends Mage_Checkout_CartController {
# overloaded addAction
public function addAction() {
// generate form_key if missing or invalid
if (!($formKey = $this->getRequest()->getParam('form_key', null)) || $formKey != Mage::getSingleton('core/session')->getFormKey()) {
$this->getRequest()->setParams(array('form_key' =>Mage::getSingleton('core/session')->getFormKey()));
}
// do parent actions
parent::addAction();
}
}
?>
Also see
Magento - Add a product to the cart via query string without form_key parameter
https://magento.stackexchange.com/questions/37779/i-want-to-use-add-to-cart-via-url-in-magento-1-8-but-dont-know-which-files-to-c
I fought with this for a bit in 1.9.0.1, but St0iK's solution above worked with the following changes:
1) place the module .xml file in app/etc/modules (as opposed to app/etc)
2) In the controller file - i had to remove _Checkout_
class MyExtension_AddProductFromUrl_Checkout_CartController extends Mage_Checkout_CartController {
to
class MyExtension_AddProductFromUrl_CartController extends Mage_Checkout_CartController {
After these minor edits, it works perfectly. Not sure if these were only necessary for 1.9.0.1, but for whatever reason, they were.
To add a product to the cart, i just use the URL format
YOURSTORE.com/checkout/cart/add/product/123/qty/1
Great solution for external PPC or SEO landing pages that need a simple "buy now" button that drops right into your magento cart.
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 have a Magento store installed, and when a product is duplicated in the backend, Magento sets its status to Disabled by default. I don't want that to happen, the duplicated product should have its status copied from the original product as well.
In this post a partial solution was given. I see where I can find the config.xml and make the necessarry changes. However, where do I put such an observer class? Which file should I use/create and would that require any changes to the config.xml input?
Or does somebody have an overall solution for this issue? Thanks in advance!
Try this:
Create: app/code/local/MagePal/EnableDuplicateProductStatus/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<MagePal_EnableDuplicateProductStatus>
<version>1.0.1</version>
</MagePal_EnableDuplicateProductStatus>
</modules>
<global>
<models>
<enableduplicateproductstatus>
<class>MagePal_EnableDuplicateProductStatus_Model</class>
</enableduplicateproductstatus>
</models>
<events>
<catalog_model_product_duplicate>
<observers>
<enableduplicateproductstatus>
<type>singleton</type>
<class>enableduplicateproductstatus/observer</class>
<method>productDuplicate</method>
</enableduplicateproductstatus>
</observers>
</catalog_model_product_duplicate>
</events>
</global>
</config>
Create: app/code/local/MagePal/EnableDuplicateProductStatus/Model/Observer.php
class MagePal_EnableDuplicateProductStatus_Model_Observer
{
/**
* Prepare product for duplicate action.
*
* #param Varien_Event_Observer $observer
* #return object
*/
public function productDuplicate(Varien_Event_Observer $observer)
{
$newProduct = $observer->getEvent()->getNewProduct();
$newProduct->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
return $this;
}
}
Create: app/etc/modules/MagePal_EnableDuplicateProductStatus.xml
<?xml version="1.0"?>
<config>
<modules>
<MagePal_EnableDuplicateProductStatus>
<active>true</active>
<codePool>local</codePool>
</MagePal_EnableDuplicateProductStatus>
</modules>
</config>
Then clear cache and try duplicating a product.
read more # :
http://magento4u.wordpress.com/2009/06/08/create-new-module-helloworld-in-magento/
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
make a new product active by default in magento
I found error on this code and find out the solution below:
On app/code/local/MagePal/EnableDuplicateProductStatus/etc/config.xml change
<method> duplicateProduct </method>
TO
<method>productDuplicate</method>
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);
}
}
Hi
I have assigned 20 products to a category called Phone, I would like to create a module to retrieve these products and displayed as a list format. Could someone tell me how to do this?
thanks
To create a widget (which you can insert via the cms) that uses a category to do something, begin by creating a standard module structure with:
/Block
/etc
/Helper
/Model
Note that in my code samples and filenames below you will need to replace [Namespace], [Module], and [module] with the appropriate namespace and module that you want to use. Case is important!
Begin by creating app/code/local/[Namespace]/[Module]/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<[Namespace]_[Module]>
<version>0.0.1</version>
</[Namespace]_[Module]>
</modules>
<global>
<helpers>
<[module]>
<class>[Namespace]_[Module]_Helper</class>
</[module]>
</helpers>
<blocks>
<[module]>
<class>[Namespace]_[Module]_Block</class>
</[module]>
</blocks>
<models>
<[module]>
<class>[Namespace]_[Module]_Model</class>
</[module]>
</models>
</global>
</config>
Then create a app/code/local/[Namespace]/[Module]/etc/widget.xml This widget includes a setting called "selected_category"
<?xml version="1.0"?>
<widgets>
<[module]_category type="[module]/category">
<name>[Module]: Category</name>
<description type="desc">Adds a [module] for a category.</description>
<parameters>
<selected_category>
<label>Categories</label>
<visible>1</visible>
<required>1</required>
<type>select</type>
<source_model>[module]/catopt</source_model>
</selected_category>
</parameters>
</[module]_category>
</widgets>
Then the obligatory Helper file in app/code/local/[Namespace]/[Module]/Helper/Data.php
<?php
class [Namespace]_[Module]_Helper_Data extends Mage_Core_Helper_Abstract
{
}
Then a model to allow the user to select the category in the widget dialog box. This goes in app/code/local/[Namespace]/[Module]/Model/Catopt.php
<?php
class [Namespace]_[Module]_Model_Catopt
{
public function toOptionArray()
{
$category = Mage::getModel('catalog/category');
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
$arr = array();
if ($ids){
foreach ($ids as $id){
$cat = Mage::getModel('catalog/category');
$cat->load($id);
array_push($arr, array('value' => $id, 'label' => $cat->getName().' ('.$cat->getProductCount().')'));
}
}
uasort($arr, array($this, 'labelsort'));
return $arr;
}
function labelsort($a, $b){
if ( $a['label'] == $b['label'] )
return 0;
else if ( $a['label'] < $b['label'] )
return -1;
else
return 1;
}
}
Finally on the module side of things a block which goes in app/code/local/[Namespace]/[Module]/Block/Category.php This block is using a custom .phtml file for it's display but you can change that to use anything else you might need to show by changing the type of block and input to setTemplate.
<?php
class [Namespace]_[Module]_Block_Category
extends Mage_Core_Block_Template
implements Mage_Widget_Block_Interface
{
/**
* A model to serialize attributes
* #var Varien_Object
*/
protected $_serializer = null;
/**
* Initialization
*/
protected function _construct()
{
$this->_serializer = new Varien_Object();
$this->setTemplate('[module]/[module].phtml');
parent::_construct();
}
public function getCategory(){
return $this->getData('selected_category');
}
}
Don't forget to add a module install file under /app/etc/modules/[Namespace]_[Module].xml like this
<?xml version="1.0"?>
<config>
<modules>
<[Namespace]_[Module]>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Cms />
</depends>
</[Namespace]_[Module]>
</modules>
</config>
Lastly you need to create a template file to display the block content. This will go under /app/design/frontend/default/default/template/[module]/[module].phtml
This .phtml file can use $this->getCategory() to get the category and go from there. You can easily customize the block included in these samples to display the default magento product list grids instead of using a custom .phtml file.
No need to create a module. just place this in a block in your layout: It will show all the products linked to the specified category (id=XXX).
<!-- Show all products linked to this category -->
<block type="catalog/product_list" name="best_sellers" template="catalog/product/list.phtml">
<action method="setCategoryId">
<category_id>XXX</category_id>
</action>
</block>
Update:
You can create a module that overide the "Mage_Catalog_Block_Product_List", and add a method to limit a certain number of products.
1- Create "app/code/local/[Namespace]/Catalog/etc/config.xml" and put this in it:
<config>
<modules>
<[Namespace]_Catalog>
<version>0.1.0</version>
</[Namespace]_Catalog>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<product_list>[Namespace]_Catalog_Block_Product_List</product_list>
</rewrite>
</catalog>
</blocks>
</global>
</config>
2- Override the Block by creating the class: "app/code/local/[Namespace]/Catalog/Block/Product/List.php"
class [Namespace]_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_List
{
/**
* Default number of product to show.
*
* #var int default = 5
*/
private $_productCount = 5;
/**
* Initialize the number of product to show.
*
* #param int $count
* #return Mage_Catalog_Block_Product_List
*/
public function setProductCount($count)
{
$this->_productCount = intval($count);
return $this;
}
/**
* Get the number of product to show.
*
* #return int
*/
public function getProductCount()
{
return $this->_productCount;
}
}
3- Overide your theme to add the product limit feature:
copy "app/design/frontend/default/default/template/catalog/product/list.phtml" to "app/design/frontend/default/[your_theme]/template/catalog/product/list.phtml"
// Insert between the foreachs and <li> for the list mode and grid mode
<?php if($_iterator < $this->getProductCount()) : ?>
...
// Insert between the foreachs and <li> for the list mode and grid mode
<?php endif; ?>
4- In the home page content tab, add this line where you want it:
// category_id = Procucts linked to this category
// product_count = Maximum number of product
{{block type="catalog/product_list" category_id="7" product_count="3" template="catalog/product/list.phtml"}}
Hope this help someone.
Thanks for the informative post. For those of you who are not so fluent in PHP but landed on this page because you were looking for a solution to display a product name list from a given category I managed to find a solution by simply modifying someone else's template file. For this solution I found the best suited extension was:
http://www.cubewebsites.com/blog/magento/extensions/freebie-magento-featured-products-widget-version-2/
(find the latest version on github: https://github.com/cubewebsites/Cube-Category-Featured-Products/tags).
After logging in and out and clearing the cache I was able to insert the widget into a static block and modify the .phtml file used to produce the custom view that I wanted.
The widget looked like this when inserted:
{{widget type="categoryfeatured/list" template="categoryfeatured/block.phtml" categories="118" num_products="10" products_per_row="1" product_type="all"}}.
I simply opened
app/design/frontend/base/default/template/categoryfeatured/block.phtml
copied it's contents and created a new .phtml file called category_product_listing.phtml
and then pointed the widget instance to the new .phtml file as follows:
{{widget type="categoryfeatured/list" template="categoryfeatured/category_product_listing.phtml" categories="118" num_products="10" products_per_row="1" product_type="all"}}.
I then went through this .phtml file with my basic understanding of PHP and removed all items like images, add to cart buttons, reviews, etc. until I was left with just the basic linked product title as well as the category title left intact.
I hope this helps someone as I spent hours trying to figure this out.