Htaccess alias redirect fake multilanguage url - .htaccess

I have a domain www.domain.com with this kind of url
www.domain.com/my-italian-page.html (already rewritten by others htaccess rules)
I'd like to create a fake multilanguage url like
www.domain.com/my-english-page.html
The user will see in the address bar the rewritter url www.domain.com/my-english-page.html but the content that I'd like to show is the original www.domain.com/my-italian-page.html .
I'm on a shared server so I can't use apache vhost rule so I have to find a solution via htaccess.
Someone could help me to find the right way?
Thanks

So you want english URLs pointing to italian content? Hope your php script that generates these rewrite rules does the translating. But you'd do this for each one of your pages:
RewriteRule ^/?english-page.html$ /italian-page.html [L]
for each one of your pages.

Generally you want to keep the code executed in the web server as small as possible, so having a rewrite rule for each page is not usually a good idea. I suggest to implement this the way most CMS work when SEO URLs are enabled:
Rewrite any url (mydomain/anytext.html [actually you should not use the .html extension either]) to a script (eg. mydomain.tld/translate.php)
Use content of $_SERVER['PATH_INFO'] (should contain anytext.html) to display the correct page
Set correct HTTP response code if page does not exist: http_response_code(...) (see end of this answer for a function on php5 below 5.4: PHP: How to send HTTP response code?)
Sample .htaccess (actually originally "stolen" and severely modified from a typo3 setup)
RewriteEngine On
# Uncomment and modify line below if your script is not in web-root
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (.*) translate.php$1 [L]
Very basic pseudo-code-like (not tested, there may be syntax errors) example:
<?php
// using a database? you have to escape the string
$db = setup_db();
$page = db->escape_string(basename($_SERVER['PATH_INFO']));
$page = my_translate_query($page);
// no database? do something like this.
$trans = array( 'english' => 'italian', 'italian' => 'italian' );
$page = 'default-name-or-empty-string';
if(isset($_SERVER['PATH_INFO'])) {
if(isset($trans[basename($_SERVER['PATH_INFO'])])) {
$page = $trans[$trans[basename($_SERVER['PATH_INFO'])]];
}
else {
http_response_code(404);
exit();
}
}
// need to redirect to another script? use this (causes reload in browser)
header("Location: otherscript.php/$page");
// you could also include it (no reload), try something like this
$_SERVER['PATH_INFO'] = '/'.$page;
// you *may* have to modify other variables like $_SERVER['PHP_SELF']
// to point to the other script
include('otherscript.php');
?>
I saw in your answer that you have another script - dispatcher.php - which you seem reluctant to modify. I modified my response accordingly, but please keep in mind that by far the easiest way would be to just modify the existing script to handle any English paths itself.

Related

Mod Rewrite to remove language from url in Concrete5 cms

I'm totally stumped. Hope you can help. I just spent a month redeveloping our website in Concrete5 version 7.3.1, latest version, and I'm ready to launch. It's a multi-lingual site and our SEO guy recommended not to include the language in the URL for the default language (English) as it would change our homepage from domain.com/ to domain.com/en/, and our old site default language was in the base directory.
Concrete5 doesn't support this so basically I'm hoping to accomplish this with some .htaccess trickery, but am getting no where.
Concrete5 urls are domain.com/index.php/en/path/to/page, so all pages are fed off index.php. There is a rewrite rule as follows to hide the index.php from the user and make the urls pretty.
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME}/index.html !-f
#RewriteCond %{REQUEST_FILENAME}/index.php !-f
#RewriteRule . index.php
I want to further add a way to add the /en/ for the server side from a url which doesn't include it. i.e.
RewriteRule ^/index.php/(.*) ^/index.php/en/$1 [L]
So I can then strip the en from the urls and the system will still work.
I've tried putting this before concrete's rewrite (without index.php), after, and multiple different combinations, but keep getting a 401 error and it's hard to diagnose the problem as it's not so easy to see the generated url.
Any help would be much appreciated as I've got to figure this out before launch.
With this recently added event in the new 5.7.4 version that is to come out sometime soon, we're able to do some interesting things with the request. One thing we can do is ensure the page at that path doesn't exist, then rewrite the request to make it look to concrete5 that the request is actually coming in to /en.
\Events::addListener('on_before_dispatch', function() {
$request = \Request::getInstance();
$page = \Page::getByPath($request->getPath()); // Get the real requested page
if ($page->isError()) { // If it doesn't exist
$path = new \Concrete\Core\Url\Components\Path($request->getPath());
$path = $path->prepend('en'); // prepend "/en" to the path, ex: "/path/to" becomes "/en/path/to"
$page = Page::getByPath($path);
if (!$page->isError) { // Make sure that this page actually exists
// This may not work, you might need to replace the actual \Request instance.
$request->setCurrentPage($page); // Set it to the requested page.
}
}
});
I really suggest that you do not do this. As described in my comments on the question, you'll run into really weird cases that will cause SEO issues and general routing issues in your site.
Edit: concrete5 version 8 includes HTTP middleware, which is a better solution to this problem.

URL rewriting without knowing page title

I currently have links at my site like this:
http://www.domain.com/locations/locationProfile.php?locationID=22
I am hoping, for SEO purposes that I could change this to something like this:
http://www.domain.com/locations/southern-maryland
"Southern Maryland" is currently pulled from a mysql db as the location name for location ID 22. Is it even possible to get this into the URL when my site structure currently utilizes the less attractive first version?
You can't use htaccess to do this for you. It's possible to use a RewriteMap that you can define in your server config (can't define it in htaccess file), but it's far easier if you just do this in your locationProfile.php script.
You can detect if the request is made with the query string using the REQUEST_URI value:
if ( $_SERVER['REQUEST_URI'] == '/locations/locationProfile.php' &&
isset($_GET['locationID'])) {
// go into DB and extract the location name then redirect
header('Location: /locations/' . $location-name);
}
Then in your htaccess file in your document root):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^locations/([^/]+)$ /locations/locationProfile.php?locationName=$1 [L,QSA]
And finally, make your php script look for the locationName parameter and server the proper page based on that instead of the ID.

Is possible redirecting without change the url in .htaccess?

I have this url:
http://localhost/search/
This returns me this file:
http://localhost/search.html
Now I want the urls with this structure:
http://localhost/search/([^/]+)/([^/]+)/([^/]+)/?
will redirect me to the search.html file too. But without changing the url.
For example with this urls:
http://localhost/search/women/23/shoes/
http://localhost/search/
http://localhost/search/man/45/shirt/
would return the same file:
http://localhost/search.html
Note: the urls of man and women does not has any existing path in the server.
Any advice or help would be appreciated. If you need more info, let me know and I'll edit the post.
RewriteEngine on
RewriteRule ^search/ /search.html
Will just work fine. Unless you explicitly request an external redirect, a RewriteRule on the same domain will not do one, thus not changing the URL visible in the browser.
if you don't need the rest of url then you can use this
RewriteEngine On
RewriteRule ^search/(.*)$ /search.html [L]
if you need to other parameters of url then let me know
edited version, Niels Keurentjes has a point if you don't need the rest of url
RewriteEngine On
RewriteRule ^search /search.html

Links don't lead to the correct page with mod_rewrite

I have just started to try and rewrite all my websites URLs, but I do not understand this. In my htaccess file I have the following code:
RewriteEngine On
RewriteBase /
RewriteRule ^tjanster/([^/.]+)/?$ tjanster.php?page=$1 [L]
So for example when I click on the link
Design
it should go to mypage.com/tjanster/design but it doesn’t it still goes to
mypage.com/tjanster/rackochskapbyggnation/tjanster.php?page=design
However, if I write mypage.com/tjanster/design directly in the URL it goes to the page.
Nope, its not working this way, but the opposite:
Design
Would lead to tjanster/rackochskapbyggnation/tjanster.php?page=design.
The one of the mod_rewrite`s ideas is to handle such non-existing URI requests and translate them to an existing ones, enabling you to prettify the URL you have or hide some specific URLs.
You'd have to experiment in PHP to figure it out, but you can also have PHP redirect to valid URLs when accessed directly.
That code may look something like this:
<?php
if (preg_match('~^/tjanster/rackochskapbyggnation/tjanster\/.php~i', $_SERVER['REQUEST_URI'])) {
if (isset($_GET['page'])) {
header('Location: /tjanster/' . $_GET['page']);
} else {
header('Location: /tjanster/');
}
exit;
}
This code looks at the REQUEST_URI variable to see if the requested URL looks like the script is being accessed directly, and if so, redirect to the nice page structure. You must also leave your Rewrite rules in place.
Try this :
RewriteRule tjanster.php?page=(.*) tjanster/$1 [L]
First param is the input uri, second how to rewrite it $1 refers to the data inside ()

Yii and Mod Rewrite: redirect to user language translated url

I'm developing a multilanguage web app with Yii.
I applied changes to hide the index.php, changed urlFormat to path and added to the url path a slug with the user language example /it/index.php /en/index.php etc...
The problem now is that I need to redirect automatically to a different url once the user chooses another language. For example:
http://localhost/~antonio/project/it/women
needs to redirect to:
http://localhost/~antonio/project/it/femme
I have been playing with htaccess with no luck at all. Here is the actual code:
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
RewriteBase /~antonio/project/
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
#My redirection code (tried a good few more to no use apart from this)
RewriteRule ^it/women$ it/femme
I would really appreciate any help on this issue, as it is driving me mad.
Thanks
Edit::
I surrendered with mod_rewrite. I found another solution by adding this code to /layout/main.php:
<?php
$onurl = Yii::app()->getRequest()->requestUri;
if ($onurl == "/~antonio/project/it/women") {
$this->redirect("/~antonio/project/it/femme");
} elseif ($onurl == "/~antonio/project/it/men") {
$this->redirect("/~antonio/project/it/uomme");
}
Rinse and repeat per combination of language/word
This might not work without setting up a proper Virtual Host (so that instead of local urls like http://localhost/~antonio/project/it/women you have nice urls like http://project1.dev). But I would do that anyway, since it makes your dev environment nicer! (Here's a place to start).
Anyway, I would try this: just leave the .htaccess file set like you normally would for "path" style urls, and then just parse a $_GET['lang'] parameter using the UrlManager? So you would have a urlManager setup like this in your config.php:
'urlManager'=>array(
'urlFormat'=>'path', // use path style parameters
'showScriptName'=>false, // get rid of index.php
'rules'=>array(
// this parses out the first chunk of url into the "lang" GET parameter
'<lang:[\w\-]+>/<controller:[\w\-]+>/<action:[\w\-]+>'=>'<controller>/<action>',
)
)
This way a url like this http://project1.dev/it/controller/action will redirect to the "action" action in your Controller like normal (controller/action), but in your action $_GET['lang'] will now have the value of "it".
I hope that helps, it's kind of a shot in the dark. I'm not sure how you are actually triggering the different languages, so a $_GET parameter might not be helpful after all.
Found a way to do this in htaccess:
RewriteCond %{REQUEST_URI} ^/~antonio/project/it/donna/shoes/(.*)$
RewriteRule ^it/donna/shoes/(.*)$ /~antonio/project/it/donna/calzature/$1 [L,R]

Resources