Creating pretty urls or permanent links in Drupal is easy. Really easy. This functionality comes out of the box with the Path module. And by adding the contributed Pathauto module you can make your life easier by letting Drupal generate the pretty urls automatically based on some properties of your post (like the title).
But there's another way of doing this in Drupal. Drupal provides a mechanism in code by means of the custom_url_rewrite_inbound and custom_url_rewrite_outbound functions. Using these wisely may give you some performance gain. Let's see how you can use these.
Some people really don't like the www part in urls. They prefer http://example.com over http://www.example.com. They want www.exampe.com redirected to example.com.
How can we manage this in Drupal? Well, we're going to rewrite urls, so it has to be via a Drupal path or via .htaccess.
We can't use a Drupal path in this case though because Drupal paths come in to play to late in the request flow.
So we have to use .htaccess. Drupal is delivered with a .htaccess file in the root which takes care of all the url writing mumbo jumbo, some url blocking for security etc. We'll have to edit this file.
Oops! We're hacking core. Which is always bad. A better place to add this solution is in you httpd.conf file (apache) or something. But let's assume that for these few lines, you want to adjust core.
Open your root .htaccess file and look for the following lines...
# Various rewrite rules. <IfModule mod_rewrite.c> RewriteEngine on
Change this to the following...
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^(.*) http://example.com/$1 [L,R=301]
Note that we're using the 301 http code. This says that we're doing a Permanent Redirect. Don't forget to do this!
I am using the Drupal i18n module for content translation. Although it sometimes isn't as straight forward in usability as it should be, mostly there's a workaround for a specific problem.
I couldn't find one myself for a certain problem I was having with Drupal clean urls. So I decided to write a simple module for it myself.
On a typical site, you have pages like '/contact', '/help', '/faq', ... that you all want to share the same path for each language (like '/fr/contact', 'en/contact', 'nl/contact', ...). You also want to have a single access point like '/contact' that points to the right translation of that page depending on the current user language.
By default, this is not possible using the i18n module. At least, there's no great solution that I know off.
My workaround is the following. For each language I add the language prefix to the clean url. So when creating my page (or whatever other node type instance), I specify 'fr/contact' and 'en/contact' instead of '/contact'.
This works great for all language specific clean urls; 'fr/contact' points to the french version etc.
But I also want the language independent url, '/contact', to point to the translation of the page in the current language. For this, I had to write a simple module, from which the code is listed below.
This content checks all your clean urls and looks for urls that are prefixed with a language. Those urls get a menu item in the menu hook. This menu item triggers a callback which redirects the user to the page with the right translation. Problem solved!
The disadvantage of this solution is that the user isn't taken straight forward to the requested page, but is rather redirected to it. So the url changes ('/contact' becomes for example '/fr/contact'). Not a big problem for me though ;)
/**
* Implementation of hook_menu().
*/
function multilingual_path_menu($may_cache) {
$items = array();
if (!$may_cache) {
$sql = "SELECT DISTINCT SUBSTR(dst,4) as dst FROM {url_alias} WHERE ";
$languages = i18n_supported_languages();
foreach($languages as $key => $name) {
$subsql[] = "dst LIKE '".$key."/%'";
}
$sql = $sql . implode(' OR ', $subsql);
$result = db_query($sql);
while($path = db_fetch_object($result)) {
if(!drupal_lookup_path('source',$path->dst)) {
$items[] = array(
'path' => $path->dst,
'title' => '',
'callback' => 'multilingual_path_get_path',
'access' => TRUE,
'type' => MENU_CALLBACK
);
}
}
}
return $items;
}
function multilingual_path_get_path() {
drupal_goto($_GET['q']);
}
The following tip can be used in multiple scenarios (being anywhere you need custom URL rewriting and want to do this without .htaccess), but I'll illustrate it for two specific purposes.
Both of these cases can be tackled by one hook (custom_url_rewrite) in Drupal that has to be specified in the settings.php file. You can find a descent explanation of how this hook works in the Drupal API.
In the following example I rewrite all admin urls to config (and vice versa).
function custom_url_rewrite($op, $result, $path) {
if ($op == 'alias') {
if (preg_match('|^admin(/{0,1}.*)|', $path, $matches)) {
return 'config'. $matches[1];
}
}
if ($op == 'source') {
if (preg_match('|^config(/{0,1}.*)|', $path, $matches)) {
return 'admin'. $matches[1];
}
}
return $result;
}