Bruter
Bruter is a miniature Ruby library that allows its bearer the ability to craft elegant Rack-based web applications with ease. Bruter stands on the backs of giants:
- Servers interface with Bruter -- a Rack-compatible application -- with minimal configuration
- Variably named paths are routed to their proper destination by HttpRouter
- Dynamic assets -- Sass, LESS, CoffeeScript and more -- are compiled and served by Sprockets
- Views and templates are rendered as one by Mustache
Surely under 200 lines of code without comments, Bruter is meant to be easy to understand and use. But do not underestimate Bruter's small footprint: Bruter's role lies in its ability to delegate responsibility and provide an intuitive syntax.
Example
Bruter can be found hiding in the usual places.
gem install bruter
You'll need to create a Rackup file.
# config.ru
require 'bruter'
$:.unshift File.dirname(__FILE__)
require 'app/application'
require 'app/views/hello' # Note that you need to require any files you'll reference, including views
run Application.new
Routes and asset paths are defined in a subclass of Bruter::Application
.
# app/application.rb
class Application < Bruter::Application
serve_assets 'assets' # Asset paths are relative to where the method is called
get '/hello/:name', to: 'views/hello' # Bruter will look for a Views::Hello class to render
end
View classes should subclass Bruter::Mustache
.
# app/views/hello.rb
module Views
class Hello < Bruter::Mustache
def name
params[:name]
end
end
end
Bruter's Mustache will automatically look for an accompanying template in '../templates'
relative to the view class.
# app/templates/hello.mustache
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello {{name}}!</title>
<link rel="stylesheet" href="/stylesheets/application.css">
</head>
<body>
<h1>Bruter kindly welcomes you, {{name}}!</h1>
<img src="/images/bruter.jpg">
</body>
</html>
Place 'bruter.jpg'
in 'app/assets/images'
and a stylesheet of your preferred format in 'app/assets/stylesheets'
and Sprockets will take care of the rest.
# app/assets/stylesheets/application.css.scss
body {
text-align: center
h1 { font-size: 1.25em; }
}
Bruter is a Rack application; choose any compatible server.
rackup config.ru
Routing
Routing is handled by HttpRouter. Most applications will subclass Bruter::Application
and generate routes by calling the class method :add
. The method accepts a path and a hash of options.
add(path, = {})
Most routes will want to specify a :to
option. The :to
option can be any Rack application.
add '/welcome', to: [200, {'Content-Type' => 'text/html'}, ['Welcome to Bruter.']]
Or more interestingly, it can be a string representing a Mustache view class.
add '/welcome', to: 'welcome' # Looks for Welcome
add '/hello', to: 'views/hello_there' # Looks for Views::HelloThere
The path can include named variables and globs.
add '/hello/:name', to: 'hello' # Matches '/hello/bruter' and '/hello/ted'
add '/tagged/*tags', to: 'tagged' # Matches '/tagged/web' and '/tagged/volcano/lava/dinosaurs'
Routes can be restricted to certain HTTP request methods.
add '/post/:id', to: 'posts/show', request_method: ['GET', 'HEAD']
Routes can be named in order to construct their paths at a later time.
add '/post/:id', to: 'posts/show', name: :post # In a view, calling path(:post, 5) returns '/post/5'
Variable paths can have a regex matching condition placed on them.
add '/:a-plus-:b-equals', to: 'add', matching: {a: /\d+/, b: /\d+/}
Redirects
Redirects can be added by setting a :redirect
option instead of a :to
option.
add '/old-path', redirect: '/new-path'
Static Files
Static files can be served by the router by setting a :static
option instead of a :to
option.
add '/images', static: 'app/images' # Will look for '/images/logo/large.png' in 'app/images/logo/large.png'
Convenience Methods
Bruter also provides a number of convenience methods that pass to :add
but first set their :request_method
option to correspond to the name of the method.
get(path, = {})
post(path, = {})
put(path, = {})
delete(path, = {})
head(path, = {})
(path, = {})
trace(path, = {})
get(path, = {})
Under the Hood
When a new Bruter::Application
object is instantiated, an HttpRouter
object is also instantiated and any routes added to the application class are added to the router object. This object can also be accessed directly with the :router
getter method.
app = Bruter::Application.new
app.router.add('/').to('my_view')
run app
See HttpRouter for more information.
Assets
Asset compilation and serving is handled by Sprockets. Asset paths can be added to the asset environment with the class method :serve_assets
. The method accepts a path, which is relative to the location the method is called.
# app/application.rb
class Application < Bruter::Application
serve_assets 'assets'
end
This application will compile and serve assets located in 'app/assets'
. For example, a route of /images/logo.png
will have the asset environment look for a file named 'app/assets/images/logo.png'
and compile (if necessary) and serve it. If it cannot be found, action is passed to the router.
Like with HttpRouter
, a new Sprockets::Environment
object is instantiated and any asset paths appended to it when a new Bruter::Application
object is instantiated. This environment can be accessed directly with the :assets
getter method.
app = Bruter::Application.new
app.assets.append_path('my/assets/path')
run app
See Sprockets for more information.
Rendering
Routes can be directed to Rack-compatible applications or to strings that represent Mustache view classes. When the latter occurs the application will instantiate the view class with three objects -- a Rack request object, a Rack response object, and the Router object -- and call render. The view class can simply subclass from Mustache
, but it will likely want to subclass Bruter::Mustache
, itself a subclass of Mustache
.
Bruter::Mustache
provides a few helpers. First, it tells any subclasses to look for their templates in '../template'
relative to the view file. It provides an :initialize
method that accepts the three previously named objects and then attempts to invoke :setup
if the view has defined it. It provides getter methods to access the Rack request object (:request
), the Rack response object (:response
), the Router object (:router
), the Rack env (:env
) and the params set during routing (:params
). It also defines a :path
method, which accepts the name of a named route and an optional list of arguments to construct a path string.
For more information, see Mustache.
License
Bruter is Copyright © 2011 by Ted Kimble and distributed under the MIT license; see LICENSE
for more information.