Last Updated: February 25, 2016
·
1.665K
· zdenekdrahos

Generate .htaccess in Middleman

Writing .htaccess file manually can be exhausting because a lot of Apache directives must be duplicated. If you use Middleman for generating static websites, you can use it for .htaccess too. My rule of thumb is that any directive should be only once in .htaccess. Define source data in yml file and loop the data in htaccess template without layout.

But there is one catch. Middleman v3 automatically appends html file extension. So add dummy extension to .htaccess file and rename the file after build. I would not use html or other well known extension because minifiers or other plugins could cause unexpected errors.

Example

It's completely up to you which directives will you use. If you have existing .htaccess, then simply extract duplicated directives. Below you can see configuration for one of my website:

config.rb

# disable layout
page ".htaccess.apache", :layout => false

# rename file after build
after_build do
  File.rename 'build/.htaccess.apache', 'build/.htaccess'
end

data/htaccess.yml

web:
    domain: example.com
    url: http://www.example.com

redirect:
    /old-url.html: /new-url.html
    /another/url.html: /new/

cache:
    deflate: \\.(js|css|html|ico|png)$
    expire:
        image/png: access plus 1 month
        image/ico: access plus 1 month
        image/x-icon: access plus 1 month
        text/html: access plus 1 minute
        text/css: access plus 7 days
        application/javascript: access plus 7 days
        text/javascript: access plus 7 days

errors:
    401: "Unauthorized access"
    404: /404.html

source/.htaccess.apache.erb

# MOVE PERMANENTLY
<% data.htaccess.redirect.each do |old, new| %>
Redirect 301 <%= old %> <%= data.htaccess.web.url %><%= new %>
<% end %>

# REWRITE - redirect to www. page
RewriteEngine on
RewriteCond %{HTTP_HOST} ^<%= data.htaccess.web.domain %>$
RewriteRule (.*) <%= data.htaccess.web.url %>/$1 [R=301,L]

# ERROR DOCUMENTS
<% data.htaccess.errors.each do |code, document| %>
ErrorDocument <%= code %> <%= document %>
<% end %>

# GZIP, CACHE
AddType image/x-icon .ico

ExpiresActive on
<% data.htaccess.cache.expire.each do |type, expire| %>
ExpiresByType <%= type %> "<%= expire %>"
<% end %>

<FilesMatch "<%= data.htaccess.cache.deflate %>">
    SetOutputFilter DEFLATE
</FilesMatch>