delegate_presenter 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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.markdown +49 -0
- data/Rakefile +1 -0
- data/delegate_presenter.gemspec +25 -0
- data/lib/delegate_presenter.rb +35 -0
- data/lib/delegate_presenter/application_controller.rb +33 -0
- data/lib/delegate_presenter/present.rb +4 -0
- data/lib/delegate_presenter/version.rb +3 -0
- data/spec/delegate_presenter_base_spec.rb +21 -0
- data/spec/spec_helper.rb +0 -0
- metadata +78 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Introduction
|
2
|
+
=================================
|
3
|
+
|
4
|
+
This gem includes a base class, `DelegatePresenter::Base` which all your presenter classes should inherit from.
|
5
|
+
|
6
|
+
So, creating a new presenter class:
|
7
|
+
|
8
|
+
class TodoPresenter < DelegatePresenter::Base
|
9
|
+
def todo_name
|
10
|
+
s("<br>", self.description)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Wait, *what* did you just do?
|
15
|
+
=================================
|
16
|
+
|
17
|
+
You mean that little s hack? That's a way to keep yourself from going sane having to `.html_escape` everything.
|
18
|
+
|
19
|
+
[See my blog article on this subject](http://rwilcox.tumblr.com/post/10546160404/presenter-pattern-rails-3-and-html-safe)
|
20
|
+
|
21
|
+
How do I get a presenter for this object I have?
|
22
|
+
=================================
|
23
|
+
|
24
|
+
Call `Present(object)`
|
25
|
+
|
26
|
+
This will look up the name of `object`'s class, then look for a class named (that name) presenter.
|
27
|
+
|
28
|
+
So, if object is a Todo instance, DelegatePresenter will look for `TodoPresenter`. It will then instantiate an object of that class (`TodoPresenter`), passing the parameter from the Present call into the constructor.
|
29
|
+
|
30
|
+
As `DelegatePresenter::Base` subclasses are just `SimpleDelegator`s at heart, this means methods that `TodoPresenter` does not know about will be passed on to (delegated to) the `Todo` instance.
|
31
|
+
|
32
|
+
So, what is DelegatePresenter, really?
|
33
|
+
================================
|
34
|
+
|
35
|
+
DelegatePresenter does two things:
|
36
|
+
|
37
|
+
1. Inherits from Ruby Standard Library's SimpleDelegator. This simple class solves many of the problems I've seen with decorators in the past. (calling object.method everywhere)
|
38
|
+
|
39
|
+
2. Makes Rails helpers available to you via the helpers method, gives you s (above) and h (your old Rails 2 friend)
|
40
|
+
|
41
|
+
3. Gives you a `record_id` method, which will return the ActiveRecord ID of the database object. Because I think it should have been this way in the first place :)
|
42
|
+
|
43
|
+
|
44
|
+
Installation
|
45
|
+
================================
|
46
|
+
|
47
|
+
1. Add me to your Gemfile
|
48
|
+
2. In your `config/application.rb`, add an autoload path for `app/presenters/`
|
49
|
+
3. Create presenters for your classes. For example: `app/presenters/todo_presenter.rb`. These classes should subclass `DelegatePresenter::Base`
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "delegate_presenter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "delegate_presenter"
|
7
|
+
s.version = DelegatePresenter::VERSION
|
8
|
+
s.authors = ["Ryan Wilcox"]
|
9
|
+
s.email = ["rwilcox@wilcoxd.com"]
|
10
|
+
s.homepage = "http://github.com/rwilcox/delegate_presenter"
|
11
|
+
s.summary = %q{A simple Superclass for your Presenters, using SimpleDelegator}
|
12
|
+
s.description = %q{Presenters are easier with delegators, and other friends}
|
13
|
+
|
14
|
+
s.rubyforge_project = "delegate_presenter"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "rails"
|
24
|
+
# s.add_runtime_dependency "rest-client"
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "delegate_presenter/version"
|
2
|
+
require 'delegate_presenter/application_controller'
|
3
|
+
require 'delegate_presenter/present'
|
4
|
+
|
5
|
+
module DelegatePresenter
|
6
|
+
class Base < SimpleDelegator
|
7
|
+
|
8
|
+
def initialize( object_to_delegate_to )
|
9
|
+
super(object_to_delegate_to)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def record_id
|
14
|
+
self.__getobj__.id
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def helpers
|
19
|
+
ApplicationController.all_helpers
|
20
|
+
end
|
21
|
+
|
22
|
+
def s(*args)
|
23
|
+
output = "".html_safe
|
24
|
+
args.each {|current_arg|
|
25
|
+
output << current_arg.html_safe
|
26
|
+
}
|
27
|
+
output
|
28
|
+
end
|
29
|
+
|
30
|
+
def h(str)
|
31
|
+
helpers.send(:h, str)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DelegatePresenter::ApplicationController
|
2
|
+
# Provide access to helper methods from outside controllers and views,
|
3
|
+
# such as in Presenter objects. Rails provides ActionController::Base.helpers,
|
4
|
+
# but this does not include any of our application helpers.
|
5
|
+
def all_helpers
|
6
|
+
@all_helpers_proxy ||= begin
|
7
|
+
# Start with just the rails helpers. This is the same method used
|
8
|
+
# by ActionController::Base.helpers
|
9
|
+
proxy = ActionView::Base.new.extend(_helpers)
|
10
|
+
|
11
|
+
# url_for depends on _routes method being defined
|
12
|
+
proxy.instance_eval do
|
13
|
+
def _routes
|
14
|
+
Rails.application.routes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Import all named path methods
|
19
|
+
proxy.extend(Rails.application.routes.named_routes.module)
|
20
|
+
|
21
|
+
# Load all our application helpers to extend
|
22
|
+
modules_for_helpers([:all]).each do |mod|
|
23
|
+
proxy.extend(mod)
|
24
|
+
end
|
25
|
+
|
26
|
+
proxy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ApplicationController
|
32
|
+
extend DelegatePresenter::ApplicationController
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#-*- tab-width: 2; indent-tabs-mode: nil; x-auto-expand-tabs: true; x-counterpart: ../../app/presenters/application_presenter.rb; x-typographers-quotes: false; -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe "DelegatePresenter::Base" do
|
6
|
+
|
7
|
+
describe "HTML building helpers" do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@ap = DelegatePresenter::Base.new(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "handles HTML elements that should not be escaped" do
|
14
|
+
@ap.s("<h1>Hi</h1>") == "<h1>Hi</h1>"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "handles an h in the middle to indicate that a particular string actually should be escaped" do
|
18
|
+
@ap.s("<blink>hello</blink>", " world ", @ap.h("<BAD TAG>")).should == "<blink>hello</blink> world <BAD TAG>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: delegate_presenter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryan Wilcox
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-20 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &82177300 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *82177300
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rails
|
27
|
+
requirement: &82177090 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *82177090
|
36
|
+
description: Presenters are easier with delegators, and other friends
|
37
|
+
email:
|
38
|
+
- rwilcox@wilcoxd.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- Gemfile
|
45
|
+
- README.markdown
|
46
|
+
- Rakefile
|
47
|
+
- delegate_presenter.gemspec
|
48
|
+
- lib/delegate_presenter.rb
|
49
|
+
- lib/delegate_presenter/application_controller.rb
|
50
|
+
- lib/delegate_presenter/present.rb
|
51
|
+
- lib/delegate_presenter/version.rb
|
52
|
+
- spec/delegate_presenter_base_spec.rb
|
53
|
+
- spec/spec_helper.rb
|
54
|
+
homepage: http://github.com/rwilcox/delegate_presenter
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project: delegate_presenter
|
74
|
+
rubygems_version: 1.8.10
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: A simple Superclass for your Presenters, using SimpleDelegator
|
78
|
+
test_files: []
|