I want user to type any URL, example:
mywebsite.com/helloworld
After, with PHP i'd like to take slug helloworld, and print it on the page.
By default Wordpress shows 404 page. My idea was to disable this page, but not sure if there's a better solution.
How i can achieve that?
add_filter( 'pre_handle_404', function() {
# you can do anything you want here but the easiest and safest is
# wp_redirect( 'your url with query parameters from the failing 404 url' );
# exit();
return FALSE;
} );
404 is one of many HTTP Status Codes and as such if you completely remove the page, you'll need to both disable it in WordPress and on your web server, eg Apache or Nginx. This is not advised as it will make browsers display legitimate 404's with uncontrollable/undesirable responses.
If your question is "the default/my templates 404 page is terrible and I want to change it" refer to the Codex page on custom 404 page or use one of the numerous plugins designed to template error pages.
I would also, personally, advise against directing error pages to a page of your choosing, eg your homepage. This does very little except confuse people wondering why example.com/helloworld goes to example.com. From a programmers perspective, it could add time to your development as you may find it harder to diagnose why you're getting redirected to your homepage rather than it coming up with 404 or 500 which each tell you different information.
To go off of #magenta you can add conditions to this as well. This is what I did:
add_action( 'pre_handle_404', function() {
global $wp_query;
if(!$wp_query->found_posts){
if($wp_query->query['post_type']=="clients"){
wp_redirect( '/login' );
exit;
}
}
return FALSE;
} );
Related
I have a challenge where you guys might help. I do have an REST interface from where get some JSON data to fill the necessary post / page data like headlines, copy and so on. On the other hand there's WordPress handling 404's on URIs that do not exists. So lets face the following scenario.
User requests the URI www.webpage.com/im-not-there/ and because that post / page doesn't exist it send you to the 404.php template. So far. so good, but this is where it becomes tricky.
Before I want WP to send the 404 I want to query the REST interface, asking it if the page exist (sure it's a bit more complicated as this ;) ). So possible answers from the REST interface could be TRUE or FALSE.
On TRUE I want to let WP go where it belongs, but on FALSE I want to "put" my data into the WP file. For that I do have the proper code and use the right hooks.
There might be the case that the post / page doesn't exist so the output (404) is correct.
Easier explanation:
User requests URI -> page / post exists -> requested template and WP stuff
User requests URI -> page / post doesn't exist -> ask REST interface and it returns
-> TRUE -> tell WP "don't use 404.php but use template-xy.php" and do your stuff as you're used to
-> FALSE -> standard WP behaviour.
Found out the following:
WP codex says cleary: "Loading a different template is not a good use of this action hook". The referenced hook is 'template_redirect'
Using template_include - see the codex example - causes further errors like the page is properly loaded but <title> is still from 404.php template
https://codex.wordpress.org/Plugin_API/Filter_Reference/template_include
Sure I can re-add all the neccessary filters like option_template and option_stylesheet and so on but is this really the way?
Codex says to the "wp" hook the following: "This hook is one effective place to perform any high-level filtering or validation, following queries, but before WordPress does any routing, processing, or handling. [...]"
From this point I'm not getting any further.
Further reading:
https://developer.wordpress.org/reference/classes/wp/handle_404/
Setup
Vagrant & PuPHPet
Nginx
MySQL 5.6
PHP 5.6
WordPress 4.6.1
No Plugins activated
Pretty URLs
Restrictions:
no core overrides
can't use server-side handling
using a filter on template_include is too late and causes further "errors" e.g. <title>
Sorry for not posting all codex links but Stackoverflow won't let me. :)
Thank you very much
Found the solution, I missed one but important step!
To set the HTTP header from 404 to 200 and also tell WP hat everything wen'T well.
So to use the codex example this is the solution on a 404
add_filter( 'template_include', 'portfolio_page_template', 99 );
function portfolio_page_template( $template ) {
global $wp_query;
if ( $wp_query->is_404 ) { // TRUE
$new_template = locate_template( array( 'no-404-template.php' ) );
if ( '' != $new_template ) {
if ($wp_query->is_404) {
$wp_query->is_404 = FALSE;
$wp_query->is_archive = TRUE;
}
header("HTTP/1.1 200 OK");
return $new_template ;
}
}
return $template;
}
In wordpress, when you hit url like the following:
http://www.example.com/?author=1
If the author ID is valid then they will be redirected to the author URL, for example:
http://www.example.com/author/username
Then the hacker start attacking the username. How could I disable (?auther=xx) query in url?
for example redirect the request to another page like 404 (not found) page
I believe that dingo-d has it right, above, referring to the 301 redirect. I have installed 301 redirects on several Wordpress sites to accomplish this. I redirect [domain]/?author=* with a wildcard to my 404 page. I have watched my activity logs before and after implementing this. The malicious login attempts immediately switch from valid user names to the generic "admin."
Add the following filter to your functions.php file;
add_action('template_redirect', 'disableAuthorUrl');
function disableAuthorUrl(){
if (is_author())) {
wp_redirect(home_url());
exit();
}
}
This will check all incoming requests to see if the page requested is an author page, and if so, redirect to the homepage, or wherever else you choose.
Typical scenario:
DB items are displaied in page http://...?item_id=467
User one day deletes
the item
Google or a user
attempts to access http://...?item_id=467
PHP diggs into DB and sees items does not exist anymore, so now PHP must tell
Google/user that item is not existing via a 404 header and page.
According to this answer I undertstood there is no way to redirect to 404 Apache page via PHP unless sending in code the 404 header + reading and sending down to client all the contents of your default 404 page.
The probelm: I already have an Apache parsed custom 404.shtml page, so obvioulsy I would like to simply use that page.
But if i read an shtml page via PHP it won't be parsed by Apache anymore.
So what do you suggest me to do?
Is there maybe some trick I could use palying with htaccess too?
Thanks,
Hmm. Two ideas come to mind:
Redirect to the 404 page using header("Location:...") - this is not standards-compliant behaviour though. I would use that only as a last straw
Fetch and output the Apache-parsed SHTML file using file_get_contents("http://mydomain.com/404.shtml"); - also not really optimal because a request is made to the web server but, I think, acceptable in most cases.
I doubt there is anything you can do in .htaccess because the PHP script runs after any rewrite rules have already been parsed.
IF you are using apache mod_php, use virtual('/404.shtml'); to display the parsed shtml page to your user.
I was trying to do this exact same thing yesterday.
Does Pekka's file_get_contents/include result in a 404 status header being sent? Perhaps you need to do this before including the custom error page?
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
You can test using this Firefox extension.
I was looking exactly for something like you needed, so you have a page:
http://example.com/page?item_id=456
and if later you want that if item is missing you are redirected to:
http://example.com/page_not_found?item_id=456
In reality I found it is much more maintainable solution to just use the original page as 404 page.
<?php
$item = findItem( $_GET['item_id']);
if($item === false){
//show 404 page sending correct header and then include 404 message
header( $_ENV['SERVER_PROTOCOL'].' 404 Not Found', true );
// you can still use $_GET['item_id'] to customize error message
// "maybe you were looking for XXX item"
include('somepath/missingpage.php');
return;
}
//continue as usual with normal page
?>
So if item is no longer in the DB, the 404 page is showed but you can provide custom items in replace or error messages.
I have a dynamic review system in place that displays 30 reviews per page, and upon reaching 30 reviews it is paginated. So I have pages such as
/reviews/city/Boston/
/reviews/city/Boston/Page/2/
/reviews/city/Boston/Page/3/
and so on and so forth
Unfortunately, Google seems to be indexing pages through what seems like inference - such as
/reviews/city/Boston/Page/65/
This page absolutely does not exist, and I would like to inform Google of that. Currently it displays a review page but with no reviews. I can't imagine this being very good for SEO. So, what I am trying to do if first check the # of results from my MySQL query, and if there are no results return a 404 and forward them to the home page or another page.
Currently, this is what I have.
if (!$validRevQuery) {
header("HTTP/1.0 404 Not Found");
header("Location: /index.php");
exit;
}
Am I on the right track?
You need to output the 404 status, and show a response body (= an error page) at the same time.
if (!$validRevQuery) {
http_response_code(404);
// output full HTML right here, like include '404.html'; or whatever
exit;
}
Note that you cannot use a redirect here. A redirect is a status code just as the 404 is. You can't have two status codes.
You cannot do both send a 404 status code and do a redirection (usually 3xx status code). You can only do one of them: Either send a 404 status code and an error document or respond with a redirection.
As Pekka suggests, the best option is to do a 404 status, and then put your 404 page code after that.
It is bad practice for SEO if you just 301 (redirect) the page because then the search engines will continue to visit the page in order to see if the redirect is still there.
I'm creating a PHP CMS and have some system pages like a 404 page, a maintenance page, and an unauthorized access page. When Page A isn't found, the CMS will redirect to the 404 page; if the user doesn't have access to Page B, it will redirect to the unauthorized access page, etc.
I'd like to use the proper status code in the header of each page, but I need clarification on how to handle the header/redirect. Do I put the 404 header on Page A and then redirect to the 404 page or do I put the 404 status on the 404 page itself? Also, if the latter is the correct answer, what kind of redirect should I use to get there, a 301 or a 302?
If a user arrives on page A and that page doesn't exist, then do not redirect : just send a 404 error code from page A -- and, to be nice for your user, an HTML content indicating that the page doesn't exist.
This way, the browser (and it's even more true for crawlers ! ) will know that the page that is not found is page A, and not anything else you'd have tried to redirect to.
Same for other kind of errors, btw : if a specific URL corresponds to an error, then, the error code should be sent from that URL.
Basically, something as simple as this should be enough :
if (page not found) {
header("404 Not Found");
echo "some nice message that says the page doesn't exist";
die;
}
(Well, you could output something nicer, of course ; but you get the idea ;-) )
I'm not sure if the redirecting is the best way for doing this. Id rather use some built in functionality that is included into the project.
If the data is not found, do not redirect the user to another page, just send him an error message, like Hey, this site does not exists! Try an other one and so.
And not at the end, you should build into the code, the code-part from the answer of Pascal Martin.
I would do this into a function, and call it from a bootstrap or something with a similar behavior.
function show_error($type="404", $header = true, $die = false)
{
if($header)
header("404 Not Found");
echo file_get_contents($type.'.php');
if($die) die; //
// and so on...
}