Zack
Zack

Reputation: 1703

Forcing directory slashes on virtual directories with htaccess

I understand how to add directory slashes to actual directories, but I need to add trailing slashes on to virtual directories – so that, when a user visits example.com/website/blog/entries (where /blog & /entries are both virtual directories), the URL address would physically change to: example.com/website/blog/entries/

Here is my current working htaccess code that works for converting fake/virtual directories into parameters for my php script:

RewriteRule ^/?([a-zA-Z_\-/.]+)$ index.php?file=$1 [L,QSA]  

This RewriteRule makes example.com/website/blog/entries/ look like example.com/website/index.php?file=blog/entries/ to PHP only, not the user.

Here are some of the Rewrite Rules I have attempted to make work with no avail:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ %{REQUEST_URI}$1/ [L,R=301]

# -----------------------------------------------

RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^.+/$ %1 [R=301,L]

I believe the problem is because my current regex that converts virtual directories into a parameter looks for the directory names starting with "/", so when the site is installed not in the root folder ("/"), or if there is not a trailing slash, it redirects to something completely wrong. I can't write the folder path anywhere in my htaccess file, because the path will constantly be changing. For example, I can't use something like:

RewriteRule ^(.*)$ http://localhost:8888/project/$1/ [L,R=301]

Is there a way to force trailing slashes on real, and virtual directories, BEFORE converting the virtual directories into PHP parameters?

Upvotes: 2

Views: 1569

Answers (1)

Kamil Šrot
Kamil Šrot

Reputation: 2221

Something like the following should do what you need:

RewriteEngine On

# Put here the URL where .htaccess is located
RewriteBase /project/

# Redirect virtual URLs w/o trailing slash to URL with it
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*[^/])$ $1/ [R=301,QSA,L]

# pass virtual URLs into index.php as file argument
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([a-zA-Z_\-/.]+)$ index.php?file=$1 [L,QSA]

The rules are processed in the order as they appear in the config, thus the redirect is done before passing the data into index.php

Here is the version w/o using RewriteBase with hardcoded part of URL:

RewriteEngine On

# Redirect virtual URLs w/o trailing slash to URL with it
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.*[^/])$
RewriteRule .* %1/ [R=301,QSA,L]

# pass virtual URLs into index.php as file argument
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/?([a-zA-Z_\-/.]+)$
RewriteRule .* index.php?file=%1 [L,QSA]

Upvotes: 1

Related Questions