philipk
philipk

I'm building a basic plugin that serves dynamic pages from the database. I've made a component from which I want to return the theme's included 404 page (/404.htm) in case the dynamic page doesn't exist. It's possible to return a \Illuminate\Http\Response from the onRun() method, but I have no idea how to return a different CMS page.

Example code from the component:

public function onRun()
{
    return \Response::make('Page not found', 404);
    return \Redirect::to('404'); // this works but a 404 should never be a redirect!
}

But this isn't what I need ofcourse. Is there an easy way to do this? (I realize October CMS is still in its infancy, so I'd totally accept any "hacky" workarounds)

Last updated

Autumn
Autumn

return \Illuminate\Support\Facades\Response::make(View::make('cms::404'), 404);

Last updated

philipk
philipk

Yes, that would be the built-in 404 page :-)

What if I wanted to show this page: /themes/demo/pages/404.htm? (the one that's editable from the CMS)

Autumn
Autumn

i'm not found, how and pull issue to github one method exists but he doesn't approach to plugin development

Daniel81
Daniel81

@phillipk

Isn't this done automatically anyway? If you create a 404 page in your theme 404.htm with a url of /404, doesn't this override the default 404 page? Not sure why you'd need/want to redirect to the 404 page, as when you navigate to a non-existent URL you get served the themes 404 page anyway - at least that's what happens for me :)

Last updated

philipk
philipk

You're right, it is. I'm in a different situation though:

public function onRun()
{
    $slug = $this->param('slug');
    $city = Models\City::where('slug', '=', $slug)->first();

    if ( ! $city)
    {
        return \Response::make('Page not found', 404); // this is where the *proper* 404 page should be returned
    }

    $this->page['city'] = $city;
}

The URL of the page this component is on is /cities/:slug. When hitting a non-existent URL, you need to handle 404's yourself. That's what I'm trying to do. The CMS won't do this for you because it's not a regular page, it has a :slug parameter which makes it dynamic.

The blog plugin has a smiliar issue. You won't get a 404 if the post doesn't exist. Instead it just shows you the page like nothing's wrong, except there's no post so it looks a bit weird...

Hope I'm making sense here :-)

Last updated

Daniel81
Daniel81

@philipk

How about returning Response::view('view', array(), 404); ?

You could add your themes/demo/pages directory to the view list in config views.paths?

Last updated

philipk
philipk

@daniel81: By using Laravel's Response::view directly you're bypassing October's templating system, which might introduce errors.

I figured out you can do this:

return $this->controller->run('404');

The only issue with this is that you're returning a HTTP 200. It should be returning a 404. It's bad for SEO. You're telling Google a page which really shouldn't exist is a HTTP 200, and therefore Google will index it. Causing duplicate content issues and all sorts of unpredictable behaviour.

The run() method in Cms\Classes\Controller is the culprit. I'll see what might be done about this.

Last updated

philipk
philipk

Case closed!

return \Response::make($this->controller->run('404'), 404);

https://github.com/octobercms/october/issues/202

dzg
dzg

Oh thanks!! I was looking for this :)

mbryson.co.uk
mbryson.co.uk

I was stumped on this one as well. Thank you from 6 years later!

The answer provided:

return \Response::make($this->controller->run('404'), 404);

works, but for me it started dumping header information at the bottom of the page. Changing it to:

$this->setStatusCode(404);
return $this->controller->run('404');

Still outputs the 404 page correctly with a 404 status, but doesn't dump the headers.

Hopefully this can help the next person who comes across this thread!

1-11 of 11