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 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