3

I have been tasked with forcing all of our 404 pages to return an http status of 301. I have been searching/reading around the web, but I can't find any info on how to accomplish this.

Is there a way to change the http status in the layout.xml or template files? if not, what controller should I be looking at?

MrGlass
  • 9,094
  • 17
  • 64
  • 89

4 Answers4

5

I haven't looked too much into it, but the 404 message seems to be sent in this file - in 3 functions:

Server path: /app/code/core/Mage/Cms/controllers

I changed the header from a 404 to a 301 redirect. Might not be the niftiest solution but it seems to work.

**/**
 * Default index action (with 404 Not Found headers)
 * Used if default page don't configure or available
 *
 */
public function defaultIndexAction()
{
    $this->getResponse()->setHeader('HTTP/1.1, 301 Moved Permanently');
    $this->getResponse()->setHeader('Location','http://www.streetcred.dk');
}
/**
 * Render CMS 404 Not found page
 *
 * @param string $coreRoute
 */
public function noRouteAction($coreRoute = null)
{
    $this->getResponse()->setHeader('HTTP/1.1, 301 Moved Permanently');
    $this->getResponse()->setHeader('Location','http://www.streetcred.dk');
}
/**
 * Default no route page action
 * Used if no route page don't configure or available
 *
 */
public function defaultNoRouteAction()
{
    $this->getResponse()->setHeader('HTTP/1.1, 301 Moved Permanently');
    $this->getResponse()->setHeader('Location','http://www.streetcred.dk');
}**
Gita Street
  • 51
  • 1
  • 2
  • For multi-store setups you'll need to first get the current baseurl and use that for the redirect. You can get the base url with `$baseurl=Mage::getUrl('',array('_nosid'=>true));` – Lucas Scholten Feb 14 '13 at 15:19
3

Per the article mentioned above, the CMS no-route page (or the defaultNoRoute action) both set their 404 headers from a controller action with the following code

$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');

If you take a look at the method definition for setHeader

#File: lib/Zend/Controller/Response/Abstract.php
public function setHeader($name, $value, $replace = false)
{
    $this->canSendHeaders(true);
    $name  = $this->_normalizeHeader($name);
    $value = (string) $value;

    if ($replace) {
        foreach ($this->_headers as $key => $header) {
            if ($name == $header['name']) {
                unset($this->_headers[$key]);
            }
        }
    }

    $this->_headers[] = array(
        'name'    => $name,
        'value'   => $value,
        'replace' => $replace
    );

    return $this;
}

You can see there's a third paramater named $replace, which you can use to set a header value again, so something like this

Mage::app()->getResponse()->setHeader('HTTP/1.1','...header text...',true);

should be sufficient to change the value of a header. Just call this before the front controller tells the response object to send its output. You could probably do this from a phtml template (as output is rendered before being sent), but the better way would be with an event listener for the two CMS no route actions (if you've set a custom action for the no-route, adjust accordingly)

controller_action_postdispatch_cms_index_noRoute
controller_action_postdispatch_cms_index_defaultNoRoute
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • Wow, I've been reading your articles all day trying to figure this out, and you post an answer just 5 minutes after I get it working. Of course, I did it completely differently (and probably wrong). Thanks for the info! – MrGlass May 30 '12 at 18:00
  • @MrGlass Nothing wrong with the way you did it. There's rarely one right answer with Magento. – Alana Storm May 30 '12 at 18:14
2

There are a number of 404 pages in Magento, this article by Alan Storm should help you find what you need:

http://alanstorm.com/magentos_many_404_pages

Josh
  • 2,820
  • 23
  • 15
  • I have read that article. I am trying to change the no route 404 page, which is int he last section, but unfortunately Alan does not go very deep into how to modify it. – MrGlass May 30 '12 at 14:09
1

I ended up doing this with 3 steps:

First I created a new cms page (404/landing) and copied over all the cms settings from my 404 page. This is the page I am redirecting users to.

I then created a new module (you can use this great guide by Alan Storm http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-3-magento-controller-dispatch) and used the following action:

public function indexAction() {
    $url = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB)."404/landing"; //build url
    $this->getResponse()->setRedirect($url, $code = 301); //set a redirect using Zend response object
}

Once I had my module and landing page working, I simple changed the Default No-route URL (System -> Configuration -> Web -> Default Pages) to that of my new module.

MrGlass
  • 9,094
  • 17
  • 64
  • 89