Fir

Fir is a minimalist Ruby framework for small, mostly-static sites. It provides an optimized workflow for sites where a CMS would be overkill, but static HTML would be like a return to the dark ages.

It's Rack-based, so it runs on Phusion Passenger. But even if your web host doesn't support Ruby, fear not! Fir allows you to export static HTML to a live server with a single command. That means it works with every web host that supports SSH and mod_rewrite.

Warning: Alpha Release

Fir is still in alpha. It has only been lightly tested. You may very well encounter bugs. If you do, please visit Fir's GitHub repository and tell us what happened.

Installation

sudo gem intall fir
fir my_fir_site

The second command runs the Fir generator, creating a skeleton Fir site in the directory my_fir_site.

Before we set up Passenger, let's test the site with Rackup:

cd my_fir_site
rackup config.ru -p 3000

The -p option tells Rackup which port to listen on. This can be anything you want. (Obviously, if you're already running Rails or anything else on port 3000, you need to give Rack a different port.)

Open your browser and visit:

http://localhost:3000

You should see the home page. If you don't, something is wrong. Please visit Fir's GitHub repository and tell us what happened.

Rackup is recommended when you're developing your site locally. Press ctrl-c to kill Rackup.

Now we're ready to make it work with Passenger, which you're encouraged to use in production. At this point, the instructions become a little iffy, because so much depends on your individual system (e.g. how Apache is configured, whether you can sudo). If you're on shared hosting, you'll probably need to contact support and have them perform some of these steps for you.

For now, let's assume you're on a Mac with the default Apache installation.

If you haven't done so, install Passenger. You should also read "Deploying a Rack-based Ruby application" in the Passenger Users' Guide.

In httpd.conf, add a virtual host:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /absolute/path/to/my_fir_site/public
    RackBaseURI /
    <Directory "/absolute/path/to/my_fir_site/public">
        Options Indexes FollowSymLinks
        Order Deny,Allow
        Allow from all
    </Directory>
</VirtualHost>

Make sure you edit the correct httpd.conf! Some systems may have more than one copy of Apache installed.

Check httpd.conf syntax and restart Apache:

sudo apachectl configtest
sudo apachectl graceful

That should do it.

If you can't make this work, there's a workaround: you can export your whole site to static HTML. See "Exporting to HTML" below.

Basic Usage

See the example app to get you started.

Editing the layout

Each page will be rendered inside application.html.erb in the layouts directory. (That name was chosen because it will no doubt be familiar to Rails developers.)

The current version does not support alternate layouts. Such a feature may be added in the future if there's a need.

Creating Pages

Pages live in the pages directory, or in a subdirectory thereof. If you create a page called my-page.markdown in pages, Fir will map it to this URL: http://youdomain.com/my-page. Similarly, if you create a subdirectory in pages called subdir, and put my-page.markdown in there, this URL will be used: http://youdomain.com/subdir/my-page.

Pages can have the following extensions:

.html
.html.erb
.markdown

Markdown pages get passed through ERB before the Markdown is transformed to HTML. Thus, you can make Markdown pages dynamic. Remember: ERB runs before Markdown, so whatever your ERB tags spit out will be interpreted as Markdown.

Configuring Pages

pages.yml contains all per-page configurations. Page titles, meta descriptions, and other configs can be specified there. Each page config property will be made available to the templates as an instance variable.

Mapping URLs

You can override the default URL mapping in pages.yml. Just add a path property to a page, and the page will be made available under the path you specify.

Content Management

Most of us will be perfectly happy managing content by editing the files in the pages directory. But for the sake of our clients, Fir offers another way.

Fir isn't a CMS. Instead, it exposes a minimal, RESTful API for managing content. The idea is that content should be managed with specially-designed Fir clients, rather than through Fir itself. You can see how this works by downloading the example app, booting it, and visiting /manage-content.html in your browser. The source of that page is available on GitHub.

As of yet, no Fir client exists, though one is in development. And anyone can make one.

Fir's API uses HTTP basic authentication. The users list is stored in users.yml. To create a user or change an existing user's password, run:

rake users:add user=username pass=password

Exporting HTML to a Remote Server

If your web host doesn't support Passenger, you can still enjoy (almost) all the goodness of Fir. Fir makes it dead-simple to export your entire site to static HTML on a remote server.

To make this work, you'll need rsync and ssh. Make sure they're in your path. In other words, you must be able to run rsync and ssh from the command line. You don't need to know how to use them; they just need to be installed.

Setup deploy.yml in the root directory of your Fir project. It should look something like this:

# deploy.yaml
host: example.com
user: your_username
path: /home/your_username/public_html

Now you can run this convenient Rake task to deploy a static version of your site to the server:

rake export_to_server

You can also skip deploy.yml and run the Rake task like this:

rake export_to_server [email protected]:/home/your_username/public_html

Behind the scenes, the export task accesses each page to generate the cache. It copies the cache and the rest of the public files to your server using rsync.

There's one obvious downside to this approach: you'll lose any dynamic features you may have built in, as well as Fir's admin API.

Exporting to HTML Locally

You can also export your whole site to static HTML on your local machine:

rake export dir=~/sites/exported_example

Webserver Support

Fir is designed primarily for Phusion Passenger. As a Rack-based framework, it theoretically supports Mongrel, CGI, FastCGI, and a host of others.

As of this writing, Fir has only been tested with Rackup, Passenger, and CGI. If you get Fir working with anything else, please visit Fir's GitHub repository and let us know how you did it.

By the way, using CGI in production is not recommended. CGI boots a new Fir instance on every request. Fir is a pretty lightweight framework, so the load time isn't huge, but that doesn't mean CGI is a good idea. If you understand the issues with CGI and still want to use it, go ahead and take a look at dispatch.cgi in the example site.

Unicode and Others

Fir doesn't change the character encoding of your content, so you can technically use any encoding scheme you want. That being said, UTF-8 is recommended. As always, make sure your HTML template correctly identifies the encoding scheme. (See The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets for more information.)

Don't use non-English characters in your URLs. They don't play nice with the filesystem, and they have to be percent-encoded anyway, resulting in ugly URLs. Avoid special characters other than - and _.