A summary of data about the Ruby ecosystem.

https://github.com/judofyr/temple

Template compilation framework in Ruby
https://github.com/judofyr/temple

Keywords from Contributors

activerecord rack mvc activejob rubygems sinatra slim template-engines crash-reporting ruby-gem

Last synced: about 2 hours ago
JSON representation

Repository metadata

Template compilation framework in Ruby

README.md

Temple

test Code Climate Gem Version Yard Docs

Temple is an abstraction and a framework for compiling templates to pure Ruby.
It's all about making it easier to experiment, implement and optimize template
languages. If you're interested in implementing your own template language, or
anything else related to the internals of a template engine: You've come to
the right place.

Have a look around, and if you're still wondering: Ask on the mailing list and
we'll try to do our best. In fact, it doesn't have to be related to Temple at
all. As long as it has something to do with template languages, we're
interested: http://groups.google.com/group/guardians-of-the-temple.

Links

Overview

Temple is built on a theory that every template consists of three elements:

  • Static text
  • Dynamic text (pieces of Ruby which are evaluated and sent to the client)
  • Codes (pieces of Ruby which are evaluated and not sent to the client, but
    might change the control flow).

The goal of a template engine is to take the template and eventually compile
it into the core abstraction:

 [:multi,
   [:static, "Hello "],
   [:dynamic, "@user.name"],
   [:static, "!\n"],
   [:code, "if @user.birthday == Date.today"],
   [:static, "Happy birthday!"],
   [:code, "end"]]

Then you can apply some optimizations, feed it to Temple and it generates fast
Ruby code for you:

 _buf = []
 _buf << ("Hello #{@user.name}!\n")
 if @user.birthday == Date.today
   _buf << "Happy birthday!"
 end
 _buf.join

S-expression

In Temple, an Sexp is simply an array (or a subclass) where the first element
is the type and the rest are the arguments. The type must be a symbol and
it's recommended to only use strings, symbols, arrays and numbers as
arguments.

Temple uses Sexps to represent templates because it's a simple and
straightforward data structure, which can easily be written by hand and
manipulated by computers.

Some examples:

 [:static, "Hello World!"]

 [:multi,
   [:static, "Hello "],
   [:dynamic, "@world"]]

 [:html, :tag, "em", [:html, :attrs], [:static, "Hey hey"]]

NOTE: SexpProcessor, a library written by Ryan Davis, includes a Sexp
class. While you can use this class (since it's a subclass of Array), it's not
what Temple mean by "Sexp".

Abstractions

The idea behind Temple is that abstractions are good, and it's better to have
too many than too few. While you should always end up with the core
abstraction, you shouldn't stress about it. Take one step at a time, and only
do one thing at every step.

So what's an abstraction? An abstraction is when you introduce a new types:

 # Instead of:
 [:static, "<strong>Use the force</strong>"]

 # You use:
 [:html, :tag, "strong", [:html, :attrs], [:static, "Use the force"]]

Why are abstractions so important?

First of all, it means that several template engines can share code. Instead
of having two engines which goes all the way to generating HTML, you have two
smaller engines which only compiles to the HTML abstraction together with
something that compiles the HTML abstraction to the core abstraction.

Often you also introduce abstractions because there's more than one way to do
it. There's not a single way to generate HTML. Should it be indented? If so,
with tabs or spaces? Or should it remove as much whitespace as possible?
Single or double quotes in attributes? Escape all weird UTF-8 characters?

With an abstraction you can easily introduce a completely new HTML compiler,
and whatever is below doesn't have to care about it at all. They just
continue to use the HTML abstraction. Maybe you even want to write your
compiler in another language? Sexps are easily serialized and if you don't
mind working across processes, it's not a problem at all.

All abstractions used by Temple are documented in EXPRESSIONS.md.

Compilers

A compiler is simply an object which responds a method called #call which
takes one argument and returns a value. It's illegal for a compiler to mutate
the argument, and it should be possible to use the same instance several times
(although not by several threads at the same time).

While a compiler can be any object, you very often want to structure it as a
class. Temple then assumes the initializer takes an optional option hash:

 class MyCompiler
   def initialize(options = {})
     @options = options
   end

   def call(exp)
     # do stuff
   end
 end

Parsers

In Temple, a parser is also a compiler, because a compiler is just something
that takes some input and produces some output. A parser is then something
that takes a string and returns an Sexp.

It's important to remember that the parser should be dumb. No optimization,
no guesses. It should produce an Sexp that is as close to the source as
possible. You should invent your own abstraction. Maybe you even want to
separate the parsers into several parts and introduce several abstractions on
the way?

Filters

A filter is a compiler which take an Sexp and returns an Sexp. It might turn
convert it one step closer to the core-abstraction, it might create a new
abstraction, or it might just optimize in the current abstraction. Ultimately,
it's still just a compiler which takes an Sexp and returns an Sexp.

For instance, Temple ships with {Temple::Filters::DynamicInliner} and
{Temple::Filters::StaticMerger} which are general optimization filters which
works on the core abstraction.

An HTML compiler would be a filter, since it would take an Sexp in the HTML
abstraction and compile it down to the core abstraction.

Generators

A generator is a compiler which takes an Sexp and returns a string which is
valid Ruby code.

Most of the time you would just use {Temple::Generators::ArrayBuffer} or any of the
other generators in {Temple::Generators}, but nothing stops you from writing your
own.

In fact, one of the great things about Temple is that if you write a new
generator which turns out to be a lot faster then the others, it's going to
make every single engine based on Temple faster! So if you have any ideas,
please share them - it's highly appreciated.

Engines

When you have a chain of a parsers, some filters and a generator you can finally create your engine. Temple provides {Temple::Engine} which makes this very easy:

 class MyEngine < Temple::Engine
   # First run MyParser
   use MyParser

   # Then a custom filter
   use MyFilter

   # Then some general optimizations filters
   filter :MultiFlattener
   filter :StaticMerger
   filter :DynamicInliner

   # Finally the generator
   generator :ArrayBuffer
 end

 engine = MyEngine.new(strict: "For MyParser")
 engine.call(something)

And then?

You've ran the template through the parser, some filters and in the end a
generator. What happens next?

Temple provides helpers to create template classes for Tilt and
Rails.

 require 'tilt'

 # Create template class MyTemplate and register your file extension
 MyTemplate = Temple::Templates::Tilt(MyEngine, register_as: 'ext')

 Tilt.new('example.ext').render     # => Render a file
 MyTemplate.new { "String" }.render # => Render a string

Installation

You need at least Ruby 1.9.3 to work with Temple. Temple is published as a Ruby Gem which can be installed
as following:

 $ gem install temple

Engines using Temple

Acknowledgements

Thanks to _why for
creating an excellent template engine (Markaby) which is quite slow. That's
how I started experimenting with template engines in the first place.

I also owe Ryan Davis a lot for his excellent
projects ParserTree, RubyParser, Ruby2Ruby and SexpProcessor. Temple is
heavily inspired by how these tools work.


Owner metadata


GitHub Events

Total
Last Year

Committers metadata

Last synced: 3 days ago

Total Commits: 607
Total Committers: 39
Avg Commits per committer: 15.564
Development Distribution Score (DDS): 0.295

Commits in past year: 3
Committers in past year: 2
Avg Commits per committer in past year: 1.5
Development Distribution Score (DDS) in past year: 0.333

Name Email Commits
minad m****l@d****e 428
Magnus Holm j****r@g****m 89
Takashi Kokubun t****n@g****m 41
grosser g****l@g****m 6
Jakub Jirutka j****b@j****z 5
Keenan Brock k****n@t****t 4
Bernard Lambeau b****u@g****m 2
Akzhan Abdulin a****n@g****m 1
Jeremy Evans c****e@j****t 1
Jean Boussier j****r@g****m 1
Igor Bochkariov u****c@g****m 1
Gerjan Stokkink g****n@b****m 1
Denys Victorovich Matveev s****3@g****m 1
Daniel J Sell d****l@g****m 1
Dan McGregor 1****n 1
Igor Kapkov i****k@m****m 1
HannesG h****g@i****e 1
Guillaume FORTAINE g****e@f****m 1
Damir i****o@f****m 1
John Bolliger j****r@g****m 1
schneems r****n@g****m 1
printercu p****u@g****m 1
itzki i****h@g****m 1
hotovson p****n@g****m 1
Yusuke Nakamura y****5@g****m 1
Vít Ondruch v****h@r****m 1
Tristan O'Neil to@t****m 1
Tim Riley t****m@r****u 1
Sam Rawlins s****s@g****m 1
Pyry Jahkola p****a@i****i 1
and 9 more...

Committer domains:


Issue and Pull Request metadata

Last synced: 3 months ago

Total issues: 43
Total pull requests: 68
Average time to close issues: 11 months
Average time to close pull requests: 4 months
Total issue authors: 28
Total pull request authors: 45
Average comments per issue: 3.56
Average comments per pull request: 2.19
Merged pull request: 46
Bot issues: 0
Bot pull requests: 0

Past year issues: 2
Past year pull requests: 2
Past year average time to close issues: about 9 hours
Past year average time to close pull requests: 6 months
Past year issue authors: 2
Past year pull request authors: 1
Past year average comments per issue: 0.0
Past year average comments per pull request: 0.5
Past year merged pull request: 1
Past year bot issues: 0
Past year bot pull requests: 0

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/judofyr/temple

Top Issue Authors

  • minad (13)
  • stonean (2)
  • jeremyevans (2)
  • srghma (2)
  • bughit (1)
  • blambeau (1)
  • denisdefreyne (1)
  • bensie (1)
  • Fudoshiki (1)
  • NARKOZ (1)
  • SteveBenner (1)
  • simrb (1)
  • eloyesp (1)
  • skunkworker (1)
  • lorinrivers (1)

Top Pull Request Authors

  • k0kubun (13)
  • jirutka (4)
  • gfortaine (2)
  • m-nakamura145 (2)
  • gstokkink (2)
  • kbrock (2)
  • doits (2)
  • shreeve (2)
  • hannesg (2)
  • schneems (2)
  • zzak (1)
  • dthorpe (1)
  • nashbridges (1)
  • djsell (1)
  • blambeau (1)

Top Issue Labels

  • Ideas (3)
  • Core (1)

Top Pull Request Labels


Package metadata

gem.coop: temple

Template compilation framework in Ruby

  • Homepage: https://github.com/judofyr/temple
  • Documentation: http://www.rubydoc.info/gems/temple/
  • Licenses: MIT
  • Latest release: 0.10.4 (published 7 months ago)
  • Last Synced: 2026-02-28T11:01:11.493Z (3 days ago)
  • Versions: 46
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 224,934,671 Total
  • Docker Downloads: 516,945,022
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 0.075%
    • Downloads: 0.111%
    • Docker downloads count: 0.19%
  • Maintainers (3)
rubygems.org: temple

Template compilation framework in Ruby

  • Homepage: https://github.com/judofyr/temple
  • Documentation: http://www.rubydoc.info/gems/temple/
  • Licenses: MIT
  • Latest release: 0.10.4 (published 7 months ago)
  • Last Synced: 2026-03-01T12:33:52.666Z (2 days ago)
  • Versions: 46
  • Dependent Packages: 22
  • Dependent Repositories: 55,893
  • Downloads: 224,996,757 Total
  • Docker Downloads: 516,945,022
  • Rankings:
    • Downloads: 0.111%
    • Dependent repos count: 0.148%
    • Docker downloads count: 0.24%
    • Dependent packages count: 0.986%
    • Average: 1.276%
    • Stargazers count: 2.553%
    • Forks count: 3.618%
  • Maintainers (3)
proxy.golang.org: github.com/judofyr/temple

  • Homepage:
  • Documentation: https://pkg.go.dev/github.com/judofyr/temple#section-documentation
  • Licenses: mit
  • Latest release: v0.10.4 (published 7 months ago)
  • Last Synced: 2026-03-01T19:25:20.697Z (2 days ago)
  • Versions: 52
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Stargazers count: 2.684%
    • Forks count: 3.304%
    • Average: 6.592%
    • Dependent packages count: 9.576%
    • Dependent repos count: 10.802%
ubuntu-24.04: ruby-temple

  • Homepage: https://github.com/judofyr/temple
  • Licenses:
  • Latest release: 0.10.3-1 (published 25 days ago)
  • Last Synced: 2026-02-06T16:08:36.117Z (25 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
ubuntu-24.10: ruby-temple

  • Homepage: https://github.com/judofyr/temple
  • Licenses:
  • Latest release: 0.10.3-1 (published 22 days ago)
  • Last Synced: 2026-02-09T17:23:12.796Z (22 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
debian-13: ruby-temple

  • Homepage: https://github.com/judofyr/temple
  • Documentation: https://packages.debian.org/trixie/ruby-temple
  • Licenses:
  • Latest release: 0.10.3-2 (published 19 days ago)
  • Last Synced: 2026-02-13T13:20:15.059Z (18 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%

Dependencies

.github/workflows/test.yml actions
  • actions/checkout v2 composite
  • ruby/setup-ruby v1 composite
temple.gemspec rubygems
  • erubi >= 0 development
  • rake >= 0 development
  • rspec >= 0 development
  • tilt >= 0 development
Gemfile rubygems

Score: 31.01196812325468