FOLLOWUP QUESTION ADDED TO THE BOTTOM!
I'm running a bunch of php code on my index page to check for GET values, but I'm having trouble figuring out how to rewrite the URLs.
I want to rewrite my URL form this:
www.domain.com?topic=courses&title=coursetitle&chapter=chaptertitle
Well, I guess technically it looks like this, right?:
www.domain.com/index.php?topic=courses&title=coursetitle&chapter=chaptertitle
to this:
www.domain.com/courses/coursetitle/chaptertitle
In other words, I have multiple GET values, and I want each to be displayed after a slash, but not have index.php displayed at all. Does that make sense? I'm sory if I'm bad at explaining it.
Also, if you got the time to explain what each part of the code does, so I don't just end up copy pasting it, but actually learn what's going on, that would be appriciated.
Followup question
I have 4 different topics on my webpage, lets use colors as example names (red, blue, green, yellow).
Topic "red" has an subcategory, lets say this is called "hue", and "hue" itself has a subcategory of "saturation".
Lets give "hue" a value of 8, and "saturation" a value of 3. Now the URL should look something like this:
www.domain.com/red/8/3
Rewritten from:
www.domain.com/index.php?topic=red&hue=8&saturation=3
This is all fine and dandy, and the code you provided in the comments does that for me.
Now, lets give our "blue" topic some subcategories as well. Lets says "darkness" with a value of 2, and keep it at one subcategory for simplicity
Now, if I go to:
www.domain.com/blue/2
How do I make sure it knows that my second GET value is supposed to be $_GET['darkness'], and not $_GET['hue'] like my first rewrite tells it to be?
Is there a way to look at my first GET value, and from that decide if the next value it reads is one or the other?
Or am I best of making real pages for my 4 subjects, instead of running everything from my index, and then create rewrites for each?
This should do the trick for you:
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?topic=$1&title=$2&chapter=$3 [L]
Related
I want to make URL friendly with multiple conditions.
I got this: www.example.com/?lang=en&page=test&model=mymodel
I want to have: www.example.com/en/test/mymodel
But I got also this (with other parameters):
www.example.com/?lang=en&otherpage=othertest&othermodel=myothermodel
Must be:
www.example.com/en/othertest/myothermodel
How can I do this for my entire website?
If you're going to use friendly URLs that look like this:
www.example.com/<language>/<value1>/<value2>
then Apache won't be able to distinguish between the first and the second "non-friendly" URLs that you mentioned:
www.example.com/?lang=en&page=test&model=mymodel
www.example.com/?lang=en&otherpage=othertest&othermodel=myothermodel
This is because the parameter names (page and model in the 1st, otherpage and othermodel in the 2nd URL) are not present, and can't be guessed, from the friendly URL.
A possible workaround depends on how many different scenarios you have, that is, how many different parameters you want to handle.
E.g. if you only have a few scenarios, you can add a part to the friendly URL pattern telling Apache which parameter names to use, like so:
www.example.com/<language>/<parameter_set>/<value1>/<value2>
then, tell Apache to use the first parameter set if <parameter_set> equals e.g. 1, the second set if it equals 2 and so on.
A sample rewrite rule set could be:
RewriteEngine On
RewriteRule ^([\w]+)/1/([\w]+)/([\w]+)$ ./?lang=$1&page=$2&model=$3
RewriteRule ^([\w]+)/2/([\w]+)/([\w]+)$ ./?lang=$1&otherpage=$2&othermodel=$3
Please note that 1 and 2 are completely arbitrary (they could be any other string).
Naturally, the official docs are there to help.
i'm trying to understand some rules or rewrite engine but i can't figure how to do it.
i have this link:
w**.example.com/index.php?city=new+york
and i wish to rewrite to this new:
w**.example.com/good-parties-in-new-york
the value of city can change to any other city.
but the point here is I only what to rewrite if all the key is:
index.php?city=
because the
index.php?zone=
is used for other things, etc...
any suggestion? thanks.
I'm a little confused on what exactly you want to achieve. URL rewriting is normally done to make URLs look nicer, not the other way around.
You would typically want to have a nice URL like this (which you'd communicate to your users):
w**.example.com/good-parties-in-new-york
act as an "alias" for a not-so-nice looking URL like this (= the actual page being served, unbeknownst to the users):
w**.example.com/index.php?city=new+york
With Rewrite, you can backreference regular expressions. In this case, you could convert parts of the "nice" URL into RegEx's which you would then backreference with variables in the query string of the page working in the background.
E.g.:
RewriteEngine On
RewriteBase /
RewriteRule ^good-parties-in-([a-z]+)-([a-z]+)$ index.php?city=$1+$2 [NC,L]
The first RegEx (([a-z]+)) is referenced as $1, the second as $2 (and so on).
Note that this example will only work for city names consisting of two words, like New York, San Francisco etc. You'll have to figure out of how many words city names can consist of and rewrite your code accordingly. (You might also have to set different flags.)
Plus, you should make sure that your php script checks against existing city names and throws an appropriate error/gives out a warning if users enter fantasy names like good-parties-in-magical-rainbow-city or similar.
If this isn't what you're looking for, maybe you could clarify your question?
I'm working on my htaccess and I finally got a result I can deal with. First I've got this
RewriteEngine on
RewriteBase /
RewriteRule ^blog/([a-zA-Z0-9\-/\.]+)/?$ blog.php?id=$1article_title=$2 [L]
This helps show my urls like so:
https://www.mydomain.com/blog.php?id=10
To
https://www.mydomain.com/blog/10/title.com
https://www.mydomain.com/blog/10/
https://www.mydomain.com/blog/10
https://www.mydomain.com/blog/10/title.com/
Four things here...
First is that all of these are accessible. I only want the first to appear and the others to direct there.
Second is that the article title will have spaces. Is there a way to turn spaces into - rather than have spaces?
Third is...is it okay to have .com within the url at the end? It just happens to be part of a post article title.
Fourth is do I include the extra part of the url$article_title in the urls I use? I'm lost on that part. Is it the same as I did with the id?
Last I was curious to know if I needed the id to show up. Can I exclude that in some way?
If I have urls already in place that use blog.php?id=10 do I change that to the new one? If I can't find it I'd like the url to go to the first rewritten url. All of the possible examples should go to that first url. or one without the id.
A big problem is that I am not a programmer….! So I need to solve this with means within my own competence… I would be very happy for help!
I have an issue with a lot of duplicated URLs in the Google index and there are strong signs that it is causing SEO problems.
I don’t have duplicate links on the site itself, but as it once was set-up, for certain pages the system allows all sorts of variations in the URL. As long as is it has a specific article-id, the same content will be presented under an infinite number of URLs.
I guess the duplicates in Google's index has been growing over long time and is due to links gone wrong from other sites that links to mine. The problem is that the system have accepted the variations.
Here are examples of variations that exists in the Google index:
site.com/a/Cow_Cat/id/5272
site.com/a/cow_cat/id/5272
site.com/a/cow…cat/id/5272
site.com/a/cowcat/id/5272
site.com/a/bird/id/5272
The first URL with mixed case is the one used site-wide and for now I have to live with it, it would take too long time to make a change to all lower case. I cannot make a manual effort via htaccess as it is a total of 300.000 articles. I believe there are 10 ‘s of thousands that have one or more duplicates.
My question is this:
Is it possible to create rules for canonical URLs in htaccess in order to make the above URLs to be handled as one as well as for the rest of the 300.000?
I e, is there a way to say that all URLs having
/a/*/id/uniqueid
should be seen as one = based only on the unique ID and not give any regard to the text expressed with the “*”?
My hope is that it would be possible to say that a certain pattern like above should only be differentiated by the last unique segment.
If it is not possible in htaccess, how would it be done with link rel="canonical" on each page, can the code include wildcards?
I should add that the majority of the duplicates are caused by incoming links being lower case where the site itself is using a mix. Would it be OK to assign a canonical URL only with lower case although the site itself is basically always using a mix of lower/upper case?
If this is possible, I would be very happy to be helped with how to do it!!!!
Jonas
Hi Michael! I am not an expert but this is how I think it could be done:
1) My problem is that the URLs have mixed cases and I cannot change that now.
2) If it is OK for the searchengines, it would be fine for me to make the canonical URL identical to the actual URLs with the difference that it was all lower case, that would solve approx 90% of the duplicates. I e this would be the used URL: site.com/a/Cow_Cat/id/5272 and this would be the canonical: site.com/a/cow_cat/id/5272. As I understand, that would be good SEO...or...?
My idea was NOT to change the address browser address bar (i e using 301 redirect) but rather just telling the search engines which URLs that are duplicates, as I understand, that can be done by defining a canonical URL either in htaccess (as a pattern - I hope) or as a tag on each page.
3) IF, it would be possible to find a wildcard solution...I am not sure if this is possible at all, but that would mean it was possible to NOT assign a specific canonical URL but rather a "group pattern", i e "Please search engine, see all URLs with this patter - having the unique identifier in the end - as if they are one and the same URL, you SE, decide which one you prefer": /a/*/id/uniqueid
Would that work? It will only work in htaccess if canonical URLs can be defined as a group where the group is defined as a pattern with a defined part as the unique id.
Is it possible when adding a tag for each page to say that "all URLs containing this unique id should be treated the same"? If that would work it would look something similar to this
link rel="canonical" /a/*/id/5272
I dont know if this syntax with wildcard exist but it would be nice : )
My advice would be to use 301 redirects, with URL rewriting. Ask your webmaster to place this in your apache config or virtual host config:
RewriteMap lc int:tolower
Then inside your .htaccess file you can use the map ${lc:$1} to convert matches to lower case. Here, the $1 part is a match (backreference from brackets in a regex in the RewriteRule) and the ${lc: } part is just how you apply the lc (lowercase) function set up earlier. Here is an example of what you might want in your .htaccess file:
RewriteCond %{REQUEST_URI} [A-Z] #this matches a url with any uppercase characters
RewriteRule (.*) /${lc:$1} [L,R=301] #this makes it lowercase
As for matching the IDs, presuming your examples mean "always end with the ID" you could use a regex like:
^(.+/)(\d+))$
The first match (brackets) gets everything up to and including the forward slash before the ID, and the second part grabs the ID. We can then use it to point to a single, specific URL (like canonical, but with a 301).
If you do just want to use canonical tags, then you'll have to say what you're using code wise, but an example I use (so as not add tags to hundreds of individual pages, for instance) in PHP would be:
if ($_SERVER["REDIRECT_URL"] != "") {
$canonicalUrl = $_SERVER["SERVER_NAME"] . $_SERVER["REDIRECT_URL"];
} else if ($_SERVER["REQUEST_URI"] != "") {
$canonicalUrl = $_SERVER["SERVER_NAME"] . preg_replace('/^([^?]+)\?.*$/', "$1", $_SERVER['REQUEST_URI']);
}
Here, the redirect URL is used if it's available, and if not the request uri is used. This code strips off the query string (this bold bit in http://www.mysite.com/a/blah/12345/?something=true). Of course you can add to this code to specify a custom path, not just taking off the query string, by playing with the regex.
I have a number of pages in my site, as one would expect.
For example:
index.php
submit.php
view.php?id=blah
I want these rewritten like
index/
submit/
view/blah
Whats the best way of doing this?
The ways of handling it through .htaccess Rewrite can generate a bit of a headache. It seems like a basic answer, but unless you're up on your regular expressions, you're going to be lost.
There's a few ways of handling it, however. I'm assuming that you only have index.php, submit.php, and view.php with an id associated.
RewriteEngine On
RewriteRule ^(index|submit|view)/(\d+)$ /$1.php?id=$2
RewriteRule ^(index|submit|view)/(\d+)$ /$1.php
Here's how it works: You tell .htaccess to turn on the Rewrite Engine. Step 2, you give the site the parameter that tells it how it's done. The parameter in this case reads: At the beginning of the url, after the domain name, check for index, submit, or view. If those exists, it'll look for the id. If both those exists, it will return the value into PHP as /(index, submit, or view)?id=$id.
The second one is in case the ID isn't viable.
This is a simple way of handling it. A more complex way of handling it would be...
RewriteEngine On
RewriteRule ^([a-z]+)/?(\d+)?$ /$1.php?id=$2
This will load whatever is written in regular alphabetical characters of upper and lower case letters only, use that as the filename, then detects if id is even necessary--it will load without.
You should be sure to include some safeguards on your $_GET lines to return errors if the names are erroneous or doesn't return anything of worth.
You should play around with it, research Regular Expressions over a pot of coffee and something alcoholic (I believe that regexp is the #1 cause of alcoholism in modern programmers, but I could be wrong ;-P ...) til you find a scheme that fits comfortably into your system.
As a side-note, you can have as many RewriteRules as you need, but they always get processed from the top one first. I realize this sounds like common sense, but it's important to know when debugging.