I have a dual language site. If a page isn't found in a localized copy, I need redirect up a level to another folder. Specifically, I need to redirect uk pages to teh corresponding en version.
A sample url is:
http://example.com/uk/this-is-thepage/ to go to http://example.com/this-is-thepage/
The sites have identical page names after the folder.
I don't want to have to redirect every page individually, and the UK site doesn't have many pages at all. I also only want this to happen when the page doesn't exist, as not all pages exist in uk. I wrote some code that was working, but then I realized I couldn't handle an arbitrary /uk/ page.
Inside /uk/.htaccess, you can use this rule to forward to parent directory if requesting URI is not found in `/uk/:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .+ ../$0 [L]
-f and -d conditions mean request is not for a valid file/directory.
Related
I'm looking to handle the URL's except homepage with a common PHP file. This is just like a PHP $_GET request except the difference that there would be no parameter. It'll be just like a file.
Ex- http://localhost/ - This should be managed by index.php file as usual.
http://localhost/ANYTHINGHERE - This should be thrown to a custom PHP file which would then decide what to do.
Actually, I'm working on a project where I need to hide the URL information from the users. So, the file that would manage the ANYTHINGHERE URL would actually access a directory localhost/i/.
Thanks and waiting for best response!
To achieve this you need two parts:
First: .htaccess which redirects all accesses to your domain passed to a php script (index.php here):
RewriteEngine On
RewriteRule (.*) index.php/$1
Second: In index.php you get the user-entered URI as $_SERVER['PATH_INFO'] (starting with /)
This, however, makes all requests to go through the index.php script (depending on the location of index.php you could also get an endless recursion, so read on ;) ). Normally one doesn't want that (e.g., images should be served directly by the web server). Thus, one normally uses (i.e., existing directories, files and links are served by the web server directly):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^(.*)$ - [NC,L]
RewriteRule (.*) index.php/$1
If this should take place in a subdirectory you need to add RewriteBase /subdirectory directly after RewriteEngine On.
If you don't want to use $_SERVER['PATH_INFO']you can also use RewriteRule (.*) index.php?url=$1 [QSA], then you get the user entered URI as $_GET['url'].
This requires mod_rewrite to be loaded on the server.
See http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html.
The site I'm building at the moment is made of two main parts: The side which the general public can access, and the admin side which only authorised people can access.
It's built with basic templating such that the different sections are accessed as follow (Using RewriteRules).
Public:
http://localhost/about should be rewritten to http://localhost/index.php?page=about
Admin:
http://localhost/admin/manage-users should be rewritten to http://localhost/admin/index.php?page=manage-users
All URLs only ever have one argument. That is, public will always be localhost/PAGE and admin will always be localhost/admin/PAGE.
At the moment, I have the following .htaccess file:
RewriteEngine on
RewriteRule ^admin/([^/.]+)/?$ /admin/index.php?page=$1 [L,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?page=$1 [L,NC]
This seems to work properly when you construct the URL correctly. For example, if I navigate to localhost/about or localhost/admin/manage-users both pages load correctly. But if I go to localhost/about/blah or localhost/admin/manage-users/blah, the pages load, however the CSS is non-existant. Looking at the developer tools in Chrome, it appears that this is because it's trying to load the CSS file from the directories localhost/about/css/ and localhost/admin/css/ respectively, due to the style sheet being linked to the page with a relative path. (In reality, localhost/css/ is the directory it is actually located in.)
So even though the RedirectRule ignores any extra arguments in the URL, it is trying to load relative paths with respect to the last "directory" provided in the URL.
Is there any way to completely ignore any extra ../.. arguments? Or, even better, trigger a 404 when too many arguments are provided?
UPDATE: I have just discovered that the problem is actually a lot more complex than I previously thought. As my pages only had dummy data to test out the templating files, I didn't notice it until now.
It appears than when you navigate to localhost/admin or localhost/admin/manage-users it is loading from the http://localhost/admin/index.php file, but when you navigate to localhost/admin/manage-users/blah is reverts back to loading the http://localhost/index.php file. This makes me think that there is something I need to change in the RewriteRule, though I have no idea what.
It is better in long term to use absolute path in your css, js, images files rather than a relative one. Which means you have to make sure path of these files start either with http:// or a slash /.
But in order to avoid making changes to your website in-mass you can use these rules to fix your css/js/images links:
RewriteEngine on
# fix CSS/js/images links
RewriteRule (?:^|/)((?:css|js|images)/.+)$ /$1 [L,R=301]
RewriteRule ^admin/([^.]+)/?$ /admin/index.php?page=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /index.php?page=$1 [L,QSA]
Don't forget to replace first rule with your actual css/js/images directories.
You need to either make all of your links absolute URLs (e.g. href="/css/style.css") or add a relative URL base to the header of your page:
<base href="/" />
My root directory contains a selection of PHP files: index.php, about.php etc. Each of these can take an ID parameter to customize a few of the variables on the page, such as contact phone number, email address etc.
If a visitor was to access http://myserver/joebloggs (joebloggs being a parameter, not a subdirectory), I want them to be served up with the index.php page from the root directory, but for joebloggs to be passed to index.php as the ID and the page then customized. I don't want to have to create a subdirectory for every user ID, I'd rather maintain this info in a DB and have PHP generate the pages for me.
Furthermore, when the user then navigates to the about.php page, I would like this ID to be carried over and then have the about page customized too, i.e. a link to 'about' maintains the ID parameter in the URL: http://myserver/joebloggs/about/
I've got a rough idea in my mind how to do this and have been reading up on mod_rewrite but haven't had much luck in piecing various solutions together.
Any pointers or help would be much appreciated.
Try something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \/(.+?)\/about
RewriteRule . /about.php?p1=%1 [L]
RewriteCond %{REQUEST_URI} \/.*?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*?)$ /index.php?p1=$1 [L]
Should do the job. Tested it on my server.
What is the best way to create user vanity URLs under a LAMP configuration?
For example, a user profile page could be accessed as follows:
http://www.website.com/profile.php?id=1
Now, if a user enters a "vanity URL" for their profile I would want the the vanity URL to load the page above.
For example, if a user selects "i.am.a.user" as their vanity URL and their user id in the database is 1 then http://www.website.com/profile.php?id=1 would be accessible by that URL and http://www.website.com/i.am.a.user .
I'm aware of mod rewrites in .htaccess but not sure how that would work here.
As I mentioned my site is in PHP, MySQL, Linux and Apache.
Thanks.
Say your other pages had specific URLs that you could check against, the following should help.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_]*)$ /profile.php?user=$1 [L]
This helps to maintain current URLs, while allowing for the user shortcut URLs. Also, the RewriteRule will only match URLs that don't contain a /, which will help protect against non-intended redirects. So,
/i-am-a-user -> MATCHES
/i_am_a_user -> MATCHES
/i-!am-a-user -> NOT MATCHED
/i.am.a.user -> NOT MATCHED
/i.am.a.user/ -> NOT MATCHED
/some/page/ -> NOT MATCHED
/doesnotexist.php -> NOT MATCHED
/doesnotexist.html -> NOT MATCHED
Hope that helps.
EDIT
I've updated the rules above so that actual files/directories aren't redirected as well as making sure that any .php or .html file is not sent to profile.php either.
Rewrite for site.com/user/USERNAME:
In your root web directory, place a .htaccess file:
RewriteEngine on
RewriteRule ^user/(.+)$ profile.php?name=$1 [L]
This routes all requests that starts with "user" to profile.php and pass the URI to $_GET['name']. This method is preferred if you have a lot of files / directories / other rewrites.
Rewrite for site.com/USERNAME:
RewriteEngine on
# if directory or file exists, ignore
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ profile.php?name=$1 [L]
This routes to profile.php ONLY if the requesting file or directory does not exists, AND when the request URI is not empty (ie, www.site.com)
PHP backend
Now in profile.php, you can have something like this:
if (!empty($_GET['name'])
$user = ... // get user by username
else
$user = ... // get user by id
First setup your .htaccess file to send all requests for files and directories that don't exist to a single php file:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) router.php [NC,L]
Then inside your router.php, look at $_SERVER['REQUEST_URI'] to get the username that you can then use in your query to get the data about the user.
This assumes that all URLs that are not user profile pages exist as physical files on your server.
If that's not the case, you can do some logic in router.php to decide what to do on each request. Do a google search for url routing in php and you'll get plenty of examples.
Well, you could solve this using an apache RewriteMap as well of course. The RewriteMap can be a plain text file (that you update regularly based on what your users enter), or alternatively you could point it to a script (Perl, PHP, whatever suits you) to do the rewriting for you.
For a quick summary on how to set this up using PHP refer to Using a MySQL database to control mod_rewrite via PHP.
I am trying to design a small site where most of (95%) of site assets will be passed through home sort of PHP script, and the remaining 5% are being hosted from a subdomain (background images, logos, etc. What I would like is that whenever a page is called, say www.example.com/blog/My_trip_to_the_andes the page that would be called is
htdocs/nexus.php and that script would be able to discover what URI was requested. From that URI the script will determine what the user is asking for and generate it. As the redirects happen the headers need to be maintained, so the script receives any POST data or COOKIE data.
I believe that I can accomplish this with an .htaccess in the site root directory. But I have little to no experience with .htaccess and the documentation doesn't seem to speak to this.
Is this even a good idea? I want every page request to go through a script so I can log, do some 404 tracking and redirects, gate keep cross site requests for resources, and stuff I can't even think about yet.
.htaccess;-
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /htdocs/nexus.php [L]
</IfModule>
And the filename that was actually called should be available as $_SERVER['REQUEST_URI']
Since your static resources resident on a different domain, you could send all requests to your nexus.php file with this mod_rewrite rule:
RewriteEngine on
RewriteRule !^nexus\.php$ nexus.php [L]
The original requested URL is then available in $_SERVER['REQUEST_URI'] (note that this also contains the URL query and not just the URL path).
But if you have other files that you want to allow access to, you can exclude them with this additional condition attached to the previous rule:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^nexus\.php$ nexus.php [L]
Now only requests that can not be directly mapped onto existing files (!-f) are rewritten to nexus.php.