My requirement is to disable cache only for cms pages. So is there any way to achieve this functionality?
You need to rewrite / modify Mage_Cms_PageController models preDispatch method.
public function preDispatch() {
$cache = Mage::app()->getCacheInstance();
// Tell Magento to 'ban' the use of FPC, can also ban other types such as 'block_html'
$cache->banUse('full_page');
parent::preDispatch();
}
The better, cleaner and safer option than rewriting this controller is to use observers, these look at these events:
controller_action_predispatch
controller_action_predispatch_' . $this->getRequest()
controller_action_predispatch_' . $this->getFullActionName()
See Disable/Bypass Magento Full Page Cache on single page for more information.
Related
In Magento EE I need to redirect customers depending Origin country, browser lang and previous preference set in a cookie.
I have huge problems making it work with FPC.
I tryed to observe the controller_action_predispatch event, but FPC somehow caches my redirect instruction and customer is not redirected.
I then tried another solution: extending the run() method in Mage_Core_Model_App in order to perform operations before FPC starts to work.
Unfortunately, I don't know why, inside this method you can't access Mage::getModel(), Mage::helper(), Mage::getConfig() ecc
Can you help me please?
Thank you
I've recently been through exactly the same pain. You are on the right track;
controller_action_predispatch
Is the correct event to observe, and you can use this quite happily if you are redirecting to a category or product page with FPC enabled. The problem is the home page - which is a cms page. The cms page cache does not fire controller_action_predispatch. I got around this by adding this to my observer;
public function switchUser($event)
{
// CMS page bug, disable FPC to still use observer
$action = $event->getEvent()->getControllerAction();
if($action instanceof Mage_Cms_IndexController) {
$cache = Mage::app()->getCacheInstance();
$cache->banUse('full_page');
}
// do the rest of your code here
}
The blocks within the cms page will still cache so the page is still nippy, though obviously not as fast as it would be with full FPC enabled. Its a sound trade off in my opinion.
I am trying to set a CMS homepage via a theme's local.xml layout update file in the <cms_index_index> node. I swear I've seen functions to change the store configuration temporarily within a layout node (but maybe I dreamt it), but I'm having trouble finding the layout function in classes like Mage_Core_Block_Abstract and its children classes.
For reference, I've checked in Mage_Cms_IndexController and found the function which renders the homepage:
public function indexAction($coreRoute = null)
{
$pageId = Mage::getStoreConfig(Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE);
if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
$this->_forward('defaultIndex');
}
}
Or, am I doing this completely the wrong way? What would be best practice for a problem like this? I do not want to add a store view for the new theme, as the new theme is for mobile platforms and requires the same settings from the store view. Thanks guys!
This is not possible. The layout configuration is not invoked until after checks occur to see if there is a valid page which has been specified; because these checks fail, the Default router will match and (by default) the application will display the 404 page.
For a Magento shop I'm working on I have to check certain session variables on each load of a page. When the variables don't have the expected values I need to redirect to certain page.
No I wonder how I could implement such a behavior. Normally I would do the check in action methods of each controller, but I don't want to rewrite each controller or all their base classes.
Is there a easier way?
Magento's event architecture to the rescue! Observe the controller_action_predispatch method.
Edit: Note that this event is dispatched in both adminhtml and frontend, so Sergy's answer is important - configure the event observer under the appropriate area.
Yes,
you can always use magento events in this case:
1. controller_action_postdispatch.
2. controller_action_predispatch .
Be careful: same events are used in admin area also.
Is it possible in Joomla to place a certain article in a template, additionally to the normal content? I want the article to show up on every page.
You can simply take it from the databse and print its content. In the template, where you want to show the article, write this:
$id=/*Id of the article to show*/;
$db=&JFactory::getDBO();
$db->setQuery("SELECT * FROM #__content WHERE id=$id");
$item=$db->loadObject();
echo $item->introtext;
UPDATE: ENABLE PLUGINS
I can't find where i've used that code and i can't copy-paste it, so i try to write it again by looking at the view.html.php of the com_content:
JPluginHelper::importPlugin('content');
$dispatcher =& JDispatcher::getInstance();
$params = &$mainframe->getParams();
$dispatcher->trigger('onPrepareContent', array (&$item, &$params, 0));
//The last line triggers the onPrepareContent event, so if it does not work maybe you need other events, so try with onAfterDisplayTitle, onBeforeDisplayContent or onAfterDisplayContent
Have you seen this? http://extensions.joomla.org/extensions/news-display/content-embed/7528
It allows you to place any article as a module on your Joomla site. And with modules you can have them displayed site wide.
Background
I use the word widget as a partial view that have its own controller (so its own actions) and it is placed in almost all pages. I implement the rendering of this via HMVC, that is just great.
Problem
Now, the problem is that the widget itself execute actions. Think about a shopping cart widget. That widget is placed in all pages so the user can see his/her stuff all along. And the widget have actions that are related to it, for instance: RemoveItem, RefreshCart, ApplyDiscountCoupon, etc. Such actions should trigger by a button or link and the link should be something like (in HMVC):
<a href='<?site_url()?>/cart/cart/removeitem/the_item_id'>Remove this item</a>
Ok. Now the user clicks that link, the cart module and cart controller are loaded and the action is executed, the action should look something like:
function removeitem($itemid)
{
// remove the item from db
...
// "load the view" ???
}
As you can see, my question is how to load the view in a HMVC module. The thing is that if I only load the cart view, it will only show my cart, and I can’t just redirect or load the main page because it can be any main page, that is: the cart could be in any main page (select product, keep buying, see product details, billing info, checkout, etc). :/
Another thing: a requirement is that I can’t use AJAX in this project.
Do you know how HMVC handle this?
Thanks in advance.
Ok. No luck with the community. Nevertheless I found a workaround. Hope would be helpful to someone.
HMVC doesn't have a natural solution to this. So I decided to use this workaround:
Into each main controller (that is, no widget, no partial view) I grab the current url in session this way (/controllers/keep_buying.php):
class Keep_buying extends Controller
{
function Keep_buying()
{
parent::Controller();
$this->session->set_userdata('main_uri', uri_string());
}
...
}
Then in my partial view widget (HMVC module view) I have a normal link to my widget controller (/modules/cart/views/cart_show.php):
<a class="button" href="cart/cart/additem">Add Item</a>
At the controller action (HMVC module controller action) I retrieve the current main page, do stuff and then redirect to that page, that implicitly will get into my widget flow (due to HMVC).
class Cart extends Controller
{
...
function additem()
{
$to_redirect = $this->session->userdata('main_uri');
// add-item work stuff...
redirect($to_redirect);
}
}
That is. Is not the ideal approach IMHO, but works.
I know that this topic is over a year old, however I have been Googling to gain some more insight into the structure an HMVC program should take, and how it can be implemented in CI, and have not found very many answers.
I'm pretty sure that for HMVC to work properly, with several widgets incorporated on all pages of a site, they need to be orchestrated by one main controller. This will be the top level of the heirarchy. Let me try to give an example:
You have a site with a shopping cart widget on every page. When you wish to use the cart functionality, you will need to link to methods in the cart module, e.g.:
add
The problem using this link is that you do not want to reload the rest of the site from that module. Instead, you can route the link through your main controller and have it reload the module, calling the desired method. e.g.
add
Then in the site controller, it will simply pass the method call to the main view
<?php
function cart_add($item){
$data['cart'] = 'cart/add/'.$item;
$this->load->view('main', $data);
}
?>
The view will call the cart widget with the following:
<?php echo modules::run($cart); ?>
Obviously this is a simplified explanation, and the main site controller will be handling several widgets in one main view, so passing the correct data will need to be managed better than just calling the main view from within a method. But hopefully this gives an idea of the structure I am referring to.
If anyone reads this and thinks I'm wrong, I would love to hear other solutions people have found to this issue.