1

I am trying to create a semi-serverless SPA w/ a blog but want to have "RESTful" URLs. I have the following .htaccess commands doing the job--in combination with JavaScript History API; but, wondering if I can simplify it with regex or RewriteEngine. Hopefully this is just a "code golf" question but hoping to turn the following sequence of .htaccess commands into a one-liner. Is this possible without server-side code?

enter image description here

The regex I've tried so far is as follows:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Redirect 301  "/blog" "/?page=blog"
RewriteRule ^blog/([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$ /?page=blog&month=$1&day=$2&year=$3 [L]

However, I keep landing at /blog instead of e.g., /blog/1/1/2010.

2 Answers 2

2

Yes, you can simplify your .htaccess rules using a single RewriteRule with conditions, and you don’t need server-side code for this if you're just rewriting URLs for a single-page application (SPA) using the History API.

Here’s a cleaner one-liner version using RewriteEngine and regex:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$ /?page=blog&month=$1&day=$2&year=$3 [QSA,L]

Explanation:

  • RewriteCond lines ensure that the rule only applies if the requested file or directory doesn't exist.

  • The RewriteRule matches /blog/1/1/2010 and rewrites it to /index.php?page=blog&month=1&day=1&year=2010.

  • [QSA,L] ensures query strings are appended and stops further rewriting.

You can remove the Redirect 301 "/blog" "/?page=blog" line if you want /blog to also be handled by the SPA and rewritten similarly.

Sign up to request clarification or add additional context in comments.

Comments

2

So you could use quite simple regex:

(?:^|\/)([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)$

It uses (?:^|\/) - to match either start of string ^ or / ([^\/]+) - match one or more characters other than / (this will capture all wanted parts)

Then it is repeated 4 times, in order to capture each part:

  • first is page
  • second is day
  • third is month
  • fourth is year.

For that we need also replacement pattern:

\/\?page=$1&day=$2&month=$3&year=$4

Regex fiddle

And now based on this SO post you can define your rules

RewriteCond %{REQUEST_FILENAME} (?:^|\/)([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)$
RewriteRule \/\?page=%1&day=%2&month=%3&year=%4

Only thing to double check here is if you need to escape / character with backslash \ or you can just use / instead of \/.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.