Wordpress Problematic URL - wordpress

I have a custom page in wordpress that uses a custom plugin which is connecting to an API to retrieve information.
The client has asked that we don't pass id's via the url as below:
http://beta.hirehere.co.uk/hire-vehicle-detail/?id=4
but instead use a category name such as:
http://beta.hirehere.co.uk/hire-vehicle-detail/?vehicle_category_name=economy
initially I was using a URL rewrite to pretty things up so:
http://beta.hirehere.co.uk/hire-vehicle-detail/4
and thought I would just change it to:
http://beta.hirehere.co.uk/hire-vehicle-detail/economy
I would then adjust the code accordingly. I've done this yet the URL rewrite does not seem to be happy and returns a 404 error but it works if I access the direct url of:
http://beta.hirehere.co.uk/hire-vehicle-detail/?vehicle_category_name=economy
Here is my htaccess file, any help is greatly appreciated:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^hire-vehicle-detail/(.+)$ index.php/hire-vehicle-detail?vehicle_category_name=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
PS. The above htaccess code worked in the scenario of using ID's instead
Edit: it appears wordpress is trying to access a sub-page (economy) of the parent page (hire-vehicle-detail). I know this because if I create the page economy as a child of hire-vehicle-detail the url takes me there. Is there anyway to stop this

Related

Wordpress and CI rewrite rule in htaccess

I have installed WordPress in example.com. I have also installed CodeIgniter in ci folder here example.com/ci/, ci is the folder name , register is the controller name and working URL of CI is example.com/ci/register . My base URL starts with https:// .
Now I have one WordPress URL example.com/hotel, hotel is the page that I have created in WordPress admin, it works fine.
I want to run my CI path like example.com/hotel/ci/register, I think we can do it with some rewrite rule so that my URL would look like example.com/hotel/ci/register. I have added given htaccess for wordpress that redirecting me here example.com/hotel/ci/register. It is showing me 404 error of CI. It means now I am in CI. Now I did following things in routes.php file.
$route['default_controller'] = 'register';
$route['404_override'] = 'register';
Now this URL example.com/hotel/ci/register is working, but this is not right way, next time there will be more controllers then it will not work.
Note: I can not create hotel folder because hotel is a page in the WordPress. If I create hotel folder then WordPress URL example.com/hotel/ will not work. It will redirect WordPress page to the hotel folder. So I have to do it without creating hotel folder. Note example.com=myurl.com .
I need to find another good solution.Any advise or guidance would be greatly appreciated?
Following is my reWrite rule in wordpress htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/?hotel/ci/register(/.*)?$ /ci/$1 [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
And following is my CI htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>
Interesting problem! I set up a Docker container with a fresh install of Wordpress and Codeigniter, I created a hotel page in WP, and a Register controller and view in CI, and got testing. I spent way too long on this, but I did find an answer.
First, your Wordpress .htaccess. As #tobiv pointed out in a comment, you should not add anything between the BEGIN/END WordPress comments as it might get whacked by a WP update. Your redirect has to come before the standard WP rules though, so add it at the top of the file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel/ci/register /ci/register [L]
</IfModule>
# BEGIN WordPress
# ... These are the default, unchnaged WP rules
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
<IfModule mod_rewrite.c> and RewriteEngine On are duplicated which seems messy but you do need them, as your new rule has to go first so it processes the request before the WP rules do.
You don't need to modify the Codeigniter .htaccess file, the default one is all you need. It should be in the root of your Codeigniter installation, ci/.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
At this point https://example.com/hotel/ci/register will show the Codeigniter 404 page. If you have logging enabled (see config/config.php), and you watch the logfile, you'll see why:
ERROR - 2017-11-14 17:57:20 --> 404 Page Not Found: Hotel/ci
And here's the root of the whole problem. Since the initial redirect is an internal redirect (means the URL shown in the browser does not change), the URI Codeigniter receives to process is the one still shown in the browser address bar - hotel/ci/register. Codeigniter will try to handle a request like that in 2 ways:
Look for a matching route in application/config/routes.php
Or look for a controller named application/controllers/Hotel.php, with a method called ci;
In our case there is no Hotel controller, and no route to describe how to handle such a request, so boom, 404.
One simple solution is to create a route to handle this request:
$route['hotel/ci/register'] = 'register/index';
And now https://example.com/hotel/ci/register works!
Notes:
Setting your default route to register ($route['default_controller'] = 'register';) means that https://example.com/ci/ will also show register. I'm not sure if you want that? You might run into duplicate-content SEO problems if that URL shows the same as https://example.com/hotel/ci/register, so maybe you want something else, or a 404, there.
Make sure you remove your $route['404_override'] = 'register'; route;
CI base_url is not relevant for this problem, though obviously should be set. Depending on how you want your links to be I think either http://example.com/ci/ or http://example.com/hotel/ci/ would be right.
I am not quite sure what the purpose of this condition in your CI .htaccess is for:
RewriteCond $1 !^(index\.php|resources|robots\.txt)
The existing default conditions already skip files and directories which exist on disk. That's what the !-f and !-d conditions mean - "if the requested pattern does not match a file or directory on disk, then do the redirect".
If you have a robots.txt file on disk (in your ci/ dir), and someone requests https://example.com/ci/robots.txt, the !-f condition will fail, and the rewrite is skipped - meaning the request is handled without rewrites and robots.txt is returned successfully. Same for index.php. If you have a directory called ci/resources, and someone requests https://example.com/ci/resources, the !-d condition will fail, the redirect is skipped, and the request is successfull.
I'm not sure about your resources part, but maybe you can remove that condition completely.
If you don't need pretty Codeigniter URLs (I mean other than https://example.com/hotel/ci/register, this change won't affect it), and it turns out you don't need that extra condition above, you can get rid of the CI .htaccess completely to simplify things. To do that, just change the Wordpress RewriteRule to the non-pretty version:
RewriteRule ^hotel/ci/register /ci/index.php/register [L]
And delete your CI .htacces.
I think you are on the right path, try this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/hotel/ci(/.*)?$ /ci/$1 [L] # remove the register part
# so that it would be handled by CI
# also remove the "?" in front of hotel
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
keep your CI htaccess as it is:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>
the last part is match your CI config.php to your new url model
$config['base_url'] = "http://example.com/hotel/ci/";
I don't thing this will be the great answer of your question but if i face the same problem i will use routes see the example code.
$route['(:any)/ci/register'] = "register";
what will the above code do (:any) means any word in first uri and after that you can defined any url you want i defined ci/register you can also do that like this.
$route['(:any)/register'] = "here_you_can_add_your_controller/function";
this will work if hit url like this.
http://www.example.com/any_word_you_want/register
it will hit your controller function. you need to echo something and it will show in your browser.
you can also defined the hotel word in your base url as #am05mhz shows in his answer but i don't thing that's a great idea because in future may you have 2 more words in your url.
Note : the above code example only work if your .htaccess give access of routs as you shows in your question the .htaccess is work for you. For full knowledge of routs please check the documentation of codeigniter URI routing
Use htaccess [P] flag instead.
Make sure the substitute (target) string will start with http://. Otherwise, it will treat the substitute string as an internal file path.
Check the code below.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/?hotel/ci/(.*)?$ http://example.com/ci/$1 [P]
# If you want rewrite any URI as long it has */ci/* in it.
# Use the following rule instead.
# RewriteRule ^(.*)/ci/(.*)?$ http://example.com/ci/$1 [P]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Also, you don't need to update CI's base url. Empty string will do.
$config['base_url'] = '';
Hope that helps.
Links:
https://httpd.apache.org/docs/current/rewrite/flags.html#flag_p

htaccess query string /?

I've been searching similar examples but I was not able to find the answer in WordPress.
In google analytics I can see various string types for the same url's coming in. I looked at the htaccess file and deactivated the cache system but it's still occurring. Not sure why yet.
Now in htaccess I would like to redirect all those url's to the correct one:
Example:
// CORRECT: ...domain.com/everest-nepal/
// INCORRECT 1: ...domain.com/everest-nepal/?/
// INCORRECT 2: ...domain.com/everest-nepal/?/=
// CORRECT 3: ...domain.com/everest-nepal/?amp (this is amp related and not interested in redirecting it to the canonical url)
Is there a possible rewrite condition that could be applied in htaccess to redirect all these url's coming with this strange /?* at the end avoiding the amp?
Thanks and regards
Enric
Once you update permalinks in wordpress admin you will get .htaccess code below like this, You need to create .htaccess file in your root folder, and paste this below code, this should work,
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

htaccess rewrite with Wordpress for translating url slug but don't show in browser bar

I have urls which include slugs that should be displayed in englich.
but the cms cannot interprete them right but can the german ones.
blah.com/en/team/sprache/french works but is not pretty
blah.com/en/team/language/french does not work, but should be in the browser address bar and is quite pretty.
I tried this .htaccess but it does not work - I land on a 404.
can anybody explain what goes wrong here:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# special rules for english urls
RewriteRule ^(.*)/language/(.*)$ $1/sprachen/$2
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
you need to know that the slugs can occure more then once in the url and there are some other slugs that must be translated as well.
Internal rewrite rules don't work with wordpress as WP uses index.php as default front controller for all the URLs.
You can use permalinks to customize how your URLs will appear to your clients.
For advanced URL customization use WP rewrite API to write your rewrite rules in PHP inside your theme. Here is a tutorial on WP rewrite rule APIs.

Mod_write, htaccess and Wordpress slugs

This is either blindingly simple or impossible; after lots of Googling and thread reading, I can't tell.
I have a WordPress site that uses a plugin to create a custom post type. The rub of this is that the custom post type has a very ugly "slug". What this means is that the URLs look like this:
http://mysite.org/uglyname/a-post-title/
Where "uglyname" is an ugly name. I can't change the name without editing the core files of the plugin, which is a bad idea in this context.
What I'd like to do is make it so that if a user visits a URL like this:
http://mysite.org/prettyname/a-post-title/
Wordpress interprets prettyname as it would uglyname and is more or less nonethewiser.
I don't want something that just redirects; I'd like it to be a silent mapping. But keep in mind that Wordpress is already using the .htaccess file to map everything it gets onto http://mysite.org/index.php.
Is this possible, or am I just barking up the wrong tree?
EDIT to add: The current .htaccess is the WordPress default:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /mysite.org/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /mysite.org/index.php [L]
</IfModule>
# END WordPress
Just above RewriteCond
%{REQUEST_FILENAME} !-f, try the following line:
RewriteRule ^prettyname/(.+)/? /uglyname/$1
If I'm not mistaken, it should pass it over, and then still process the index.php routing.
Haven't tested it - not at a server right now.

Using mod_rewrite for GET variables in a Wordpress blog page

I am working on a wordpress blog, with the default .htaccess settings:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
In my wordpress blog, I have created a page called "mypage". Using my rewrite settings, it is shown in the address bar as http://www.mysite.com/mypage.
I am using a custom page template and am processing some things, which include the use of GET variables. For instance:
if (isset($_GET='word')) { echo $_GET['word]; }
So, http://www.mysite.com/mypage?word=dog will display "dog".
The problem I am having is rewriting the URL so that it can look like: http://www.mysite.com/mypage/dog, still being able to access "dog" as the GET variable.
I am not too good with mod_rewrite rules to begin with, but working from within a wordpress installation is throwing me an extra curveball.
Does anyone know what I need to add to my .htaccess to achieve this?
Thank you!
Try the following:
RewriteRule ^mypage/([^/])/?$ mypage?word=$1 [L,QSA]
The L flag instructs .htaccess to stop processing rules, and QSA appends the query string since you might have other GET parameters on the end of the URL.
Mod_Rewrite Documentation

Resources