I've got a single tikiwiki instance and several domain names. I want domain-1.com to have a homepage at domain-1.com/tiki-index.php?page-1. And then I want domain-2.com to have a homepage at domain-2.com/tiki-index.php?page-2. Both will internally map to the same tikiwiki instance.
I.e. I want several domains to point to the same tikiwiki instance. But coming from different domains should land you at different home pages. And then user could manually navigate from domain-1.com/tiki-index.php?page-1 (hompage) to domain-1.com/tiki-index.php?page-2
I tried to do this by setting DirectoryIndex but looks like it ignores all page arguments, i.e. ?page-1.
Any clues how to make an index page with arguments?
did it mylsef
RewriteEngine on
RewriteCond %{REQUEST_URI} "^/$"
RewriteRule ^(.*) "http://domain-1.com/tiki-index.php?page=page-1"
The key here is to set rewrite condition to match empty URI, that is the default address - http://domain-1.com
Related
I'm trying to rewrite the below URL but the URLs just don't change, no errors.
Current URL:
https://example.com/test/news/?c=value1&s=value2&id=9876
Expected URL:
https://example.com/test/news/value1/value2
My .htaccess
RewriteEngine On
RewriteRule ^test/news/([^/]*)/([^/]*)$ /test/news/?c=$1&s=$2&id=1 [L]
but I've seen many articles where a url such as example.com/display_article.php?articleId=my-article can be rewritten as example.com/articles/my-article for example with .htaccess
But the important point here (that I think you are missing) is that the URL must already have been changed internally in your application - in all your internal links. It is a common misconception that .htaccess alone can be used to change the format of the URL. Whilst .htaccess is an important part of this, it is only part of it.
Yes, you can implement a redirect in .htaccess to redirect from the old to new URL - and this is essential to preserve SEO (see below), but it is not critical to your application working. If you don't first change the URL in your internal links then:
The "old" URL is still exposed in the HTML source. When a user hovers over or copies the link, they are seeing and copying the "old" URL.
Every time a user clicks one of your internal links they are externally redirected to the "new" URL. This is slow for your users, bad for SEO (you should never link to a URL that is redirected) and bad for your server, as it potentially doubles the number of requests hitting your server (OK, 301s are cached locally).
To quote from #IMSoP's answer to this reference question on the subject:
Rewrite rules don't make ugly URLs pretty, they make pretty URLs ugly
So, once you have changed your internal links to the "new" (expected) format, eg. /test/news/value1/value2 (or should that be /test/news/value1/value2/id or even /test/news/id/value1/value2? See below), then you can do as follows...
RewriteRule ^test/news/([^/]*)/([^/]*)$ /test/news/?c=$1&s=$2&id=1 [L]
This internally rewrites a request from /test/news/<value1>/<value2> to /test/news/?c=<value1>&s=<value2>&id=1. However, there are a couple of issues with this:
/test/news/ is not itself a valid endpoint. This requires further rewriting. Perhaps you are serving a DirectoryIndex document (eg. index.php)? This might appear seamless to you, but this requires an additional internal subrequest and makes the rule dependent on other elements of the config. You should rewrite directly to the file that handles the request. eg. /test/news/index.php?c=<value1>&s=<value2>&id=1 (remember, this is entirely hidden from the user).
You are hardcoding the id=1 parameter? Should every URL have the same id? Or should this be passed in the "new" URL (which is what I would expect)? What does the id represent? If this is critical to the routing of the URL then the id should appear earlier in the URL-path, in case the URL gets accidentally truncated when copy/pasted/shared.
If the id is required then it needs to be passed in the "new" URL. We only have the "new" URL to route the request, so the information can't be hidden.
So, if the "new" URL is now /test/news/<id>/<value1>/<value2> then the rewrite would need to be like this instead:
# Rewrite new URLs to old/actual URL
# "/test/news/<id>/<value1>/<value2>" to "/test/news/?c=<value1>&s=<value2>&id=<id>"
RewriteRule ^test/news/(\d+)/([^/]+)/([^/]+)$ /test/news/?c=$2&s=$3&id=$1 [L]
Then (optionally*1) you can implement an external redirect in order to preserve SEO. This is for search engines that have indexed the "old" URLs or third party inbound links that cannot be updated - these need to be corrected to inform search engines of the change and get the user on the "new" canonical URL having followed an out-of-date inbound link.
(*1 It's not "optional" if you are changing an existing URL, but optional with regards to your application being functional.)
This "redirect" goes before the above rewrite:
# Redirect old URLs to the new "canonical" URL
# "/test/news/?c=<value1>&s=<value2>&id=<id>" to "/test/news/<id>/<value1>/<value2>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^c=([^&]+)&s=([^&]+)&id=(\d+)
RewriteRule ^test/news/$ /$0%3/%1/%2 [QSD,R=301,L]
The $0 backreference contains the full match from the RewriteRule pattern, ie. test/news/ in this case - this simply saves repetition.
The %1, %2 and %3 backreferences contain the values captured from the preceding condition. ie. the values of the c, s and id URL parameters respectively.
Note that the URL parameters / path segments should not be optional as in your original directive (ie. ([^/]*)). If they are optional and they are omitted, then the resulting URL becomes ambiguous. eg. <value2> becomes <value1> if <value1> is omitted.
Note that the URL parameters must be in the order as stated. If you have a mismatch of "old" URLs with these params in a different order (or even intermixed with other params) then this can be accounted for with additional complexity. (It may be easier to perform this redirect in your server-side script, instead of .htaccess.)
The first condition that checks against the REDIRECT_STATUS environment variable ensures that we only redirect direct requests and not rewritten requests by the later rewrite (which would otherwise result in a redirect loop). An alternative on Apache 2.4 is to use the END flag on the RewriteRule instead.
The QSD flag (Apache 2.4) discards the original query string from the request.
You should test first with a 302 (temporary) redirect to avoid potential caching issues and only change to a 301 (permanent) redirect once you have tested that everything works as intended. 301s are cached persistently by the browser so can make testing problematic.
Summary
Your complete .htaccess file should look something like this:
Options -MultiViews +FollowSymLinks
# If relying on the DirectoryIndex to handle the request
DirectoryIndex index.php
RewriteEngine On
# Redirect old URLs to the new "canonical" URL
# "/test/news/?c=<value1>&s=<value2>&id=<id>" to "/test/news/<id>/<value1>/<value2>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^c=([^&]+)&s=([^&]+)&id=(\d+)
RewriteRule ^test/news/$ /$0%3/%1/%2 [QSD,R=301,L]
# Rewrite new URLs to old/actual URL
# "/test/news/<id>/<value1>/<value2>" to "/test/news/?c=<value1>&s=<value2>&id=<id>"
RewriteRule ^test/news/(\d+)/([^/]+)/([^/]+)$ /test/news/?c=$2&s=$3&id=$1 [L]
i'm trying to achieve the following:
I have domain.it and domain.fr
domain.it contains a website localized in multiple languages, so for example if you go to www.domain.it/fr/somecontent.php it shows that content in french language. This works. This website is hosted on a dedicated server.
In domain.fr i have an empty space with only an .htaccess. What i want is that when the user go to www.domain.fr/somecontent.php the browser shows the content from www.domain.it/fr/somecontent.php but keeping www.domain.fr/somecontent.php in the URL. So basically www.domain.fr/* should show the content from www.domain.it/fr/* but keeping www.domain.fr/* in the browser address bar.
Using an iframe is not an option because is not good for the SEO.
I'm using the following code inside the .htaccess on domain.fr (which is hosted on an OVH shared hosting):
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domain.fr$
RewriteRule ^(.*) https://www.domain.it/fr/$1 [P]
But when i open www.domain.fr or www.domain.fr/somecontent.php in the browser it says "Forbidden: You don't have permission to access /somecontent.php on this server."
Instead, if i place [L] or [L,R=302] in place of the [P] in the last line of .htaccess, it correctly redirect to the www.domain.it/fr/somecontent.php showing it contents, but it shows the destination url (the it domain) in the browser bar.
So i think the rules are correct, but for some reason when i use the [P] flag which as far as i know is needed to mask the url, it doesn't work.
Have you any clues ?
Thank you!
I have a site that's coded mainly in PHP, but I'm trying to rewrite my dynamic php URL's into static HTML URL's.
But I want the address bar to still remain as the static HTML link.
I'm trying to accomplish this through .htaccess (I have no access to httpd.conf as I'm hosted on a shared account). Here is what's written in my .httaccess file:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule ^inventory-search-([^.]+)-by-([^.]+).html$ http://www.pianostudiosandshowcase.com/inventory.php?search=$1&by=$2 [R]
But I can't get the address bar to remain as the static HTML link.
Here is a link to show you what I mean:
http://www.pianostudiosandshowcase.com/inventory.php?search=manufacturer&by=1
What am I missing?
You need to remove both the R flag in your rewrite rule as well as the protocol/domain name:
RewriteRule ^inventory-search-([^.]+)-by-([^.]+).html$ /inventory.php?search=$1&by=$2 [L]
Both will cause the server to externally redirect the browser, telling it "what you were looking for is not at that URL, you need to go to this entirely different URL". The forces the browser to display the new location in its address bar.
If you internally rewrite it, the browser has no idea the URI that it sent as a request had been changed, therefore the address bar remains unchanged.
Okay...i am doing something kinda strange and out of the ordinary. I will try to explain...
I have several domain names pointed to the same root directory on my webserver. I can access the entire website using any of the domain names (I know this is bad for SEO, but there are reasons). Additionally, none of the "pages" really exist...as they are all being built dynamically...so i have some mod rewrite rules set up to point all incoming queries to view.php and passing in variables to generate the page content...anyway...
What i want to do is set ONLY THE HOME PAGE of two of my domains to (invisibly) use content of an existing sub page. Here is an example:
These all are the same page:
www.domain1.com/process/
www.domain2.com/process/
www.domain3.com/process/
which is really doing something like: view.php?page=process/
I want this page to display for www.domain2.com (and still also be accessible at domain2.com/process)
Essentially, there is a sub page of the site that i want to serve as the "HOME" page for domain2.com and domain3.com but if domain1.com should still use the default (index.php) HOME page.
I am sure i will need to post clarifications to this once replies start coming in...but here is what i have at the moment:
# special rules to set other domain names default homepage as specific internal page
RewriteCond %{HTTP_HOST} ^www.domain2.com [NC]
RewriteRule ^(.+)?$ /view.php?page=process/ [NC,L]
Currently this is sending ALL traffic to domain2.com to the "process/" page...so it is blocking out all other pages. I need to know how to have this rule ONLY apply to the base domain without any extra query string or url path. The key is that i DO NOT want to affect other pages within the domain...so i shoudl still be able to browse the whole site using this domain name...i just get started on a different view.
To only match the homepage, i.e. http://domain2com/ you need to match the empty path (as mod_Rewrite removes the leading /.
RewriteCond %{HTTP_HOST} ^www.domain2.com [NC]
RewriteRule ^$ /view.php?page=process/ [NC,L]
Is the following possible?
A user requests the url http://example1.com/example.php and the apache opens http:// example1.com/example.php?id=1
A user requests the url http://example2.com/example.php and the apache opens http:// example2.com/example.php?id=2
But the user should not see the id in his browser adress bar (the user should only see http://example1.com/example.php or http://example2.com/example.php).
You can say the id is invisible for the user but transfered to the example.php.
How can I implement this?
Is that the correct solution?
RewriteEngine On
RewriteRule ^/example.php http://example1.com/example.php$1 [P]
ProxyPassReverse /example.php?id=1 http:// example1.com/example.php
RewriteEngine On
RewriteRule ^/example.php http://example2.com/example.php$1 [P]
ProxyPassReverse /example.php?id=2 http:// example2.com/example.php
You have to understand several concept.
Once the server received the user requested url he can do several things
Take the requested path from the url and use it without modifications. That's the default solution
Map the requested path to any other physical path, things that can be done via Alias, AliasMatch or RewriteRules.
Map the requested path to another website while hiding the fact thtat another website is requested. That's the proxy solution, thta mod_proxy or mod_rewrite could handle (but you do not need that)
Redirect the user to another path, sending him a new url to use, making another client/server roundtrip, with Redirect instructions or mod_rewrite (the swiss knife). But you do no need that.
So you want a server-side only remapping of the requested path.
Let,s say we will use mod rewrite to make this mapping. If you check all tags available in RewriteRule (summary here) the interesting ones are:
passthrough|PT : Forces the resulting URI to be passed back to the URL mapping engine for processing of other URI-to-filename translators, such as Alias or Redirect.
qsappend|QSA: Appends any query string from the original request URL to any query string created in the rewrite target
last|L: Stop the rewriting process immediately and don't apply any more rules. Especially note caveats for per-directory and .htaccess context (see also the END flag)
nocase|NC: Makes the pattern comparison case-insensitive.
details on the PT flag shows that:
The target (or substitution string) in a RewriteRule is assumed to be a file path, by default.
Well, that,s maybe enough for you. But using PT is a good thing, if you have other apache configusation elements you should try to let them apply after mod_rewrite job.
So... assuming you may need to handle some query strings arguments and that this id argument is based on the domain name in the request, and that only the example.php script needs this behavior; you should start your research with such rules (untested):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example1.com$ [nocase]
RewriteRule ^example\.php$ example.php?id=1 [passthrough,qsappend,last]
RewriteCond %{HTTP_HOST} ^example2.com$ [nocase]
RewriteRule ^example\.php$ example.php?id=2 [passthrough,qsappend,last]