I'm working on a simple five page website which includes a blog. This is the first time I'm using .htaccess to correctly rewrite my URLs for SEO friendly optimization.
The two parameters I am trying to allow a visitor to use is sitename.com/blog/category/WORD or sitename.com/blog/SLUG. If /category/word is used, I'd want it to list all the posts with the chosen category word. If /slug is used (short title of a post such as "learn-how-to-code"), I'd want it to just show that specific post.
Here's my old .htaccess:
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
It was originally working fine for single pages, such as sitename.com/about, sitename.com/contact and so on, but any time I tried sitename.com/blog/SLUG or sitename.com/blog/category/WORD it would just redirect to the blog page. I am echoing $_GET['category'] and $_GET['slug'] in blog.php to test it, but it never showed anything.
After looking at a few posts here, I figured out that I needed to add some separate lines to just check on /blog being used and to pull in the appropriate parameters.
Here's my current .htaccess:
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^blog/([^\.]+)$ blog.php?slug=$1 [NC,L]
RewriteRule ^blog/category/([^\.]+)$ blog.php?category=$1 [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
The sitename.com/blog/SLUG is working fine, but anytime I do sitename.com/blog/category/WORD, it's showing "category/WORD" as the slug, and not breaking it into the category word.
Am I doing something wrong here? Is there a better way of doing this?
Simple explanation without tech is for better clarification
Line1 RewriteRule ^blog/([^\.]+)$ blog.php?slug=$1 [NC,L]
Line2 RewriteRule ^blog/category/([^\.]+)$ blog.php?category=$1 [NC,L]
in line 1 you are doing regular expression checking by code ([^\.]+) after the url blog
and in line 2 your url is kind of hard coded part of category and then you are doing regular expression check
so in simple work regular engine never goes to the line2 of code because it already become part of line1 is already checked and passed regular expression part so category becomes part
simple tip: Always keep hard url parts first and regular expression parts rules at the end.
You'd need to swap your ^blog lines. Since the first one is using the L flag, you're essentially telling it to stop using other rules, so it's already picking up $1 as category/WORD in your case.
I don't know how the rest of your backend is setup, but you could also look into routing everything through an index page.
Related
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]
my problem is that I want to get three simple rules working, but my knowledge is too little, to get them working together:
These are obvious:
RewriteRule ^login$ /login.php [L]
RewriteRule ^register$ /register.php [L]
domain.com/login and domain.com/register
Secondly, since i have only one page used for displaying data, i want its url to be as simple as posible, like:
RewriteRule ^(.*)$ /data.php?id=$1 [L]
which should be translated into:
domain.com/1a2s3d
As third, I want to be able to change url with activation code:
RewriteRule ^register/activate/([^/]+)$ /register.php?action=activate&code=$1 [L]
which finally should be translated into:
domain.com/register/activate/some-hash
I know just simply basics. And I cannot mix all of these three ideas into one single working htaccess file. With the second rule the server gives me 500 error, with third rule registration page works, but css file path is translated into domain.com/register/activate/theme/style.css instead of domain.com/theme/style.css
Any help would be appreciated.
Try just with that:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^login$ /login.php [L]
RewriteRule ^register$ /register.php [L]
RewriteRule ^register/activate/([^/]+)$ /register.php?action=activate&code=$1 [L]
RewriteRule ^(.*)$ /data.php?id=$1 [L]
There is an issue with the htaccess rewrite conditions in my setup.
Currently I have the following code.
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://mydom.com/$1.php
This works fine for any base page making them look like this.
http://mydom.com/page
What I want to also be able to do is add parameters from the url if they exist. I have some pages that will be like this.
http://mydom.com/page?param=1&secondParam=2
What I've tried to do is add this.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*)$ http://mydom/$1/$2/$3 [L]
RewriteRule ^(.*)/(.*)$ http://mydom/$1/$2 [L]
This made sense to me, because I thought if the condition didn't match, it would move on, but this gave me an internal server error.
What I ended up doing was setting up a separate rule for each page that could have multiple parameters like this.
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/(.)/(.)$ http://mydom.com/page.php?param=$1&secondParam=$2 [L]
RewriteRule ^page/(.*)$ http://mydom.com/page.php?param=$1 [L]
RewriteRule ^(.*)$ http://mydom.com/$1.php
This works, however you need to keep in mind relative links you may have in your site such as style sheets and javascript files. In my case, I had to replace all relative paths with full site paths, depending on the way you set up your site, it could take a while to replace.
i have a strange apache mod_rewrite problem. I need to hide a sub-directory from the user, but redirect every request to that sub-directory. I found several quite similar issues on stackoverflow, but nothing really fits, so i decided to post a new question.
My .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)?$ foo/$1 [QSA,L]
The document-root only contains the following folder/files:
/foo/bar/index.html
I would now expect that example.com/bar and example.com/bar/ would just show me the contents of index.html.
Instead example.com/bar/ show me the content as expected but example.com/bar redirects me with a 301 to example.com/bar/foo/ an then shows the contents. I really don't get why there is a 301 redirect in this case.
When i put something this
RewriteCond %{REQUEST_URI} !^[^.]*/$
RewriteCond %{REQUEST_URI} !^[^.]*\.html$
RewriteCond %{REQUEST_URI} !^[^.]*\.php$
RewriteRule ^(.*)$ $1/ [QSA,L]
on top of that rule it seems to work, but that would require me to list every used file extension...
Is there any other way i can omit the redirect, the folder "bar" should never be seen by an outside user.
Thanks in advance!
1st rewrite rule is redirect from /foo/(.) to ($1) and second - from (.) to $1.
just idea, this has not been tested.
Better late than never...
Got it working with a simple RewriteRule which append a / to every url that doesn't have on.
# only directories
RewriteCond %{REQUEST_FILENAME} !-f
# exclude there directories
RewriteCond %{REQUEST_URI} !^/excluded-dirs
# exclude these extensions
RewriteCond %{REQUEST_URI} !\.excluded-extension$
# exclude request that already have a /
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [R=301,L]
I’m trying to use the following .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^images/
RewriteRule (.*) view.php?picid=$1 [L]
RewriteRule ^/user/(.*)$ /users.php?user=$1
I want two things to happen: Whenever someone requests /1234, it redirects to /view.php?picid=1234, and also when someone visits /users/bob, it redirects to /users.php?user=bob.
My code however, doesn’t seem to be working correctly.
There are several ways to do that. Here’s one that should work:
RewriteRule ^user/(.+)$ users.php?user=$1 [L]
RewriteRule ^([0-9]+)$ view.php?picid=$1 [L]
The first rule will catch any request that’s URI path begins with /user/ followed by one or more arbitrary characters. And the second will catch any request that’s URI path begins with / followed by one or more digits.
The initial problem with your rules is that the RewriteRule with (.*) will match everything.
If you do not want it to match a URL with a slash in it (such as users/bob), try ^([^/]*)$
Secondly, after a URL is rewritten, the new URL goes through your rules again. If you want to avoid matching something that has already been rewritten once, you should add a condition like
RewriteCond %{REQUEST_URI} !\.php