Prevent a theme page returning 404

Post Reply
jonathanholvey
Ssr. Bludit
Posts: 23
Joined: Mon May 22, 2017 10:15 pm

Hi,

I have a page in my theme which displays categories. The URL is /category, and my index.php file looks something like this:

Code: Select all

if ($Url->whereAmI() == "home")
	include_once(THEME_DIR_PHP . "home.php");
elseif ($Url->uri() == "/category") {
	$Url->setHttpCode(200);
	include_once(THEME_DIR_PHP . "category-list.php");
}
elseif ($Url->whereAmI() == "page") {
	include_once(THEME_DIR_PHP . "page.php");
}
When I visit my custom page /category, Bludit returns a 404 HTTP code, since it thinks there is no such page.

Is there a way to prevent this, and get $Site->notFound() to return false? The call to $Site->setHttpCode(200) doesn't achieve this. Perhaps there is a better way of having a page built into the theme?

Cheers,
Jon
darkgamer
Jr. Bludit
Posts: 1
Joined: Sat Nov 18, 2017 3:54 pm

Hi Jon,

I did something similar, maybe that could help.

- create a static Page called "category" with the slug "category"
- change the code in the theme index.php to something like that

Code: Select all

if ($Url->whereAmI()=='page' AND $Page->title() == 'category') {
	include("yourfile.php");
}
Done. I hope that helped!

Cheers
Flo
User avatar
diego
Site Admin
Posts: 773
Joined: Sat May 16, 2015 2:53 pm
Been thanked: 1 time
Contact:

Hi,
I changed the class URL to set this parameter you mention, please update this file https://github.com/bludit/bludit/blob/m ... #L158-L164

Now you can set the properties of Not Found.

Code: Select all

$Url->setNotFound(false, 200, 'Ok');
jonathanholvey
Ssr. Bludit
Posts: 23
Joined: Mon May 22, 2017 10:15 pm

Thanks for that! I'll give it a try
jonathanholvey
Ssr. Bludit
Posts: 23
Joined: Mon May 22, 2017 10:15 pm

Unfortunately, this doesn't really work as expected. It allows me to set the parameters in the $Url object, however, since the response code header has already been sent by bl-kernel/boot/site.php, the browser still sees the 404 response code.

I managed to re-send the response code header, however this means two codes are sent. Chrome seems to ignore the first code, but it's a bit messy and I don't know if is allowed in the HTTP standard.

Code: Select all

$Url->setNotFound(false, 200, 'Ok');
include(PATH_RULES.'99.header.php');
https://stackoverflow.com/questions/47540851
jonathanholvey
Ssr. Bludit
Posts: 23
Joined: Mon May 22, 2017 10:15 pm

I can't be sure, but it seems like PHP is only sending the most recent status code. I can't find a client which will show me multiple status codes when using this technique.

So, assuming this is ok, and to to get $Url->setNotFound(false, 200, "Ok") to work as expected, I've created a new function setHttpCode(), which can be used by both $Url->setNotFound() and in 99.header.php.

https://github.com/JonathanHolvey/bludi ... 46f9c0a348
jonathanholvey
Ssr. Bludit
Posts: 23
Joined: Mon May 22, 2017 10:15 pm

After a little more thought...

Allowing Url->setNotFound() to override Bludit's found/not found logic is confusing, especially since Bludit uses it internally. Also, the implementation I wrote to handle the status code reset won't work to force a page into a not found state if Bludit thinks it exists.

I believe that setNotFound() should probably keep its original functionality, and a new Url method is required to override the HTTP code and message, called overrideHttpStatus(). What I've written will automatically set Url->notFound to true or false, based on the provided code, then re-send the HTTP response code, keeping everything in sync.

Code: Select all

class Url {
    ...
    function overrideStatus($httpCode, $httpMessage)
    {
        $this->notFound = (floor($httpCode / 100) == 4);
        $this->httpCode = $httpCode;
        $this->httpMessage = $httpMessage;
        $this->sendHttpStatus();
    }

    public function sendHttpStatus()
    {
        header('HTTP/1.0 '.$this->httpCode.' '.$this->httpMessage);
    }
    ...
}
https://github.com/bludit/bludit/compar ... :not-found
Post Reply