frill 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,2 @@
1
+ require 'frill/frill'
2
+ require 'frill/engine' if defined? Rails
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ class ActionController::Base
2
+ def frill object
3
+ Frill.decorate object, self
4
+ end
5
+ end
@@ -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.
@@ -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