Hello guys i have created a controller. I want every action in this controller that is rendering layout to exclude header and footer. Is it possible to this via the xml.
<adminhtml_trips_index>
<remove name="header" />
<remove name="menu" />
<remove name="footer" />
without doing this for each action?
Also is there some event observer like _beforeRenderLayout.
The only solution i have at the moment is to invoke my custom made exclude_redundant_blocks() function, after $this->loadLayout() in every action.
Why not override the loadLayout method in your own controller and exclude the blocks after that instead of doing it in every action?
Something like this:
public function loadLayout($ids=null, $generateBlocks=true, $generateXml=true)
{
parent::loadLayout($ids, $generateBlocks, $generateXml);
//remove blocks here
return $this;
}
Or an other way would be to create a customer layout handle that removes the unwanted blocks
<custom_handle>
<remove name="header" />
<remove name="menu" />
<remove name="footer" />
</custom_handle>
Then load that handle in each action.
again rewrite the loadLayout method and make it look like this
public function loadLayout($ids=null, $generateBlocks=true, $generateXml=true)
{
$this->getLayout()->getUpdate()->addHandle('custom_handle')
return parent::loadLayout($ids, $generateBlocks, $generateXml);
}
the code above is untested, but in theory it should work.
Related
We have developed a site with multiple controllers that accept GET and POST and return views and JSON, and everything works fine in our Development environment.
But on the client's acceptance server we have an issue: all the GETs return well their results, but the POSTs return an error described here by John West. The Stacktrace is identical.
System.InvalidOperationException: Could not invoke action method: askquestion. Controller name: Assistance. Controller type: [Namespace].Assistance.Controllers.AssistanceController
We use the approach of defining the route for each controller:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor type="[Namespace].Assistance.Pipelines.RegisterWebApiRoutes, [Namespace].Assistance"
patch:before="processor[#type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']" />
</initialize>
</pipelines>
</sitecore>
</configuration>
The processor is like this:
public class RegisterWebApiRoutes
{
public void Process(PipelineArgs args)
{
RouteTable.Routes.MapRoute(
name: "Assistance.Api",
url: "api/assistance/{action}",
defaults:new {controller = "Assistance" });
}
}
The action method is like this
[HttpPost]
public ActionResult AskQuestion(AskQuestionViewModel model)
{
if (ModelState.IsValid)
{
....
return View("Confirmation");
}
else
{
return View(model);
}
}
What is happening? Somehow Sitecore blocks AJAX POST requests. Definitely, this is the configuration issue. Where should I look?
OK, I have found the source of the issue.
They had URL Rewrite Module with one rule: LowerCaseRule1 (or it may be any other). But when it made it's work, the request turned to GET. Then the controller could not find the corresponding GET action and voila: could not invoke the action method.
I simply added the exception in rewrite rules and it worked.
<rewrite>
<rules>
<rule name="LowerCaseRule1" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" redirectType="Permanent" url="{ToLower:{URL}}" />
<conditions>
<add input="{URL}" pattern="^.*\.(axd|ashx|asmx|lic|ico|swf|less|aspx|ascx|css|js|jpg|jpeg|png|gif)$" negate="true" ignoreCase="true" />
<!-- here is my exception -->
<add input="{URL}" pattern="/api/assistance" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
I am working on an application that is using Struts2 framework. In action class I got two validatemethods, one for each action. In struts.xml I have input to validate a method and returns a corresponding a view but for the other action that needs validation too, how this approach would work? The only thing I need to know is whether I can change the default input to something else so that method2 gets validated if not then how can I go to different view after actions are validated.
Action Class:
public void validateSearch() {
// validation
}
public void validateSubmit() {
// validation
}
// Action Methods
public String search() {
// business logic
}
public String submit() {
// business logic
}
struts.xml
<result name="input">search.jsp</result>
<result name="????">submit.jsp</result>
In case of two input I don't get my views the way I want them. For submit I get a view of search. is there any way to configure this.
You are probably using DMI (which is deprecated and highly discouraged), and have something like this:
<action name="foo" class="foo.bar.fooAction">
<result name="success">foo.jsp</result>
<result name="input">search.jsp</result>
</action>
You simply need to turn your two action methods into two real actions, like follows:
<action name="fooSearch" class="foo.bar.fooAction" method="search">
<result name="success">foo.jsp</result>
<result name="input">search.jsp</result>
</action>
<action name="fooSubmit" class="foo.bar.fooAction" method="submit">
<result name="success">foo.jsp</result>
<result name="input">submit.jsp</result>
</action>
then instead of:
<s:submit action="foo" method="search" />
<s:submit action="foo" method="submit" />
something like:
<s:submit action="fooSearch" />
<s:submit action="fooSubmit" />
ok, since you are still looking fro answers I will tell you that input name for result is conventional. You can change it any time if your action class implements ValidationWorkflowAware.
ValidationWorkflowAware classes can programmatically change result name when errors occurred This interface can be only applied to action which already implements ValidationAware interface!
public void validateSubmit() {
// validation
if (hasErrors())
setInputResultName("inputSubmit");
}
The result config
<result name="inputSubmit">submit.jsp</result>
Im looking for solution to define layout handle for whole controller insteat of controller_action. For example i want to define:
<mymodule_index></mymodule_index>
instead of
<mymodule_index_index></mymodule_index_index>
<mymodule_index_someaction></mumodule_index_someaction>
Thanks.
You can add a layout handle by running this :
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index')
You can then add this piece of code to a protected "_initHandles" function within your controller that you would run for every action.
In my controller I've (re)implemented this method
public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
{
return parent::loadLayout(array('default','mymodule_index'),$generateBlocks,$generateXml);
}
which will add an update handle called mymodule_index (not loosing the default one) for every controller's action.
You'll need to call loadLayout() in every controller's action, but that's how magento works...
please try below code....
public function indexAction(){
{
...
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index');
$this->loadLayoutUpdates();
$this->generateLayoutXml()->generateLayoutBlocks();
$this->renderLayout();
}
public function samelocationAction(){
{
...
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index');
$this->loadLayoutUpdates();
$this->generateLayoutXml()->generateLayoutBlocks();
$this->renderLayout();
}
I've found solution. In each next update you must provide <update handle="" /> like this:
<companies_catalog>
<label>Companies (All Pages)</label>
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="left">
<block type="businesscategory/companies_navigation" name="companies.navigation" before="-" template="businesscategory/companies/navigation.phtml" />
</reference>
</companies_catalog>
<companies_catalog_index>
<label>Companies (All Pages)</label>
<update handle="companies_catalog" />
<reference name="content">
<block type="businesscategory/companies_list" name="companies.list" template="businesscategory/companies/list.phtml" />
</reference>
</companies_catalog_index>
<companies_catalog_view>
<label>Company page</label>
<update handle="companies_catalog" />
<reference name="content">
<block type="businesscategory/companies_view" name="company.info" template="businesscategory/companies/view.phtml" />
</reference>
</companies_catalog_view>
I'm trying to change template for 'form' block in such layout:
<adminhtml_sales_order_create_index>
...
<reference name="root">
<block type="adminhtml/sales_order_create" name="content">
<block type="adminhtml/sales_order_create_form" template="sales/order/create/form.phtml" name="form">
...
<block type="adminhtml/sales_order_create_shipping_method" template="sales/order/create/abstract.phtml" name="shipping_method">
<block type="adminhtml/sales_order_create_shipping_method_form" template="sales/order/create/shipping/method/form.phtml" name="form" />
</block>
<block type="adminhtml/sales_order_create_billing_method" template="sales/order/create/abstract.phtml" name="billing_method">
<block type="adminhtml/sales_order_create_billing_method_form" template="sales/order/create/billing/method/form.phtml" name="form" />
</block>
<block type="adminhtml/sales_order_create_newsletter" template="sales/order/create/abstract.phtml" name="newsletter">
<block type="adminhtml/sales_order_create_newsletter_form" template="sales/order/create/newsletter/form.phtml" name="form" />
</block>
...
I do
<adminhtml_sales_order_create_index>
<reference name="form">
<action method="setTemplate">
<template>my_module/sales/order/create/form.phtml</template>
</action>
</reference>
</adminhtml_sales_order_create_index>
But this does not work. I think because block with name form exist in several places more after. I just want to change it in block type="adminhtml/sales_order_create_form". How can I do this?
#input
Rewrite of block is not the best appoach. It is better to observe 'core_block_abstract_to_html_before' event and change template there I think. Like:
if ($observer->getBlock() instanceof Mage_Adminhtml_Block_Sales_Order_Create_Form) {
$observer->getBlock()->setTemplate('my_module/newtemplate.phtml');
}
This works and is better because you will not get modules conflict if somebody else will rewrite this block. But I thought that may be possible on layout level..
Whilst not the prettiest solution I too do not know of a way of setting a template on a non unique form reference.
Warning this is pretty gross, and I am really not sure of the side affects and for some reason calling setTemplate in the constructor is not enough I guess this is being called at a earlier or later stage than the parents
class My_Module_Block_Adminhtml_Sales_Order_Create_Form extends Mage_Adminhtml_Block_Sales_Order_Create_Form
{
public function _toHtml()
{
$this->setTemplate('my_module/sales/order/create/form.phtml');
return parent::_toHtml();
}
}
Add the write to your Module
<blocks>
<adminhtml>
<rewrite>
<sales_order_create_form>My_Module_Block_Adminhtml_Sales_Order_Create_Form</sales_order_create_form>
</rewrite>
</adminhtml>
</blocks>
I really hope there is a better solution than this.
your right, thats the reason why its not working.
i can't think of a clean way because of this bad naming.
However there are several options that are not clean but will work:
1 option: copy the whole sales.xml into your own admin layout folder and change the template there directly.
2 option: "rewriting" "Mage_Adminhtml_Block_Sales_Order_Create_Form" and set the template from the code
3 option: subscribe to "adminhtml_block_html_before" and listen for the right block and change the template then.
However if you write a community module non of these options are really good.
if it is your own project i would go for option 1
hope that helps
For overwriting the form name form.phtml file from the billing_method you should do the following:
In the config.xml:
<core_block_abstract_to_html_before>
<observers>
<mymodule_core_block_abstract_to_html_before>
<class>MyModule_Model_MyPath</class>
<method>setTemplateFile</method>
</mymodule_core_block_abstract_to_html_before>
</observers>
</core_block_abstract_to_html_before>
and in your observer:
public function setTemplateFile(Varien_Event_Observer $observer)
{
if ($observer->getBlock() instanceof Mage_Adminhtml_Block_Sales_Order_Create_Billing_Method_Form) {
$observer->getBlock()->setTemplate('mymodule/sales/order/create/billing/method/form.phtml');
}
}
I am creating a module that will have its own page at mysite.com/memymodule/index/index
I want to add functionality from a template file from at templates/me/template.phtml
I have an index controller like this:
<?php
class me_mymodule_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
$this->loadLayout();
$this->renderLayout();
}
}
?>
I have a layout update mymodule.xml that looks like this:
<?xml version="1.0"?>
<layout version="0.1.0">
<mymodule_index_index>
<reference name="content">
<block type="core/template" name="me.mymodule" template="me/template.phtml" />
</reference>
</mymodule_index_index>
</layout>
The frontName of the module is mymodule
When the page renders the content block is completely empty and the content of template.phtml is completely ignored.
Help much appreciated :-)
Try this Code within your Controller's Action -
var_dump(Mage::getSingleton('core/layout')->getUpdate()->getHandles());
exit("Your Layout Path is ".__LINE__." in ".__FILE__);
This code tells you about the Tag which you need to create within Layout.xml.
Also check Config.xml that the Layout Update Section is correctly defined or not.
Hope it'll be beneficial for you.
THANKS