viewtastic 0.1.0 → 0.1.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.
@@ -0,0 +1,82 @@
1
+ # Viewtastic #
2
+
3
+
4
+ ## Installation ##
5
+
6
+ Install the gem
7
+
8
+ gem install viewtastic
9
+
10
+ Load the gem in your `environment.rb` file
11
+
12
+ config.gem "viewtastic"
13
+
14
+ ## Usage ##
15
+
16
+ My presenters go into the `app/presenters` directory of the application so this is added to the load_path in Rails by default by Viewtastic.
17
+
18
+ ### Presenters ###
19
+
20
+ A Presenter inherits from `Viewtastic::Base` and should use the `presents` method to declare presented objects.
21
+
22
+ class CommentPresenter < Viewtastic::Base
23
+ presents :comment
24
+ end
25
+
26
+ This gives you several 'magic' methods:
27
+
28
+ * All attributes of comment with the prefix 'comment'. For instance: `comment_body`, `comment_post`, `comment_created_at`.
29
+ * `comment_dom_id` is the same as calling `dom_id(comment)` in a view.
30
+
31
+ If you want to skip the prefix and just have the attribute name, you can declare:
32
+
33
+ presents :comment => [:body, :created_at]
34
+
35
+ and you get `presenter.body` and `presenter.created_at`.
36
+
37
+
38
+ Assuming you have a `Comment` model and your controller has a helper method `current_user` that returns the user currently logged in, you could make the following presenter to help in presenting products.
39
+
40
+ class CommentPresenter < Viewtastic::Base
41
+ presents :comment
42
+
43
+ def dom_id
44
+ comment_dom_id
45
+ end
46
+
47
+ def owner?
48
+ controller.current_user.comments.include?(comment)
49
+ end
50
+
51
+ def links
52
+ returning([]) do |links|
53
+ links << link_to("Edit", [:edit, comment]) if owner?
54
+ links << link_to("Reply", [:new, :comment]) if controller.current_user
55
+ end
56
+ end
57
+ end
58
+
59
+ ### Convenience ###
60
+
61
+ `each_with_presenter` is available on any `Array`, and it is designed to reuse a single Presenter instance and pass every element in the array as the presented object.
62
+
63
+ In your view (maybe `posts/show.html.erb`):
64
+
65
+ <ul>
66
+ <% @post.comments.each_with_presenter(CommentPresenter, :comment) do |comment| %>
67
+ <li id="<%= comment.dom_id %>">
68
+ <%= comment.body %>
69
+ <%= comment.links %>
70
+ </li>
71
+ <% end %>
72
+ </ul>
73
+
74
+ ## Credits ##
75
+
76
+ * [ActivePresenter](http://github.com/giraffesoft/active_presenter) was the inspiration for this project and some of the presenter code was used from ActivePresenter.
77
+ * [Authlogic](http://github.com/binarylogic/authlogic) -- the Authlogic activation code is used to activate Viewtastic on each request.
78
+
79
+ ## License ##
80
+
81
+
82
+ Copyright (c) 2009 Istvan Hoka, released under the MIT license
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ Rails.configuration.load_paths << "app/presenters"
@@ -1,4 +1,8 @@
1
1
  class Array
2
+ # Wrap each element in the Array with a presenter specified by @presenter_class@ and
3
+ # assigned as the model for @object_name@.
4
+ # @presenter_options@ are set once on the initial presenter instance.
5
+ #
2
6
  def each_with_presenter(presenter_class, object_name, presenter_options={}, &block)
3
7
  presenter = presenter_class.new(presenter_options)
4
8
  each do |object|
@@ -1,3 +1,7 @@
1
1
  require File.dirname(__FILE__) + "/viewtastic/activation"
2
2
  require File.dirname(__FILE__) + "/viewtastic/base"
3
3
  require File.dirname(__FILE__) + "/duck_punches/array/each_with_presenter"
4
+
5
+ module Viewtastic
6
+ VERSION = "0.1.1"
7
+ end
@@ -1,7 +1,7 @@
1
1
  module Viewtastic
2
2
  module Activation
3
3
  # Lets Viewtastic know about the controller object via a before filter, AKA "activates" viewtastic.
4
- # Borrowed from Viewtastic.
4
+ # Borrowed from Authlogic.
5
5
  #
6
6
  def self.included(klass) # :nodoc:
7
7
  if defined?(::ApplicationController)
@@ -1,101 +1,127 @@
1
- class Viewtastic::Base
2
- include ActionView::Helpers::UrlHelper
3
- include ActionView::Helpers::TextHelper
4
- include ActionView::Helpers::TagHelper
1
+ module Viewtastic
2
+ # Base class for presenters. See README.md for usage.
3
+ #
4
+ class Base
5
+ include ActionView::Helpers::UrlHelper
6
+ include ActionView::Helpers::TextHelper
7
+ include ActionView::Helpers::TagHelper
8
+
9
+ class_inheritable_accessor :presented
10
+ self.presented = []
5
11
 
6
- class_inheritable_accessor :presented
7
- self.presented = []
12
+ delegate :protect_against_forgery?,
13
+ :request_forgery_protection_token,
14
+ :form_authenticity_token,
15
+ :dom_id,
16
+ :to => :controller
8
17
 
9
- delegate :protect_against_forgery?,
10
- :request_forgery_protection_token,
11
- :form_authenticity_token,
12
- :dom_id,
13
- :to => :controller
14
-
15
- class << self
16
- def presents(*types)
17
- types_and_attributes = types.extract_options!
18
+ class << self
19
+ # Indicates which models are to be presented.
20
+ #
21
+ # class CommentPresenter < Viewtastic::Base
22
+ # presents :comment, :post
23
+ # end
24
+ #
25
+ # If you want to delegate messages to models without prefixing them with the model name, specify them in an Array:
26
+ #
27
+ # class PresenterWithTwoAddresses < ActivePresenter::Base
28
+ # presents :post, :comment => [:body, :created_at]
29
+ # end
30
+ #
31
+ def presents(*types)
32
+ types_and_attributes = types.extract_options!
18
33
 
19
- types_and_attributes.each do |name, delegates|
20
- attr_accessor name
21
- presented << name
22
- delegates.each do |msg|
23
- delegate msg, :to => name
34
+ types_and_attributes.each do |name, delegates|
35
+ attr_accessor name
36
+ presented << name
37
+ delegates.each do |msg|
38
+ delegate msg, :to => name
39
+ end
24
40
  end
25
- end
26
41
 
27
- attr_accessor *types
28
- self.presented += types
42
+ attr_accessor *types
43
+ self.presented += types
29
44
 
30
- presented.each do |name|
31
- define_method("#{name}_dom_id") do |*args|
32
- send(:dom_id, send(name), *args)
45
+ presented.each do |name|
46
+ define_method("#{name}_dom_id") do |*args|
47
+ send(:dom_id, send(name), *args)
48
+ end
33
49
  end
34
50
  end
35
- end
36
51
 
37
- def controller=(value)
38
- Thread.current[:viewtastic_controller] = value
39
- end
52
+ def controller=(value) #:nodoc:
53
+ Thread.current[:viewtastic_controller] = value
54
+ end
40
55
 
41
- def controller
42
- Thread.current[:viewtastic_controller]
43
- end
56
+ def controller #:nodoc:
57
+ Thread.current[:viewtastic_controller]
58
+ end
44
59
 
45
- def activated?
46
- !controller.nil?
60
+ def activated? #:nodoc:
61
+ !controller.nil?
62
+ end
47
63
  end
48
- end
49
64
 
50
- def initialize(*values)
51
- keys_and_values = values.extract_options!
65
+ # Accepts arguments in two forms. If you had a CommentPresenter that presented a Comment model and a Post model, you would write the follwoing:
66
+ #
67
+ # 1. CommentPresenter.new(:comment => Comment.new, :post => @post)
68
+ # 2. CommentPresenter.new(Comment.new, @post) - it will introspect on the model's class; the order is not important.
69
+ #
70
+ # You can even mix the two:
71
+ # CommentPresenter.new(Comment.new, :post => @post)
72
+ #
73
+ def initialize(*values)
74
+ keys_and_values = values.extract_options!
52
75
 
53
- keys_and_values.each do |name, instance|
54
- send("#{name}=", instance)
55
- end
76
+ keys_and_values.each do |name, instance|
77
+ send("#{name}=", instance)
78
+ end
56
79
 
57
- values.each do |value|
58
- send("#{value.class.name.underscore}=", value)
80
+ values.each do |value|
81
+ send("#{value.class.name.underscore}=", value)
82
+ end
59
83
  end
60
- end
61
84
 
62
- def method_missing(method_name, *args, &block)
63
- if method_name.to_s =~ /_(path|url)$/
64
- # Delegate all named routes to the controller
65
- controller.send(method_name, *args)
66
- elsif presented_attribute?(method_name)
67
- delegate_message(method_name, *args, &block)
68
- else
69
- super
85
+ def method_missing(method_name, *args, &block)
86
+ if method_name.to_s =~ /_(path|url)$/
87
+ # Delegate all named routes to the controller
88
+ controller.send(method_name, *args)
89
+ elsif presented_attribute?(method_name)
90
+ delegate_message(method_name, *args, &block)
91
+ else
92
+ super
93
+ end
70
94
  end
71
- end
72
-
73
- def controller
74
- self.class.controller
75
- end
76
95
 
77
- protected
78
- def delegate_message(method_name, *args, &block)
79
- presentable = presentable_for(method_name)
80
- send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
96
+ # The current controller performing the request is accessible with this.
97
+ #
98
+ def controller
99
+ self.class.controller
81
100
  end
101
+
102
+ protected
103
+ def delegate_message(method_name, *args, &block) #:nodoc:
104
+ presentable = presentable_for(method_name)
105
+ send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
106
+ end
82
107
 
83
- def presentable_for(method_name)
84
- presented.sort_by { |k| k.to_s.size }.reverse.detect do |type|
85
- method_name.to_s.starts_with?(attribute_prefix(type))
108
+ def presentable_for(method_name) #:nodoc:
109
+ presented.sort_by { |k| k.to_s.size }.reverse.detect do |type|
110
+ method_name.to_s.starts_with?(attribute_prefix(type))
111
+ end
86
112
  end
87
- end
88
113
 
89
- def presented_attribute?(method_name)
90
- p = presentable_for(method_name)
91
- !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
92
- end
114
+ def presented_attribute?(method_name) #:nodoc:
115
+ p = presentable_for(method_name)
116
+ !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
117
+ end
93
118
 
94
- def flatten_attribute_name(name, type)
95
- name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
96
- end
119
+ def flatten_attribute_name(name, type) #:nodoc:
120
+ name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
121
+ end
97
122
 
98
- def attribute_prefix(type)
99
- "#{type}_"
100
- end
123
+ def attribute_prefix(type) #:nodoc:
124
+ "#{type}_"
125
+ end
126
+ end
101
127
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: viewtastic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Istvan Hoka
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-30 00:00:00 +02:00
12
+ date: 2009-12-01 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -21,15 +21,16 @@ extensions: []
21
21
 
22
22
  extra_rdoc_files:
23
23
  - LICENSE
24
- - README
24
+ - README.md
25
25
  files:
26
26
  - LICENSE
27
+ - init.rb
27
28
  - lib/duck_punches/array/each_with_presenter.rb
28
29
  - lib/viewtastic.rb
29
30
  - lib/viewtastic/activation.rb
30
31
  - lib/viewtastic/base.rb
31
32
  - lib/viewtastic/test_case.rb
32
- - README
33
+ - README.md
33
34
  has_rdoc: true
34
35
  homepage: http://github.com/ihoka/viewtastic
35
36
  licenses: []
data/README DELETED
@@ -1,13 +0,0 @@
1
- Viewtastic
2
- ==========
3
-
4
- Introduction goes here.
5
-
6
-
7
- Example
8
- =======
9
-
10
- Example goes here.
11
-
12
-
13
- Copyright (c) 2009 [name of plugin creator], released under the MIT license