url rewriting

How to create URL aliases in Drupal without path module

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.

Written on February 02, 2010 at 14:04, tagged as Drupal, performance, url rewriting

Lose the www part in your url

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!

Written on April 10, 2008 at 10:13, tagged as canonical url, Drupal, url rewriting

Drupal module for using the same clean url for multilple languages

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']);
}
Written on April 03, 2008 at 15:52, tagged as Drupal, i18n, modules, tips, url rewriting

Drupal custom URL rewriting - Change the admin url to enhance security

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.

  1. At our company all urls beginning with /admin are blocked from outside by a firewall for content security reasons. This sucks, because Drupal administration is done on pages with a /admin url. So we need to find a way to rewrite all of the urls to something like /config (or something else).
  2. If someone knows your site is on Drupal, this gives him some knowledge on how the site is structured. For example does he know that all administration is done on /admin. To make it harder to guess this url, we want to rename it.

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;
  
}
Written on March 10, 2008 at 15:02, tagged as administration, Drupal, security, settings, tips, url rewriting

About

drupalcoder.com is a blog on all things Drupal in specific and LAMP on OS X in general. It is maintained by Davy Van Den Bremt, a Belgian (Drupal) web developer and designer living in Ghent. The goal of this blog is to log all interesting things that have crossed the writer's path while developing Drupal sites. You can read all about Davy's professional activities on his LinkedIn profile. If you want to get in touch, use the contact form.