Welcome Guest, Not a member yet? Register   Sign In
Problem with custom 404 page :(
#1

[eluser]victorche[/eluser]
Hi @all!

I really need a custom 404 page, as the one provided with CI does not allow enough customisation. For my needs I am using the solution, described here:

http://codeigniter.com/wiki/Custom_404_error_pages/

It works really nice and gentle. But because I am a newbie, maybe there is something as logic in general, which I can not understand.

The problem is, let's say... I have /products page, where all my products are listed. Every product has a short description and a button "view details". This link is leading to /products/detail/product_id, for example /products/detail/23

So I have a products.php in application/controllers/... It has function index(), which makes the product list with /views/products_tpl.php
But in products.php I am adding function detail() which is taking care for the single product page. It is using /views/product_details_tpl.php
For example, if I have url like this: /products/detail/23
I am getting the product_id and then details from the table like this:
Code:
$id = $this->uri->segment(3);
$this->db->where('id', $id);
Everything works fine, except the 404 page Sad
Here is the problem, explaned:
if I have products/ -> This is products list, works and displays correct;
if I have products/detail/23 -> This is the details page of a single product, and if I have a row with id = 23, it works fine...
if I have /products/detail/werxcgwet -> Here I want 404, but I only have a blank page
if I have /products/detail/23457656723454576 -> Id, which is numeric but does not exist in the database... again blank page

I know that it is normal, I mean the logic is like this, but how can I make something like... If the product ID does not exist... this custom 404 to be used?
#2

[eluser]Clooner[/eluser]
In your products controller you have the function detail. This will have to check if the product exists and act accordingly. It sounds like you always assume it is correct. Check the result of your query if no records exists display a product not found page else display the products page!

Code:
$data['product'] = $this->product_model->get($id);
if (!$data['product'])
  $this->load->view('product_not_found');
else
  $this->load->view('product_view, $data);

It's not a 404 page it's a feature Wink
#3

[eluser]victorche[/eluser]
Some more info... I know that all my links will lead to existing ID's. Anyway I am talking about the cases when an user can enter a wrong url manually.
And yes, I am doing a check like:
Code:
if ($query->num_rows() > 0)
And I know that if it returns FALSE, I can redirect them to somewhere... But I don't want such a solution. I want the url to stay like /products/detail/some_wrong_id
But to have the 404 error template there.
#4

[eluser]victorche[/eluser]
@clooner, thanks for the reply! Anyway, as I said already... This solution is not Ok for me. The whole idea of 404 pages is missing if I do it this way. Can I think about all the possible wrong urls that someone can enter manually?
I have /products/detail/some_id page and I have to prepare a "missing product" template, because someone can type missing product url.
I have /news/view/some_id page and I have to make a "missing news" template, because of the same reason...
I have /users/profile/some_id page ... and again template like "missing user".

So why I need the 404 page then?
#5

[eluser]Clooner[/eluser]
First of all: don't redirect, if you don't want it to be redirected!

I used this method a few times over already and this will give you all the flexibility you need! In case the controller and / or funtion do not exists I suggest you make a catch all controller/function in your route
Code:
// controllers
$route['products/(:any)/(:num)'] = 'products/$1/$2';
$route['news/(:any)/(:num)'] = 'news/$1/$2';
$route['users/(:any)/(:num)'] = 'users/$1/$2';
// catch all
$route['(:any)'] = 'catch_all_ctrl/index';
// default
$route['default'] = 'lander/index';
You should place all other routes 'manually' before that. This seems like more work but it is really only a few extra lines of code.
#6

[eluser]victorche[/eluser]
@clooner, thanks again! I am reading now about routes here:
http://ellislab.com/codeigniter/user-gui...uting.html

Anyway... I think if I do it this way:
Code:
$route['products/(:any)/(:num)'] = 'products/$1/$2';
This might help only because there will be rule for the last segment (num). It means url like:
/products/detail/xyz
Will maybe lead to 404, as "xyz" is not numeric. Is this correct?

And one last question... If it is correct, it means it will not help if there is a numeric value, like:
/products/view/23537542
Because 2353742 is numeric value. Anyway what happens if this ID does not exist in my database table? Blank page again?

I really don't know a lot about those routes and the info provided in the user guide is not so much Sad For example:
Code:
// catch all
$route['(:any)'] = 'catch_all_ctrl/index';
What this will do?
#7

[eluser]Clooner[/eluser]
[quote author="victorche" date="1278939827"]
Code:
// catch all
$route['(:any)'] = 'catch_all_ctrl/index';
What this will do?[/quote]

It will make sure that everything that doesn't have a route defined gets run by this controller/method
#8

[eluser]victorche[/eluser]
[quote author="clooner" date="1278944491"][quote author="victorche" date="1278939827"]
Code:
// catch all
$route['(:any)'] = 'catch_all_ctrl/index';
What this will do?[/quote]

It will make sure that everything that doesn't have a route defined gets run by this controller/method[/quote]
Ah, @clooner... Thanks for your time, but anyway can you tell me with a small example.
In my situation, this "route" thing... Will it help in a case like:
/products/detail/some_missing_id
to be with this nice 404 magic or not?
Because I am digging Google about it, but no success for now Sad

And am I correct that (:num) will cover the cases when the 3rd segment has not numeric values?
For example, I will add this route:
Code:
$route['products/(:any)/(:num)'] = 'products/$1/$2';
Will it help in a case like /products/detail/blabla_not_numeric
#9

[eluser]Clooner[/eluser]
Code:
$route['products/(:any)/(:num)'] = 'products/$1/$2';

in this case /products/detail/blabla_not_numeric will be run by the catch all controller and not the products controller.

I suggest to try it out for yourself
#10

[eluser]victorche[/eluser]
I will for sure. It is just that I am at work, and the testing case is at home Smile
Still reading about those routes and began to understand them. But I don't see the connection with my problem yet Sad




Theme © iAndrew 2016 - Forum software by © MyBB