Rayo is a CMS based on lightweight Sinatra framework and Radius gem. It was inspired by Radiant, very powerful ROR-based CMS.

Caution! The project in a very early stage of development!


Install rayo gem (recommended):

sudo gem install irwi

Or clone it:

git clone git://github.com/alno/rayo

Rack application

To create basic Rayo-based application all you need is Rackup file (config.ru) with content similar to:

require '../rayo/lib/rayo.rb'

class Application < Rayo::Application

  configure do |c|
    c.content_dir = File.join( File.dirname(__FILE__), 'content' ) # Content location
    c.languages = ['en','ru'] # Supported languages


run Application

Content structure

Here we create our application by extending Rayo::Application class, set content directory location and supported languages. Content should be placed in content subdirectories similar to following scheme:

+ layouts
  + base.html
+ snippets
  + footer.html
+ pages
  + index.yml
  + index.html
  + index.sidebar.ru.html
  + index.sidebar.en.html
  + section.yml
  + section.html
  + section
    + subpage.yml
    + subpage.html

There are example layout, snippet and 3 pages: index, section and section/subpage. Index page contains additional page part sidebar, wchih is translated to English and Russian. It should be noticed what each page have corresponding .yml file. This file contains page properties which should be used in page rendering.

Generic pages

You may create generic pages which are rendered for a set of different paths. For example to create archive pages in blog you may use:

+ 2010
| + 09
|   + my-first-post.yml
|   + my-first-post.html
+ %year.yml
+ %year.html
+ %year
  + %month.yml
  + %month.html

Content formatting

Built-In Tags

Hidden pages

If a page shouldn't be listed in children of parent page you may set property hidden to true in its yml file.



Configuration options are provided in configure block in application class:

configure do |c|
  c.content_dir = File.join( File.dirname(__FILE__), 'content' ) # Content location
  c.languages = ['en','ru'] # Supported languages

Besides of these options you append your filters for processing content (after expanding radius tags):

c.add_filter 'textile' do |source|
  RedCloth.new( source ).to_html

Also, you may define modules which contain tag definitions:

module MyTags

  include Rayo::Taggable

  tag 'hello' do
    'Hello world'

  tag 'repeat' do |tag|
    number = (tag.attr['times'] || '1').to_i
    result = ''
    number.times { result << tag.expand }


And register it:

c.add_tags MyTags

Multidomain setup

Sometimes you may want to serve different domains with one application sharing layouts and snippets. Rayo has built-in support for this scenario. All you need is to create subdirectories in pages for different domains and add some lines to configure block:

To serve 'first.example.com' with pages from content/pages/first.example.com directory:

c.add_domain 'first.example.com'

To serve 'second.example.com' or 'www.second.example.com' with pages from content/pages/second directory:

c.add_domain 'second.', /^(www\.)?second\.example\.com$/

With both lines corresponding directory structure should be:

+ layouts
+ snippets
+ pages
  + first.example.com
  + second

That's all you need to build multi-domain application.


Rayo supports transparent caching of your generated pages in filesystem which is configured by one line, specifying cache directory:

c.cache_dir = 'your cache directory'

Every page after request are written to corresponding file in cache directory, so next requests will be served from there. And if you configure your web server to search for files in cache directory ruby application will not be touched at all.

For single-domain setups it may be useful to point cache_dir to the public location, so it will be served by web-server without additional configuration.

Planned features

  • Support for sites without I18n

  • Drop-in tag libary support

  • Support for pages without .yml

  • Generator which creates a set of static pages from content structure


Feel free to add yourself when you add new features.

Copyright © 2010 Alexey Noskov, released under the MIT license