frill 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -0
- data/lib/frill.rb +2 -0
- data/lib/frill/engine.rb +26 -0
- data/lib/frill/frill.rb +42 -0
- data/lib/frill/rails.rb +5 -0
- data/readme.markdown +109 -0
- data/spec/frill_spec.rb +94 -0
- metadata +74 -0
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/frill.rb
ADDED
data/lib/frill/engine.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Frill
|
4
|
+
class Engine < Rails::Engine
|
5
|
+
config.autoload_paths << "app/frills"
|
6
|
+
|
7
|
+
initializer "frill.rails_integration" do
|
8
|
+
require 'frill/rails'
|
9
|
+
end
|
10
|
+
|
11
|
+
config.to_prepare do
|
12
|
+
if Rails.env.development? && !Rails.application.config.cache_classes
|
13
|
+
Frill.reset!
|
14
|
+
|
15
|
+
Frill::Engine.force_load Dir["#{Frill::Engine.root}/app/frills/*"]
|
16
|
+
Frill::Engine.force_load Dir["#{Rails.root}/app/frills/*"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.force_load files
|
21
|
+
files.each do |f|
|
22
|
+
load f
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/frill/frill.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Frill
|
2
|
+
def self.included(base)
|
3
|
+
self.decorators << base
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.decorators
|
8
|
+
@decorators ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.reset!
|
12
|
+
@decorators = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.decorate object, context
|
16
|
+
decorators.each do |d|
|
17
|
+
object.extend d if d.frill? object, context
|
18
|
+
end
|
19
|
+
|
20
|
+
object
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def before decorator
|
25
|
+
move Frill.decorators.index(decorator)
|
26
|
+
end
|
27
|
+
|
28
|
+
def after decorator
|
29
|
+
decorator.before self
|
30
|
+
end
|
31
|
+
|
32
|
+
def first
|
33
|
+
move 0
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def move index
|
38
|
+
Frill.decorators.delete self
|
39
|
+
Frill.decorators.insert index, self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/frill/rails.rb
ADDED
data/readme.markdown
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# Frill
|
2
|
+
|
3
|
+
Simple decoration of objects for presentation. If you don't know what I'm talking
|
4
|
+
about, reading up on decorators and their role in MVC.
|
5
|
+
|
6
|
+
Out of the box integration with Rails.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Throw this in your Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem "frill"
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
(For the purposes of this tutorial, I'm going to assume you're using
|
19
|
+
`frill` inside a Rails app. Checkout the `Usage outside Rails` section
|
20
|
+
below for information about how to use this outside of a Rails app.)
|
21
|
+
|
22
|
+
Imagine you're creating a web application that includes both a
|
23
|
+
JSON API and an HTML frontend, and you've decided to always present a
|
24
|
+
timestamp as YEAR/MONTH/DAY. Furthermore, when presented in HTML, you
|
25
|
+
always want your timestamps wrapped in `<bold>` tags.
|
26
|
+
|
27
|
+
This is a perfect fit for the GoF decorator pattern.
|
28
|
+
|
29
|
+
Create a new TimestampFrill module in `app/frills/timestamp_frill`:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
module TimestampFrill
|
33
|
+
include Frill
|
34
|
+
|
35
|
+
def self.frill? object, context
|
36
|
+
object.respond_to? :created_at
|
37
|
+
end
|
38
|
+
|
39
|
+
def created_at
|
40
|
+
super.strftime "%Y/%m/%d"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
The first method `self.frill?` tells `Frill` what kind of objects this
|
46
|
+
decorator is applicable to. In our case, it's any object that responds
|
47
|
+
to `created_at`.
|
48
|
+
|
49
|
+
Next, let's create an `HtmlTimestampFrill` module:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
module HtmlTimestampFrill
|
53
|
+
include Frill
|
54
|
+
after TimestampFrill
|
55
|
+
|
56
|
+
def self.frill? object, context
|
57
|
+
object.respond_to?(:created_at) && context.request.format == "text/html"
|
58
|
+
end
|
59
|
+
|
60
|
+
def created_at
|
61
|
+
helper.content_tag :b, super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Two things to note: the `HtmlTimestampFrill` is only applicable to
|
67
|
+
objects that respond to `created_at` when presented in "html". Also, we
|
68
|
+
tell `Frill` to decorate after `TimestampFrill` is applied (so that
|
69
|
+
`super` in `created_at` returns our `TimestampFrill` response).
|
70
|
+
|
71
|
+
Next, in our controller, we need to decorate our objects with frills:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class PostsController < ApplicationController
|
75
|
+
respond_to :json, :html
|
76
|
+
|
77
|
+
def show
|
78
|
+
@article = frill Article.find(params[:id])
|
79
|
+
respond_with @article
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Notice that we've wrapped our article in a `frill`.
|
85
|
+
|
86
|
+
In your html view, you simply call `@article.created_at`:
|
87
|
+
|
88
|
+
```erb
|
89
|
+
<%= @article.created_at %>
|
90
|
+
```
|
91
|
+
|
92
|
+
The same goes for your JSON view.
|
93
|
+
|
94
|
+
## Usage outside Rails
|
95
|
+
|
96
|
+
There are really just two integrations in a Rails app: the `frill`
|
97
|
+
method inside of your controller, plus the ability to call
|
98
|
+
`ActionView::Helper` methods inside of your module methods.
|
99
|
+
|
100
|
+
To kickoff the decoration of an object outside of a Rails application,
|
101
|
+
simply call `Frill.decorate`:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
Frill.decorate my_object, my_context
|
105
|
+
```
|
106
|
+
|
107
|
+
## License
|
108
|
+
|
109
|
+
MIT.
|
data/spec/frill_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative '../lib/frill/frill'
|
2
|
+
|
3
|
+
describe Frill do
|
4
|
+
before do
|
5
|
+
Frill.reset!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".reset" do
|
9
|
+
before do
|
10
|
+
Frill.decorators << Module.new
|
11
|
+
Frill.decorators.should_not be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should wipe out all decorators" do
|
15
|
+
Frill.reset!
|
16
|
+
Frill.decorators.should be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".decorate" do
|
21
|
+
let(:object) { double :object }
|
22
|
+
let(:object_context) { double :object_context }
|
23
|
+
let(:eigenclass) { (class << object; self; end) }
|
24
|
+
|
25
|
+
let!(:applicable_module) do
|
26
|
+
Module.new do
|
27
|
+
include Frill
|
28
|
+
|
29
|
+
def self.frill? object, context
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
let!(:unapplicable_module) do
|
36
|
+
Module.new do
|
37
|
+
include Frill
|
38
|
+
|
39
|
+
def self.frill? object, context
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should decorate the object with any applicable modules" do
|
46
|
+
Frill.decorate object, object_context
|
47
|
+
|
48
|
+
eigenclass.included_modules.should include applicable_module
|
49
|
+
eigenclass.included_modules.should_not include unapplicable_module
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".included" do
|
54
|
+
let(:test_module) { double :module }
|
55
|
+
|
56
|
+
subject { Frill.decorators }
|
57
|
+
|
58
|
+
before { Frill.included test_module }
|
59
|
+
|
60
|
+
it { should include test_module }
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Frill::ClassMethods do
|
64
|
+
let(:module1) { Module.new { include Frill } }
|
65
|
+
let(:module2) { Module.new { include Frill } }
|
66
|
+
|
67
|
+
describe ".before" do
|
68
|
+
it "inserts the current module before the requested module in Frill's list of decorators" do
|
69
|
+
Frill.decorators.should == [module1, module2]
|
70
|
+
|
71
|
+
module2.before module1
|
72
|
+
Frill.decorators.should == [module2, module1]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe ".after" do
|
77
|
+
it "inserts the current module after the requested module in Frill's list of decorators" do
|
78
|
+
Frill.decorators.should == [module1, module2]
|
79
|
+
|
80
|
+
module1.after module2
|
81
|
+
Frill.decorators.should == [module2, module1]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".first" do
|
86
|
+
it "inserts the current module at the beginning of the list of Frill's decorators" do
|
87
|
+
Frill.decorators.should == [module1, module2]
|
88
|
+
|
89
|
+
module2.first
|
90
|
+
Frill.decorators.should == [module2, module1]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: frill
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Parker
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &70325001861360 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70325001861360
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70325001860160 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70325001860160
|
36
|
+
description:
|
37
|
+
email: moonmaster9000@gmail.com
|
38
|
+
executables: []
|
39
|
+
extensions: []
|
40
|
+
extra_rdoc_files: []
|
41
|
+
files:
|
42
|
+
- lib/frill/engine.rb
|
43
|
+
- lib/frill/frill.rb
|
44
|
+
- lib/frill/rails.rb
|
45
|
+
- lib/frill.rb
|
46
|
+
- VERSION
|
47
|
+
- readme.markdown
|
48
|
+
- spec/frill_spec.rb
|
49
|
+
homepage: https://github.com/moonmaster9000/frill
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.8.17
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Decorating objects for presentation. Supports Rails out of the box.
|
73
|
+
test_files:
|
74
|
+
- spec/frill_spec.rb
|