LiveSource
LiveSource

Reputation: 6409

SilverStripe framework only - how to handle 404

I'm using just the framework without the CMS module for the first time. When I visit the app via a URL that is not handled by a controller/action, I just get a page with the text "No URL rule was matched". This results from Director::handleRequest() not matching any controllers to the url segments... Or "Action 'ABC' isn't available on class XYZController."

I'd like to direct any unmached requests to a controller equivalent of a nice 404 page. What is the correct or best way to do this?

Upvotes: 3

Views: 2212

Answers (2)

Nathan Glasl
Nathan Glasl

Reputation: 1

Without updating the routes as previously mentioned, there's a module that I've been recently working on which will allow regular expression redirection mappings, hooking into a page not found (404). This has been designed to function with or without CMS present :)

https://github.com/nglasl/silverstripe-misdirection

It basically makes use of a request filter to process the current request/response, appropriately directing you towards any mappings that may have been defined.

Upvotes: 0

micmania1
micmania1

Reputation: 623

The error templates are only included in the CMS. The framework just returns the HTTP response code with a message in plain text.

I've just started on my own framework-only project too and this is my solution:

[routes.yml]

---
Name: rootroutes
---
Director:
  rules:
    '': 'MyController'
    '$URLSegment': 'MyController'

[MyController]

class MyController extends Controller {

    private static $url_handlers = array(
        '$URLSegment' => 'handleAction',
    );


    public function index() {
        return $this->httpError(404, "Not Found");
    }


    /**
     * Creates custom error pages. This will look for a template with the 
     * name ErrorPage_$code (ie ErrorPage_404) or fall back to "ErrorPage".
     *
     * @param $code int
     * @param $message string
     *
     * @return SS_HTTPResponse
    **/
    public function httpError($code, $message = null) {
        // Check for theme with related error code template.
        if(SSViewer::hasTemplate("ErrorPage_" . $code)) {
            $this->template = "ErrorPage_" . $code;
        } else if(SSViewer::hasTemplate("ErrorPage")) {
            $this->template = "ErrorPage";
        }

        if($this->template) {
            $this->response->setBody($this->render(array(
                "Code" => $code,
                "Message" => $message,
            )));
            $message =& $this->response;
        }

        return parent::httpError($code, $message);
    }

}

[ErrorPage.ss]

<h1>$Code</h1>
<p>$Message</p>

You can also create more specific error templates using ErrorPage_404.ss, ErrorPage_500.ss etc.

Upvotes: 3

Related Questions