I have a problem with my related and upsells.
When a customer login, my related and upsells not display in product_view.
The three most likely ways in which this can happen involve the following:
Layout XML
PHP/PHTML
CSS
Layout XML: grep your layout xml for <customer_logged_in> and see if there are any <remove /> nodes referring to these blocks. Also check for <action> tags with unsetChild method calls that refer to these blocks.
PHP/PHTML: It's possible that the templates and class definitions for these blocks have had logic added to them to check for customer logged in state. This would be an inefficient way to accomplish this, but it's possible. You'll need to check the templates (google for Magento template path hints) and the block classes in which they are rendered; see if they have been customized.
CSS: This is the most unlikely candidate, but I've seen developers set display:none based on <body> classes added via layout XML. This could be seen as an addBodyClass call in the <customer_logged_in> layout update handle, which I described how to find above.
Related
As I have seen for each Template file there exists a layout which connect blocks of particular Module. I struggled to understood each pieces in Magento, let me explain what I had done,
Consider a Template app\design\frontend\base\default\template\catalog\category\view.phtml
we have, $_category = $this->getCurrentCategory();
this function belongs to Block app\code\core\Mage\Catalog\Block\Category\view.php
What Magento's Template does is, it search for Layout instead of Block file,
i.e, Inside Layout file, app\design\frontend\base\default\layout\catalog.xml
we have, <block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
In this layout definition, the type attribute defines the block file,
i.e., Through layout file the Template gets the value of getCurrentCategory() function from Block.
Also we have <reference name="content">, <reference name="left"> which decides where to append the template.
My Question is,
Why can't Templates get the Value directly from Block without referring Layout?
Why Magento is not allowing us to do so?
What is the use of Layout while considering these 3 Block,Layout and Template?
1 - Why can't Templates get the Value directly from Block without referring Layout?
They can. Using your example:
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
This can be written as:
<block type="catalog/category_view" name="category.products">
And within the actual block (app/code/core/Mage/Catalog/Block/Category/View.php):
...
public function _construct()
{
parent::_construct();
// set the template here instead
$this->setTemplate('catalog/category/view.phtml');
}
...
2 - Why Magento is not allowing us to do so?
Magento does allow you to do so. The Magento layout system is very powerful, albeit very difficult to understand it initially.
3 - What is the use of Layout while considering these 3 Block,Layout and Template?
I will use this question to clear some of your misconceptions. As stated the Magento layout is very powerful and allows a lot of flexibility but at first glance this is not obvious. I will try explain best I can.
Imagine you created your own module within Magento and the Layout did not exist - everything was controlled within the 'controllers'. You would need to rewrite/extend/hack core Magento code to get things the way you wanted. If you wanted an extra widget on the category view page, you would need to override a controller method, or add your own controller.
The Magento Layout overcomes this by creating a global layout file which you can extend without messing with the core infrastructure.
Lets take your example.
On a category view page, if we wanted to change the above template, catalog/category/view.phtml, to something else, say my/category/view.phtml, we could do this:
<!-- this is the controller handle -->
<catalog_category_view>
<!--
by referencing, we are actually referring to a
block which has already been instantiated. the
name is the unique name within the layout.
generally all blocks should have a name and it
must be unique. however there can also be
anonymous blocks but thats out of scope of this
answer
-->
<reference name="category.products">
<!--
the layout allows us to fire methods within
the blocks. in this instance we are actually
firing the setTemplate method on the block
and providing a "template" argument.
this is the same as calling:
$this->setTemplate('my/category/view.phtml');
within the block.
-->
<action method="setTemplate">
<template>my/category/view.phtml</template>
</action>
</reference>
</catalog_category_view>
Just to reiterate:
Also we have <reference name="content">, <reference name="left"> which decides where to append the template.
This is incorrect. The "reference" tag allows you to reference blocks that are already instantiated. Just for completeness - the following example shows you how you can reference another block and place a block within it:
<!--
the default layout handle which is call on nearly all
pages within magento
-->
<default>
<!--
we are not referencing the "left" block
we could if we wanted reference "right",
"content" or any other blocks however
these are the most common
-->
<reference name="left">
<!--
add a block
in this example we are going to reference
"core/template" which translates to:
Mage_Core_Block_Template
which exists at:
app/code/core/Mage/Core/Block/Template.php
-->
<block type="core/template" name="my.unique.name.for.this.block" template="this/is/my/view.phtml" />
</reference>
</default>
Further reading: Introducing The Magento Layout
To answer your question, you need to dig down Magento's MVC approach,
A webpage is divided into several parts logically, for example, header, body, footer, etc., making the page layout organized and easy to adjust. Magento provides such flexibility through Layout XML files. Magento processes those layout files and render them into web pages.
Layout files act as detailed instructions to the application on how to build a page, what to build it with and the behavior of each building block.
Layout files are separated on a per-module basis, every module bringing with it its own layout file .The system is built this way in order to allow seamless addition and removal of modules without effecting other modules in the system.
In Magento, the View component of Model, View, Controller directly references system models to get the information it needs for display.
The View has been separated into Blocks and Templates. Blocks are PHP objects, Templates are "raw" PHP files that contain a mix of HTML and PHP. Each Block is tied to a single Template file. Inside a phtml file, PHP's $this keyword will contain a reference to the Template’s Block object.
Layout files contains <handlers> which are mapped to MVC controller, so expect your handler
<adminhtml_example_index> to be used in adminhtml/example/index controller page
and
<reference name="content"> means that the blocks or other references inside those blocks will be available in content block on your theme templates.
Each page request in Magento will generate several unique Handles. The 'View' of Magento’s MVC pattern implementation is divided in two parts: Layout and Template. The template represents a HTML block while layout defines the location of the block on a web page.
In Magento’s MVC approach, it's not the responsibility of the controller to set variables for the View (in Magento’s case, the view is Layout and Blocks). Controllers set values on Models, and then Blocks read from those same models.
Your controller’s job is to do certain things to Models, and then tell the system it’s layout rendering time. It’s your Layout/Blocks job to display an HTML page in a certain way depending on the state of the system’s Models.
In Magento, when a URL is triggered,
It determines Controller and action
Action Method manipulates Models
Action loads layout and starts rendering
Template, read from Models, via Blocks
Block and child blocks render into HTML
I have a custom info.phtml file which is already working if placed at app\design\frontend\default\default\template\sales\order\info.phtml.
However, I do not want to use this approach since this is part of a module, so if later someone else overrides this file it'll brake the functionality. I've read about using custom blocks but I tried many different approaches without success.
Actually, the path you cite will only work when the theme package is set to default. The intended fallback theme for all files since CE1.4 is base/default. There's quite a lot to consider here, so let's break it down. Of course, being the end implementer of a Magento instance is luxurious because you can use any number of customization options without worrying about how to support other developers' needs. However, when developing a third party module for release to/consumption by others (as you are, it seems), then you have some tough decisions to make if you wish to ensure that output is modified in the way which your module intends/needs. Let's look at the template you mention, which is part of the means by which output is generated. This example contains several of the factors involved in the generation of output.
app/design/frontend/base/default/template/sales/order/info.phtml:
<?php $_order = $this->getOrder() ?>
<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<div class="page-title title-buttons">
<h1><?php echo $this->__('Order #%s - %s', $_order->getRealOrderId(), $_order->getStatusLabel()) ?></h1>
<?php echo $this->getChildHtml('buttons') ?>
</div>
Are you in the right place?
The first question to ask is, "What do I need to change, and where?" If the answer lies in the output of a child block (e.g. the output of $this->getChildHtml('buttons')), then customizing the output means specifying an alternate child (with multiple possibilities for customization). If not, then the change is likely local to the template/block environment.
Is the change entity-related?
For third-party devs, the ideal solution is to avoid theme-dependent output whenever possible. For example, if you needed to change or add to the data available directly from one of the constituent objects, it is possible to modify that object or its behavior via Magento's configuration XML using configuration-based rewrites or via the event-observer architecture. In the current example, $this->getOrder() is an instance of Mage_Sales_Model_Order, $this is an instance of Mage_Sales_Block_Order_Info, and it is possible to rewrite either of these to a different class. Also, the sales_order_load_after method can be observed to modify properties of the order object.
Can translations be used?
If there is a need to modify just a string, it is often possible to effect this change via Magento's translation functionality. In a template, any string rendered via the __() method is passed through translation. This is very easy to modify for the end-implementer in a theme-specific translate.csv file. For third-party developers a little configuration XML allows to specify an additional translation CSV file, even for a core module.
Am I stuck with markup?
If there is a need to change the view markup being presented, it's necessary to modify the source of the markup, which most often is a template file. This can be effected in a couple of ways. In the case of the order info block, the sales/order/info.phtml template is defined in the Magento constructor:
class Mage_Sales_Block_Order_Info extends Mage_Core_Block_Template
{
//snip...
protected function _construct()
{
parent::_construct();
$this->setTemplate('sales/order/info.phtml');
}
//snip...
}
This usually means that there is no specified template in layout XML. The next step is to determine if the block is in fact instantiated via layout XML or in the controller. In the case of the latter, there's no way to manipulate the block via layout XML, so you'll need to use one of many possible Magento/PHP options to change the _template property. If the block is instantiated via layout XML, great - it's easy to specify some custom layout XML to point to an alternate template which will not be present in any theme; you just need to know the handle(s) and names which the block has been given, which can be determined by searching for the block instantiation markup (e.g. search *app/design/frontend/* for type="sales/order_info". This will lead you to *.../base/default/layout/sales.xml*:
<sales_order_view translate="label">
<label>Customer My Account Order View</label>
<update handle="customer_account"/>
<reference name="my.account.wrapper">
<block type="sales/order_info" as="info" name="sales.order.info">
<block type="sales/order_info_buttons" as="buttons" name="sales.order.info.buttons" />
</block>
<!-- etc. -->
It's possible to then use the handles and names to update the block's _template property in your module's custom layout update XML file, e.g.:
<sales_order_view>
<reference name="sales.order.info">
<action method="setTemplate"><tpl>my/custom/template.phtml</...>
<!--
Instead of <reference> you can use the 'block' attribute:
<action method="setTemplate" block="sales.order.info"><tpl>my/custom/template.phtml</...>
-->
This would allow you to put your custom template in the base/default template directory, where it belongs. However, you'll notice that this block is instantiated in a number of handle:
You might want to use a utility handle and <update /> directive to encapsulate the instructions into one place and provide it to all of the stock handles.
Nothing's foolproof!
This is one of several approaches, but it's not foolproof. Depending on your extension consumer audience, you might want to scan layout XML and template directories for customizations of/changes from the stock template and provide a notice to the admin.
If you need your custom info.phtml as part of a module, then declare it in module's xml. Then you can place your custom phtml file in app\design\frontend\whatever\somethingelse\template\sales\order and it will override it. For example, see this thread about how to override existing template file.
This is done from layout xml of your module.
Just put the code below in your layout xml with needed changes as per your namespace, module and controller action which call that file:
<checkout_onepage_index>//Use correct Controller action
<reference name="checkout.onepage.payment">//Change reference name as per your need
<action method="setTemplate">
<template>giftcard/checkout/onepage/payment.phtml</template>//Path of phtml file in yourmodule template folder
</action>
</reference>
</checkout_onepage_index>
I want to add same login form in my site
is there any module available for that or we can have something else coding changes for this
please suggest me something
i want something like this :
http://livedemo00.template-help.com/magento_42632/
You could create a block of type customer/form_login. Using the XML as follows
<block type="customer/form_login" name="customer_small_login" template="customer/form/small-login.phtml" />
You can view the customer/form/login.phtml form for reference of what kind of fields your block is expecting.0
You can then add this to your sidebar using
<?php $this->getChildHtml('customer_small_login'); ?>
NOTE: Ensure your adding you XML block as a child node of the sidebar which you wish to include it in.
I have 3 questions that my normal Googling efforts haven't answered. I'm a in-house front end web developer that has been trying to learn Magento for the past two weeks. I'm also new to posting on Stack Overflow, so let me know if these would be better posted as separate questions or something.
1. Layouts - Making it so every single page uses the same layout
So most of my pages are using my 2columns-left layout, but not all of them. I have some set in my local.xml, and some I just hard coded in the .phtml pages directly. I would have thought the following code would make ALL pages use the same layout:
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
<action method="setIsHandle">
<applied>1</applied>
</action>
</reference>
There are a lot of pages I don't normally see when I work on the site that are stuck with the default Magento layouts, like the /cookies-enabled page, or the review pages. What's the best practice for unifying all pages if you want the same layout on the entire site, rather than having a block like this in local.xml for every single page?
2. Contact Us Form - Clicking the submit button doesn't work
I am editing the contact us page under CMS>Pages, and I think I am possibly missing the file that my form action is pointing to. The form shows up, but it doesn't submit.
Here is what I have on our Contact Us CMS page:
{{block type='core/template' name='contactForm' form_action="/contacts/index/post/" template='contacts/form.phtml'}}
Here's the error I get after clicking the submit button:
Not Found
The requested URL /contacts/index/post/ was not found on this server.
I've gone through the configuration settings and I think those are right, but maybe there is something else I have to do there.
3. Product Reviews - Getting an "Overall" rating to display
I have the review div that utilizes form.phtml showing up on my product pages after you login and add a review, but the ratings aren't being shown. I am apparently not satisfying the conditions of an if statement that controls if the ratings should be displayed. Below is the if statement that it is getting caught on I believe:
<?php if( $this->getRatings() && $this->getRatings()->getSize()): ?>
I'm not sure how to satisfy these conditions.
4. Rearranging Blocks - Using local.xml to rearrange where blocks are going
Before I start developing bad habits, I want to make sure I'm using best practices from the get go. I've typically just gone into the template files and manually move where stuff was appearing in the phtml, but I've heard it's best to make those changes in the XML. One particular issue I can't seem to figure out is a seemingly simple one: How do I make the "Proceed to Checkout" button move to the bottom of the cart?
I'm trying to unset it then re-set it after the other blocks. I haven't even been able to get the unsetChild part to work. Here is my code from local.xml:
<reference name="content">
<action method="unsetChild">
<name>checkout.cart.top_methods</name>
</action>
</reference>
I think the reason this isn't working is because in checkout.xml it's the child of a child. Here's the general flow of the checkout.xml:
<checkout_cart_index>
<reference name="content">
<block name="checkout.cart">
**<block name="checkout.cart.top_methods">**
Any ideas? Thanks so much, and sorry about the length of this post!
1°) Edit all your layout xml to change the layout of the root reference to 2columns-leftf.phtml template
You can also go through an observer. Observe the controller_action_layout_generate_blocks_after event and in your method do :
public function myEventHandling($event) {
$event->getAction()->getLayout()->getBlock('root')->setTemplate('page/2columns-left.phtml');
}
2°) module Contacts controller index action postAction() so it should be /contacts/index/post/ so it should work. Except if you made your CMS page replacing /contacts/ normal behaviour (module contacts controller index action indexAction() ) it will search under your cms page instead of in the contacts module. If your CMS page have contacts as url, try changing it.
3°) Could you be more precise ? I don't really understand what you need. The form or the existing ratings are not showing up ?
4°) UnsetChild or remove instruction are global, you have to set it with a different name after a replace. But you can edit your layout file in your template directory (not the ones on the base/default/layout directory) to move the block in the proper location, and in the phtml file, try to move the
echo $this->getChildHtml('myblock')
in the proper location.
I'm putting together my first Magento theme. Wee.
This site will have a large number of static pages, and I'm trying to determine the best method of getting that content into the system in an easily maintainable way. Ideally, this process can be managed by a team member with limited experience in magento (this is a key point).
Aside from these two main methods of including static "page" content:
1 - save page-content as a CMS static block, to be added to a
category page
2 - save page-content as a CMS page
it seems I should be able to just render a phtml template file (with page-content as real markup) from a combination of layout update xml directives (in a cms page / category page), or as a widget type of include.
Assuming my file structure looks like this:
/my_theme
/default
/varient
/template
/cms
/template
/category1
/category2
- page_content.phtml
I've tried planting this file into a cms page via a number of variations on:
<reference name="content">
<block type="core/template" name="content.current" as="content.current" output="toHtml" template="cms/template/category1/category2/page_content.phtml"
</reference>
in the layout update xml.
Alternatively, I've tried to render this file via content directives like:
{{block type="core/template" name="content.current" template="cms/template/category1/category2/page_content.phtml"}}
With (obviously) no luck so far.
Granted - there maybe reasons not to deal with static content in this way, but it may still be a viable alternative to the two steps already mentioned (image and link pathing, for example).
At any rate - I believe some combination of update xml or content directives should be workable, but I'm still getting my head around Magento layout and haven't figured out the correct method.
Any advice or explanations would be grand.
Cheers -
b[]x
For any future overflowers looking to figure this out:
{{block type='core/template' template='cms/template/category1/category2/page_content.phtml'}}
works for sure. Just tried it this morning without the name attribute and viola.