Htaccess handling current year plus previous years with index.php endpoint

Currently, I have a simple PHP/htaccess setup where a single index.php can take incoming url and include files based on rewritten query string:


Options +FollowSymlinks -Indexes
RewriteEngine On
# Router:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]

The above works great when my index file is at the root of the server:

http://foo.com/about/

… the above would pass ?page=about/ to my PHP script, and I’d include the “about.php” from there. Simple enough.

Here’s what I’d like to do:

http://foo.com/2012/about/
http://foo.com/2013/about/
http://foo.com/about/ (this is actually housed in the 2014 folder).
http://foo.com/2014/about/ (this will remove 2014 from URL but keep about/)

Where, at the root of my server, I have:


2012/index.php
2013/index.php
2014/index.php

… and within each folder will be the index.php file that handles requests.

Here’s the tricky part: As you can see above, I only want the current year to be removed from the URL.

What would be the best way to handle this?

Here’s what I’ve got so far (not working):


# http://stackoverflow.com/a/10427485/922323
# http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html

AddDefaultCharset utf-8
Options +FollowSymlinks -Indexes -MultiViews

RewriteEngine on

RewriteBase /

# Block access to hidden files:
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\\." - [F]

# Force trailing slash:
RewriteCond %{REQUEST_URI} /+[^\\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]

# If a request tries to access the current year directly, then redirect
# it to its canonical version:
RewriteCond %{THE_REQUEST} 2014/
RewriteRule ^2014/(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

# .. and map any non-year requests to current year:
RewriteCond %{REQUEST_URI} !201(2|3|4)/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /2014/?page=$1 [L,QSA]

# Router:
RewriteCond %{REQUEST_URI} ([0-9]{4})/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /%1/index.php?page=$1 [L,QSA]

I’ve tried a number of combinations … At first, it was my hope that I could just put sub-htaccess files inside each year folder to handle the index.php part, but that seemed to trump the rewrite rules found in the parent directory.

I feel like I’m getting close.

The above currently has two problems:

  1. The root index request doesn’t work.
  2. The /2013 and /2012 does not pass $page as a query string.

With that said, can anyone give me pointers on the best way to handle this situation?

TIA!

Your newer htaccess code (as shown in this post) doesn’t include your original root index rewrite. Did you forget to put it back in?

I copy-pasted your newer htaccess code and tested it on my machine, but the $page query string came through correctly. Is it possible there’s something else in your htaccess that we haven’t seen here?

Hi Jeff!

Thanks so much for the reply, I really appreciate it!

Your newer htaccess code (as shown in this post) doesn’t include your original root index rewrite. Did you forget to put it back in?

Doh, sorry, I should have been more clear.

When I said “The root index request doesn’t work”, what I meant to say is:

When requesting:

http://foo.com/

I get a 403 Access Forbidden message.

What I would like is to have the above URI be the index.php found in /2014/index.php.

In other words, without any rewrites, there will not be an index.php at the root. I want to use modrewrite to “fake” an index at the root (and “secretly” load index found in the current year’s folder).

I copy-pasted your newer htaccess code and tested it on my machine, but the $page query string came through correctly. Is it possible there’s something else in your htaccess that we haven’t seen here?

If it is of any help, I’ve posted my test code here:

Zip archive is here: https://github.com/mhulse/years/archive/master.zip

My goal is to have a setup where, once each year, I can duplicate a previous year’s folder, change a few settings, and have a new site ready to go. The point of having the old years accessible is for archive’s sake (each year, the copy/verbiage found in each year might change).

I probably could avoid some of this by using a database, but I’m currently just using a little bit of basic PHP and flat file includes.

I hope that makes more sense/helps. Please let me know if I can provide more information.

Thanks so much for taking the time to help! I greatly appreciate it. :slight_smile:

Looks like the non-year requests weren’t working because you were rewriting to a directory rather than a file. This should fix that.

RewriteRule ^(.*)$ /2014/[COLOR="#FF0000"]index.php[/COLOR]?page=$1 [L,QSA]

The regular year requests seem to work for me (it shows the $page as expected).

As for the root, you’d probly expect that to be handled as a non-year request, and the only reason that isn’t happening is because it fails the not-a-directory test ( / is a directory, after all). If you remove that condition, it should work.

Providing the full source was tremendously helpful! More people should do that. :slight_smile:

Jeff! Thanks! I’m updating my code with you suggested changes now. Thanks so much for the help and tips!

I’ll may be back here in a few with a few more questions. :slight_smile:

Thanks a ton!