X Marks the Spot

random commentary on life, the universe, and anything

WordPress, pretty permalinks, and 404s (part 2)

| 0 comments

As I noted back in September 2017, I switched from Rackspace to Amazon Lightsail for my personal website as well as for a learning management system I run for Harbor-UCLA Pediatrics.

I’m using apache virtual hosts run both in separate subdirectories. One problem I had, but didn’t have time to fix (and then forgot about), was that turning on pretty permalinks in WordPress broke the learning management system. I knew two things: 1) it was probably a .htaccess issue and 2) my VirtualHost config was probably making a mess of things.

So why now? I have this lovely short domain (fu.fyi) doing nothing, I thought I’d use it as a custom URL shortener through bit.ly. I can set a default 404 for bad links in bit.ly so I thought I’d just use the themed WP one. But then I realized that the 404 being shown was the default apache 404 page. Which meant that I had to figure out why missing pages were not being passed to the WP stack. Which meant fixing .htaccess and httpd.conf.

Sources:
Giving WordPress Its Own Directory
This is the .htaccess code in WordPress. Can someone explain how it works?
A really lovely online .htaccess checker: https://htaccess.madewithlove.be/

The WP default .htaccess is pretty straightforward.

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

What they don’t tell you is that you break things when you duplicate RewriteRules in both VirtualHost configs and .htaccess. So cleaning httpd.conf up:

# lms hosting
<VirtualHost *:80>
   ServerName lms.domain2.com
# redirect all HTTP traffic to HTTPS
   RewriteEngine on
   RewriteCond %{SERVER_NAME} =lms.domain2.com
   RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
   ServerName lms.domain2.com
   DocumentRoot "/var/www/html/lms"
   <Directory "/var/www/html/lms">
      Options -Indexes +FollowSymLinks
      Require all granted
   </Directory>
   Include /etc/letsencrypt/options-ssl-apache.conf
   SSLCertificateFile /etc/letsencrypt/live/domain1.com/fullchain.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
</VirtualHost>

And adding a catch-all to .htaccess before the WP default:


# Turn on rewrites
RewriteEngine On

# Ruleset 1 - rewrite URI to wordpress subdir
# apply to URLs in this domain
RewriteCond %{HTTP_HOST} ^(www.)?fuweb.com$
# Don't apply (!) to URI with this subdirectory in the path
RewriteCond %{REQUEST_URI} !^/fuweb/
# Don't apply (!) to URLs that go to existing files (-f) or folders (-d)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Take (everything), call it $1, and remap URI to include /subdir
# ^ = beginning anchor
# (.*) = . [single character] * [wildcard]
# $ = end anchor
RewriteRule ^(.*)$ /fuweb/$1

# Ruleset 2 - rewrite any URI paths to wordpress index.php
# apply to URLs in this domain
RewriteCond %{HTTP_HOST} ^(www.)?fuweb.com$
# if the URI has a / then send to index.php
RewriteRule ^(/)?$ fuweb/index.php [L] 


And the best thing? I actually understand .htaccess better now.

Oh yeah. And it works.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.