Noumenon
I did have a description of where the name Noumenon came from here, but it doesn't actually fit that well. Maybe I'll
come up with a better reason for th name choice some day.
What is This Thing?
Noumenon is a web application based on Sinatra for constructing dynamic websites which use a Git repository
for storing all content. It's designed to allow technical and non-technical teams to collaborate on development and
populate of a content management system using the tools they are most comfortable with.
In the case of developers (and some designers) that's version control and text editors, while in the case of content
editors thats more likely to be a web interface.
## Getting Started
If you want to skip the theory, and get on with the fun bit, follow these steps:
$ gem install noumenon thin bundler
$ noumenon my_site
$ cd my_site
$ bundle install
$ thin start
You're basic Noumenon site will be running at http://localhost:3000/ now. If you want to put it on the internet it should
work straight out of the box on Heroku.
How it Works
Noumenon splits your site into three parts:
Themes
Themes define how your content should be presented, and can provide templates and assets. You can load a theme from any
filesystem path in your config.ru file. In the near future Ruby Gem based themes will also be supported.
Assets
Assets such as images, stylesheets, and javascripts are placed in the "assets" directory, and are accessible from your
application at http://example.org/themes/Theme Name/asset.png. The URL structure directly matches the directory structure
of your assets directory.
Templates
The core of a theme is the templates it provides. Each template can list the fields that it supports, and mark some or all
of them as being required. Templates also include a Liquid template which is used to transform the provided fields into a
web page.
Templates should be placed in a "templates" sub-directory within your theme, and end with the extension .nou.html
title:
required: true
label: "Page title"
subtitle:
required: false
body:
required: true
type: "text"
---
<h1>{{ title }}</h1>
{% if subtitile %}
<h2>{{ subtitle }}</h2>
{% endif %}
{{ body }}
Currently the "label" and "type" attributes on a field are only present for documentation purposes, but they will be used in
the future to automatically build the content management interface used by content editors to publish pages, so it's probably
worth taking the time to include them.
If not specified the type defaults to "string", the label to a capitalised version of the name, and required to false.
Any fields provided to a template which aren't specified will still be available in the Liquid template part.
Templates are written using Liquid, and so all the standard tags and filters
are available, as well as the ones documented at Noumenon::Template::CoreTags.
Layouts
Layouts are used to wrap a piece of content with the overall look and feel of your website, and are provided with a single field
"content" containing the rendered content, along with any fields that were specified on the page being rendered.
Unless otherwise specified the layout "default" will be used, which is loaded from the path layouts/default.nou.html within your
theme. To specify a different layout set the "layout" field on your content item.
content:
required: true
type: "text"
---
<html>
<head>
<link rel="stylesheet" href="/themes/example_theme/styles.css">
<title>Enormicorp</title>
</head>
<body>
<h1>Enormicorp</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<section id="content">
{{ content }}
</section>
<footer>Copyright © 2011, Enormicorp Plc.</footer>
</body>
</html>
### A Content Repository
The site's content is stored within a repository. Each piece of content is represented by a set of key/value pairs, something
like this:
template: team_member
name: Jon Wood
position: Head Honcho of Awesomeness
description: Do you need a description after a position like that?
Currently the only available content repository uses YAML files to store your content, but shortly a MongoDB one will be created,
and the API for content repositories is simple enough that just about any datastore could be used if you want to implement an
adapater for it.
### An Asset Repository
The asset repository is used to store arbitrary files, such as images to embed within pages.
Any uploaded assets can usually be accessed from /assets/path/to/image.jpg, although in some cases it may be quicker to access them
directly. To get the correct URL for an asset use the {% asset /path/to/image.jpg %}
template tag, which will return the correct
URL.
### Applications
If part of your site requires something other then rendering a piece of content within a static template then you can use a
custom URL handler to provide that part of the site. In this example we'll provide a basic contact form.
The ContactForm Handler
class Noumenon::Applications::ContactForm < Noumenon::Core
def initialize(options = {})
@to = options[:to]
end
get '/' do
Noumenon.theme.template("templates/contact/form.html")
end
post '/send' do
require 'pony'
Pony.send :to => @to, :body => params[:body], :from => params[:from]
Noumenon.theme.template("templates/contact/thanks.html").render(body: params[:body], from: params[:from])
end
end
The Content item
To mount an application you need to put a content item in the tree where you want it, so in this example we'll put this at "/contact":
type: application
application: Noumenon::Applications::ContactForm
to: info@example.org
Make sure you've loaded the file that defines Noumenon::Applications::ContactForm.
Getting Help and Contributing
If you're using Noumenon I'd love to know about it, especially if you're having trouble, since my aim is to make creating a site based
on Noumenon as simple as possible. The best way to get in touch is to open an issue at http://github.com/Noumenon/noumenon/issues.
If you'd like to contribute fork this repository, and then submit a pull request when you're done. Please make sure to include some tests
so that your feature doesn't get broken in the future.
There are full API docs available at http://rubydoc.info/gems/noumenon/ which are generated whenever a new version is published.
## License
Noumenon is released under the MIT license by Blank Pad Development.