Nice urls with symfony

Usually when working with symfony, when the time comes to deploy the application, one problem arises, the urls.

While developing a normal url could be: http://www.jnieto.org/web/index.php/articles/my_first_article

Two elements are not welcome here: index.php and web/

Index.php/

To get rid of index.php a setting must be configure in the settings.yml file from the config folder:

 
prod:
  .settings:
    no_script_name:         true
 

Now after cleaning the cache the annoying index.php is gone.

Note: Just an application can have this setting as true (more info in this regard in the symfony guide)

Web/

This can be avoided depending on the kind of hosting available. If it is a dedicated server then the solution is to change the webroot to be the actual web dir. Ok that’s the easy one, however when using a shared hosting some steps should be followed.


First add to the factories.yml file of the desire application the following code:

 
  controller:
    class:                   FrontWebController
 

Then create the class FrontWebController.class.php in the project/lib/controller folder (it could be other folder but this follows the symfony original folder structure).

The class should overwrite the method genUrl:

 
  public function genUrl($parameters = array(), $absolute = false)
  {
    $url = parent::genUrl($parameters, $absolute);
 
    if(preg_match('/\.php/', $url) ||
       preg_match('/index\.php/', $_SERVER['SCRIPT_NAME']))
 
      $url = substr($url, 0, strpos($url, 'web')).
             substr($url, strpos($url, 'web') + 4);
 
    return $url;
  }
 

This method helps the link_to’s to generate urls without the usual …/web/…

Don’t forget to clean the cache for symfony to take account of the changes.

Now copy the .htaccess file to the root folder and copy this code:

 
  Options +FollowSymLinks +ExecCGI
 
 
  RewriteEngine On
 
  # we skip all files in /web
  RewriteCond %{REQUEST_URI} ^/web/
  RewriteRule .* - [L]
 
  # we rewrite all other files with .something to /web
  RewriteCond %{REQUEST_URI} \..+$
  RewriteCond %{REQUEST_URI} !\.html$
  RewriteRule ^(.*)$ /web/$1 [L]
 
  # we check if the .html version is in /web (caching)
  RewriteRule ^$ /web/index.html [QSA]
  RewriteRule ^([^.]+)$ /web/$1.html [QSA]
  #####################################################
 
  # no, so we redirect to our front web controller
  RewriteRule ^(.*)$ /web/index.php [QSA,L]
 

This code gets rid of the undesired web/, now the site could be accessed by:

http://www.jnieto.org/articles/my_first_article

A nice and clean url.

References:

http://forum.symfony-project.org/index.php/m/102500/#msg_102500

http://groups.google.com/group/symfony-devs/browse_thread/thread/0ec9a54b46725beb?pli=1

Leave a Reply

Your email address will not be published. Required fields are marked *