Rack::Component
Like a React.js component, a Rack::Component implements a render method that
takes input data and returns what to display.
You can combine Components to build complex features out of simple, easily testable units.
Installation
Add this line to your application's Gemfile:
gem 'rack-component', require: 'rack/component'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rack-component
API Reference
Please see the YARD docs on rubydoc.info
Usage
Subclass Rack::Component and #call it:
require 'rack/component'
class Useless < Rack::Component
end
Useless.call #=> the output Useless.new.render
The default implementation of #render is to yield the component instance to
whatever block you pass to Component.call, like this:
Useless.call { |instance| "Hello from #{instance}" }
#=> "Hello from #<Useless:0x00007fcaba87d138>"
Useless.call do |instance|
Useless.call do |second_instance|
" <h1>Hello from \#{instance}</h1>\n <p>And also from \#{second_instance}\"</p>\n HTML\n end\nend\n# =>\n# <h1>Hello from #<Useless:0x00007fcaba87d138></h1>\n# <p>And also from #<Useless:0x00007f8482802498></p>\n"
Implement #render or add instance methods to make Components do work
Peruse the specs for examples of component chains that handle data fetching, views, and error handling in Sinatra and raw Rack.
Here's a component chain that prints headlines from Daring Fireball’s JSON feed:
require 'rack/component'
# Make a network request and return the response
class Fetcher < Rack::Component
require 'net/http'
def initialize(uri:)
@response = Net::HTTP.get(URI(uri))
end
def render
yield @response
end
end
# Parse items from a JSON Feed document
class JSONFeedParser < Rack::Component
require 'json'
def initialize(data)
@items = JSON.parse(data).fetch('items')
end
def render
yield @items
end
end
# Render an HTML list of posts
class PostsList < Rack::Component
def initialize(posts:, style: '')
@posts = posts
@style = style
end
def render
" <ul style=\"\#{@style}\">\n \#{@posts.map(&ListItem).join}\"\n </ul>\n HTML\n end\n\n ListItem = ->(post) { \"<li>\#{post['title']}</li>\" }\nend\n\n# Fetch JSON Feed data from daring fireball, parse it, render a list\nFetcher.call(uri: 'https://daringfireball.net/feeds/json') do |data|\n JSONFeedParser.call(data) do |items|\n PostsList.call(posts: items, style: 'background-color: red')\n end\nend\nend\n#=> A <ul> full of headlines from Daring Fireball\n\n"
Development
After checking out the repo, run bin/setup to install dependencies. Then, run
rake spec to run the tests. You can also run bin/console for an interactive
prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To
release a new version, update the version number in version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push
git commits and tags, and push the .gem file to
rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/chrisfrank/rack-component.
License
MIT