slash (/) in GET-Request and my mod_rewrite statement in htaccess - .htaccess

I am getting a little bit crazy on the topic and hope to find some help.
I am re-building currently my website into an MVC structure. This includes also SEO-friendly (pretty) URLs.
I achieved already the transformation of my URL-requests
from: http://www.example.com/company?id=about_us
to: http://www.example.com/company/about_us
my .htaccess-file
RewriteEngine On
RewriteBase /
# Transforms an ugly-URL into a pretty-URL ('external redirect' updates also adress in browser)
# ugly URL: www.example.com/company?id=about_us
# pretty URL: www.example.com/company/about_us
RewriteCond %{QUERY_STRING} ^id=([\w-]+)$
RewriteRule ^(.+)$ $1/%1? [R=301,L]
# Transform an pretty-URL into a ugly-URL ('internal redirect')
# pretty URL: www.example.com/company/about_us
# ugly URL: www.example.com/index.php?url=company/about_us
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
Now the GET-Request of a FORM (select box for some articles) comes into the game, which is not working with the above-mentioned htaccess-file. While each article has a SEO_slug saved in the database, which is dynamically put into the form. The SEO-slug has already this format:
"<city>/<type>/<articlename>"
The HTML looks like this:
<form method='get' action='../articles/'>
<select name='id'>
<option value='london/fruit/article_1' >Article 1</option>
<option value='london/nuts/article_2' >Article 2</option>
<option value='newyork/fruit/article_3'>Article 3</option>
<option value='newyork/nuts/article_4' >Article 4</option>
<option value='miami/fruits/article_5' >Article 5</option>
</select>
</form>
The Problem:
Now, the request is sent to the server, but the slashes (/) are transformed to '%2f', which generates with my current htaccess a server internal error.
Questions
1) Can I prevent the transformation from slash (/) to '%2f'?
2) How do I have to update my mod_rewrite to enable this. I have seen so many websites, but I never found a good solution. I was capable to achieve a bit with this:
RewriteCond %{QUERY_STRING} ^id=([\w-]+)(%2F*)(.*)(%2F*)(.*)$
RewriteRule ^(.+)$ $1/%1/%3/%5? [R=301,L]
, but I have problems with the numbers of slashes as sometimes the depth is different.
Can anybody give me a good advice? Many thanks!
Maybe I am trying to solve the story on the wrong end and need to think totally different??
Cheers
Tim

Finallay I found a solution, which I would like to share with you:
RewriteEngine On
RewriteBase /
# Transforms an ugly-URL into a pretty-URL ('external redirect' updates also adress in browser)
# ugly URL: www.example.com/company?id=about_us
# pretty URL: www.example.com/company/about_us
#
# REMARK: The important group is the thrid. The two first groups are
# important if the query string contains slahes (/) that are
# encoded as '%2F'. As there is no 'replace'-function each
# Level of '%2F' needs to be rewritten step by step
RewriteCond %{QUERY_STRING} ^id=([\w-]+)%2F([\w-]+)%2F([\w-]+)$
RewriteRule ^(.+)$ $1/%1/%2/%3? [R=301,L]
RewriteCond %{QUERY_STRING} ^id=([\w-]+)%2F([\w-]+)$
RewriteRule ^(.+)$ $1/%1/%2? [R=301,L]
RewriteCond %{QUERY_STRING} ^id=([\w-]+)$
RewriteRule ^(.+)$ $1/%1? [R=301,L]
# Transform an pretty-URL into a ugly-URL ('internal redirect')
# pretty URL: www.example.com/company/about_us
# ugly URL: www.example.com/index.php?url=company/about_us
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
If you have any comment on this to improve it, I am happy to hear about it.

Related

htaccess rewrite key/value pair params in url

I know this is very common question but I can't seem find any solution regarding in my problem. The folder structure looks like this:
- rootProject
- subfolder
* .htaccess
* index.php
Normal url params: http://website.com/subfolder/?dynamicKey=dynamicValue.
But What I want to achieve is like this: http://website.com/subfolder/dynamicKey/dynamicValue
But I failed to do that, I can only retrieve the dynamicKey.
Here is my current htaccess:
RewriteEngine On
RewriteRule ^([a-z]+)/?$ index.php?$1 [NC,QSA,L]
Thanks to #Ar Rakin. Here is the solution.
RewriteEngine On
RewriteRule ^([a-z]+)/?$ index.php?$1 [NC,QSA,L]
RewriteRule ^([a-z]+)/([a-z]+)/?$ index.php?$1=$2 [NC,QSA,L]
With your shown samples and attempted code, please try following htaccess rules. We need to add conditional checks before rewrite rules else later it will affect your existing pages also.
Make sure to clear your browser cache before testing your URLs.
RewriteEngine On
##Added conditions if non-existing pages requested then only perform rewrite.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)/?$ index.php?$1 [NC,QSA,L]
##Added conditions if non-existing pages requested then only perform rewrite.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)/([a-z]+)/?$ index.php?$1=$2 [NC,QSA,L]
NOTE: your used regex [a-z] will only match small letters in uri, in case it needed to check any alphabets(capital OR small) then change FROM [a-z] TO [a-zA-Z] in above rules also.

How do I redirect an old style post to a new URL format?

I have a website that is going to be converted to a new cms. The reason for doing this is to not lose inbound links and end up with dead pages in search engines.
In the old website the URLs are structured like:
website.com/4212/write-a-google-review
and in the new:
website.com/blog?write-a-google-review
although I have some flexibility in that I can add the ID into the URL string as in any of:
website.com/blog?4212&write-a-google-review
website.com/blog?4212-write-a-google-review
website.com/blog?4212/write-a-google-review
website.com/blog?write-a-google-review&4212
I have tried a number of rewrite variations some just matching the ID, others matching the text string, but haven't gotten the right formula yet.
RewriteRule ^4212/?$ blog?4212/write-a-google-review [NC,L] ##
RewriteRule ^[4212]?$ blog?4212/write-a-google-review [NC,L] ##
Comment added testing the 1st answer (by Croises).
As a singular redirect I found that this works but only if I gave the full url with https://www.mywebsite.com/:
RewriteRule write-a-google-review/?$ https://www.mywebsite.com/blog?write-a-google-review [NC,L]
When I added the following two lines it resulted in a broken page, no styling, no post content output:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+(?:/.+?)?)/?$ blog?$1 [L]
So curious I changed it to include the full url like the following and it worked as a regex solution for all entries:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+(?:/.+?)?)/?$ http://www.mywebsite.com/blog?$1 [L]
You can use:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+(?:/.+?)?)/?$ blog?$1 [R=301,QSA,L]
RewriteCond %{QUERY_STRING} (^|&)blog\?4212($|&)
RewriteCond %{QUERY_STRING} (^|&)write-a-google-review($|&)
RewriteRule ^website\.com/index\.php$ /website.com/blog?4212-write-a-google-review&%{QUERY_STRING}
From
website.com/index.php?blog?4212&write-a-google-review
To
website.com/blog?4212-write-a-google-review
Regex
RewriteRule ^([a-z]+)/([0-9]+)/([a-z0-9\-]+)?$ index.php?alias=$1\?$2\-$3 [L]
Array
(
[alias] => blog?8753-lowering-expectations-with-skype
)

.htaccess - clean urls with different parameters

Is there a way to get this to work?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ index.php?a=1&b=2 [L]
RewriteRule ^([^/]+)/([^/]+)$ index.php?a=$1&c=$2 [L]
The urls should look like this:
http://test.com/a/b
or
http://test.com/a/c
It only works with the first rule.
In my case I'm trying to create a profile page and get the ID either of the session ID or via $_GET['id'].
So if I visit a profile of someone else the url is
index.php?page=profile&id=25
/profile/25
And if I'm visiting my own profile it is
index.php?page=profile
/profile
And for example I want to edit my profile it is
index.php?page=profile&action=edit
/profile/edit
I hope you understand what I mean and can help me.
The key to solving this is noticing the differences between each parameter you want to pass.
If the visitor is looking at someone else's profile, an id (numeric) is passed.
If the visitor is editing their profile, a parameter string (alphanumeric) is passed
If the visitor is looking at their own profile, or another generic page, no extra parameters are passed
.htaccess rules can be most easily written from the most specific to the most general, so translating this, the rules become
RewriteRule ^([^/]+)/([0-9]+)$ index.php?page=$1&id=$2 [L]
RewriteRule ^([^/]+)/([a-z0-9]+)$ index.php?page=$1&action=$2 [NC,L]
RewriteRule ^([^/]+)$ index.php?page=$1 [L]
It is also important to skip existing files & directories, however because RewriteCond statements only match the next RewriteRule, it is easiest to do this in a slightly different way than you are doing it.
RewriteEngine On
# If the file or directory exists, exit
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [END]
RewriteRule ^([^/]+)/([0-9]+)$ index.php?page=$1&id=$2 [L]
RewriteRule ^([^/]+)/([a-z0-9]+)$ index.php?page=$1&action=$2 [NC,L]
RewriteRule ^([^/]+)$ index.php?page=$1 [L]

Twitter Like URL but with a #'s?

I am making a social networking website, and I can't get this done:
If the url is http://url.com/#username, I want it to show the http://url.com/user?u=username page, but show http://url.com/#username URL.
However, if there is no # in the beginning, treat it like a regular URL.
This is my .htaccess file:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/(\d+)*$ ./user.php?u=$1
The last three lines are what I tried, however that does not work as I wanted it to. I thought it would work because RewriteRule ^/(\d+)*$ takes any URI after the slash, and rewrites it to .user.php?u=*, but that didn't work, so I am looking for some suggestions on what to do next.
From my understanding of your question, this should work.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^#(.+?)$ user.php?u=$1 [NC,L]
It requires you to have a # before the username and it passes it as a GET variable (u) However, a person can add other characters which could confuse it as a username.
/#username/muffins
But if you want this, and to have pages per username (ie, /#username/info, /#username/about, etc) you can just use the explode() function in PHP.
If you just want it to get the username and nothing else, you can try
RewriteRule ^#([A-Za-z0-9]+)$ user.php?u=$1 [NC,L]
Hope this helps! :)

htaccess url rewrite

i have a htaccess file which redirectes all the requests to index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php
My question is i would like to make a redirect to folder which doesn't exist and it should not affect the present htaccess redirects to index.php. since it is linked to entire website
for eg
domain.com/search=kannan&id=21
to
domain.com/kannan
I just need a way to allow only this request and everything else goes to index.php, any ideas...
You could use a condition to capture requests that match a specific pattern, like:
RewriteCond %{REQUEST_URI} ^domain.com/search(.+)$
Then do your rewrite. Or: http://www.google.com/search?q=htaccess+query+string+rewrite
i suggest you to pass id through form . Means use Form post method to pass id then you only need to have 'domain.com/kannan' in url and id will passed as post
Use similar type of code as below -
<form method="post" action="domain.com/kannan">
<input type="hidden" value="21" name="id" />
</form>
In this way form will be posted to domain.com/kannan with id = 21 and url will be domain.com/kannan
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1
#RewriteRule ^ index.php [L]
</IfModule>

Resources