benedikt/tempo

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Tempo [![Build Status](https://travis-ci.org/benedikt/tempo.png?branch=master)](https://travis-ci.org/benedikt/tempo) [![Dependency Status](https://gemnasium.com/benedikt/tempo.png)](http://gemnasium.com/benedikt/tempo) [![Code Climate](https://codeclimate.com/github/benedikt/tempo.png)](https://codeclimate.com/github/benedikt/tempo)

Tempo is a simple templating system based on the Handlebars syntax. It provides a safe framework to render user provided templates without affecting the security of the server they are rendered on. It is designed to be easily extendable, without relying on global state.

## Requirements

* [Ruby Language Toolkit (RLTK)](https://github.com/chriswailes/RLTK) (~> 2.2)

## Installation

Add this line to your application's Gemfile:

    gem 'tempo'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install tempo

## Usage

**Tempo is still under heavy development, so the following is mostly pseudo-code, yet.**

The simplest way to use Tempo is to use the `Tempo.render` method. Pass it a template and a context hash and it renders the template. 

```ruby
Tempo.render('This is a {{demo}}.', :demo => 'simple demo')
# => This is a simple demo.
```

In order to add custom helpers you've to create a new instance of `Tempo::Runtime` and configure it according to your needs.

```ruby
tempo = Tempo::Runtime.new do |runtime|
  runtime.partials.register(:header, '<header>{{title}}</header>')
  runtime.helpers.register(:truncate) do |input, options|
    length = options[:length]
    input[0..length]
  end
end

tempo.render('{{> header}} This is fun! {{truncate "This is a long sentence that needs to be truncated" length=20}}...', :title => 'Title here')
# => <header>Title here</header> This is fun! This is a long sente...
```


### Contexts

```ruby
class Page
  attr_accessor :title, :created_at, :user

  def to_tempo
    PageContext.new(self)
  end
end

class PageContext < Tempo::Context
  allows :title, :created_at
end

page = Page.new
page.title = 'Example'
page.created_at = Time.now
page.user = 'Benedikt'

Tempo.render('The page "{{title}}" was created at {{created_at}}', page)
# => The page "Example" was created at 2013-10-07 17:13:40 +0000

Tempo.render('The page "{{title}}" was created by "{{user}}"', page)
# => The page "Example" was created by ""
```


### Helpers

```ruby
tempo = Tempo::Runtime.new do |runtime|
  runtime.helpers.register(:random_block) do
    rand <= 0.5 ? yield : ''
  end
end

tempo.render('{{#random_block}}This is visible in 50% of the cases{{/random_block}}')
# => This is visible in 50% of the cases
```

```ruby
class FancyHelper < Tempo::Helper
  def call(arg1, arg2, options)
    if arg1 == arg2
      contents
    else
      inverse
    end
  end
end

tempo = Tempo::Runtime.new do |runtime|
  runtime.helpers.register(:fancy, FancyHelper.new)
end

rempo.render('{{#fancy 1 2}}The arguments are equal{{else}}The arguments are not equal{{/fancy}}')
# => The arguments are not equal
```


### Partials

It's possible to customize the way Tempo looks up the partials. By default it uses the `Tempo::PartialResolver` which requires you to manually register each partial.
Tempo provides a `Tempo::FilePartialResolver` which looks up the templates in the given directory on the file system. 

```ruby
tempo = Tempo::Runtime.new do |runtime|
  runtime.partials = Tempo::FilePartialResolver.new('/path/to/templates')
end
```

To further customize this, you can provide your own PartialResolver. The following example looks up the partials in the database.

```ruby
class CustomPartialResolver
  def lookup(partial)
    template = Template.find_by_name(partial)
    template ? template.content : "Partial #{partial} could not be found!"
  end
end

tempo = Tempo::Runtime.new do |runtime|
  runtime.partials = CustomPartialResolver.new
end
```


## Build Status

tempo is on [Travis CI](https://travis-ci.org/benedikt/tempo) running the specs on Ruby 1.9, Ruby 2.0, and JRuby (1.9 mode). Unfortunately, Rubinius is currently not supported.

## Known issues

See [the issue tracker on GitHub](https://github.com/benedikt/tempo/issues) for a list of known issues.

## Repository

The repository is [available on GitHub](https://github.com/benedikt/tempo). Feel free to fork it!

## Contributors and special thanks

See a [list of all contributors on GitHub](https://github.com/benedikt/tempo/contributors). Thanks a lot to everyone!

Special thanks go to:

* Kevin Garnett: For suggesting the name "Tempo"
* Gregory T. Brown: For giving away the name on RubyGems
* Joe Walnes: For helping with debugging some parser issues

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

## Copyright

Copyright (c) 2013 Benedikt Deicke. See LICENSE for details.