Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added gemspec, some documentation, license.

  • Loading branch information...
commit fa62efea6699b4ed1c0e7f5f80d9ec6733b32769 1 parent 2265b2a
@ihoka authored
View
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2009 Istvan Hoka
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
View
13 README
@@ -1,13 +0,0 @@
-Viewtastic
-==========
-
-Introduction goes here.
-
-
-Example
-=======
-
-Example goes here.
-
-
-Copyright (c) 2009 [name of plugin creator], released under the MIT license
View
81 README.md
@@ -0,0 +1,81 @@
+# Viewtastic #
+
+
+## Installation ##
+
+Install the gem
+
+ gem install viewtastic
+
+Load the gem in your `environment.rb` file
+
+ config.gem "viewtastic"
+
+## Usage ##
+
+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.
+
+### Presenters ###
+
+A Presenter inherits from `Viewtastic::Base` and should use the `presents` method to declare presented objects.
+
+ class CommentPresenter < Viewtastic::Base
+ presents :comment
+ end
+
+This gives you several 'magic' methods:
+* All attributes of comment with the prefix 'comment'. For instance: `comment_body`, `comment_post`, `comment_created_at`.
+* `comment_dom_id` is the same as calling `dom_id(comment)` in a view.
+
+If you want to skip the prefix and just have the attribute name, you can declare:
+
+ presents :comment => [:body, :created_at]
+
+and you get `presenter.body` and `presenter.created_at`.
+
+
+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.
+
+ class CommentPresenter < Viewtastic::Base
+ presents :comment
+
+ def dom_id
+ comment_dom_id
+ end
+
+ def owner?
+ controller.current_user.comments.include?(comment)
+ end
+
+ def links
+ returning([]) do |links|
+ links << link_to("Edit", [:edit, comment]) if owner?
+ links << link_to("Reply", [:new, :comment]) if controller.current_user
+ end
+ end
+ end
+
+### Convenience ###
+
+`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.
+
+In your view (maybe `posts/show.html.erb`):
+
+ <ul>
+ <% @post.comments.each_with_presenter(CommentPresenter, :comment) do |comment| %>
+ <li id="<%= comment.dom_id %>">
+ <%= comment.body %>
+ <%= comment.links %>
+ </li>
+ <% end %>
+ </ul>
+
+## Credits ##
+
+* [ActivePresenter](http://github.com/giraffesoft/active_presenter) was the inspiration for this project and some of the presenter code was used from ActivePresenter.
+* [Authlogic](http://github.com/binarylogic/authlogic) -- the Authlogic activation code is used to activate Viewtastic on each request.
+
+## License ##
+
+
+Copyright (c) 2009 Istvan Hoka, released under the MIT license
View
17 Rakefile
@@ -9,3 +9,20 @@ Spec::Rake::SpecTask.new(:spec) do |t|
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
t.spec_files = FileList['spec/**/*_spec.rb']
end
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = "viewtastic"
+ gem.summary = "Presenter plugin for Ruby on Rails"
+ gem.email = "istvan.hoka@gmail.com"
+ gem.homepage = "http://github.com/ihoka/viewtastic"
+ gem.authors = ["Istvan Hoka"]
+
+ gem.files = FileList['lib/**/*.rb', 'LICENSE']
+ gem.test_files = []
+ end
+ Jeweler::GemcutterTasks.new
+rescue LoadError
+ puts "Jeweler not available. Install it with: gem install jeweler"
+end
View
4 lib/duck_punches/array/each_with_presenter.rb
@@ -1,4 +1,8 @@
class Array
+ # Wrap each element in the Array with a presenter specified by @presenter_class@ and
+ # assigned as the model for @object_name@.
+ # @presenter_options@ are set once on the initial presenter instance.
+ #
def each_with_presenter(presenter_class, object_name, presenter_options={}, &block)
presenter = presenter_class.new(presenter_options)
each do |object|
View
2  lib/viewtastic/activation.rb
@@ -1,7 +1,7 @@
module Viewtastic
module Activation
# Lets Viewtastic know about the controller object via a before filter, AKA "activates" viewtastic.
- # Borrowed from Viewtastic.
+ # Borrowed from Authlogic.
#
def self.included(klass) # :nodoc:
if defined?(::ApplicationController)
View
170 lib/viewtastic/base.rb
@@ -1,101 +1,127 @@
-class Viewtastic::Base
- include ActionView::Helpers::UrlHelper
- include ActionView::Helpers::TextHelper
- include ActionView::Helpers::TagHelper
+module Viewtastic
+ # Base class for presenters. See README.md for usage.
+ #
+ class Base
+ include ActionView::Helpers::UrlHelper
+ include ActionView::Helpers::TextHelper
+ include ActionView::Helpers::TagHelper
+
+ class_inheritable_accessor :presented
+ self.presented = []
- class_inheritable_accessor :presented
- self.presented = []
+ delegate :protect_against_forgery?,
+ :request_forgery_protection_token,
+ :form_authenticity_token,
+ :dom_id,
+ :to => :controller
- delegate :protect_against_forgery?,
- :request_forgery_protection_token,
- :form_authenticity_token,
- :dom_id,
- :to => :controller
-
- class << self
- def presents(*types)
- types_and_attributes = types.extract_options!
+ class << self
+ # Indicates which models are to be presented.
+ #
+ # class CommentPresenter < Viewtastic::Base
+ # presents :comment, :post
+ # end
+ #
+ # If you want to delegate messages to models without prefixing them with the model name, specify them in an Array:
+ #
+ # class PresenterWithTwoAddresses < ActivePresenter::Base
+ # presents :post, :comment => [:body, :created_at]
+ # end
+ #
+ def presents(*types)
+ types_and_attributes = types.extract_options!
- types_and_attributes.each do |name, delegates|
- attr_accessor name
- presented << name
- delegates.each do |msg|
- delegate msg, :to => name
+ types_and_attributes.each do |name, delegates|
+ attr_accessor name
+ presented << name
+ delegates.each do |msg|
+ delegate msg, :to => name
+ end
end
- end
- attr_accessor *types
- self.presented += types
+ attr_accessor *types
+ self.presented += types
- presented.each do |name|
- define_method("#{name}_dom_id") do |*args|
- send(:dom_id, send(name), *args)
+ presented.each do |name|
+ define_method("#{name}_dom_id") do |*args|
+ send(:dom_id, send(name), *args)
+ end
end
end
- end
- def controller=(value)
- Thread.current[:viewtastic_controller] = value
- end
+ def controller=(value) #:nodoc:
+ Thread.current[:viewtastic_controller] = value
+ end
- def controller
- Thread.current[:viewtastic_controller]
- end
+ def controller #:nodoc:
+ Thread.current[:viewtastic_controller]
+ end
- def activated?
- !controller.nil?
+ def activated? #:nodoc:
+ !controller.nil?
+ end
end
- end
- def initialize(*values)
- keys_and_values = values.extract_options!
+ # Accepts arguments in two forms. If you had a CommentPresenter that presented a Comment model and a Post model, you would write the follwoing:
+ #
+ # 1. CommentPresenter.new(:comment => Comment.new, :post => @post)
+ # 2. CommentPresenter.new(Comment.new, @post) - it will introspect on the model's class; the order is not important.
+ #
+ # You can even mix the two:
+ # CommentPresenter.new(Comment.new, :post => @post)
+ #
+ def initialize(*values)
+ keys_and_values = values.extract_options!
- keys_and_values.each do |name, instance|
- send("#{name}=", instance)
- end
+ keys_and_values.each do |name, instance|
+ send("#{name}=", instance)
+ end
- values.each do |value|
- send("#{value.class.name.underscore}=", value)
+ values.each do |value|
+ send("#{value.class.name.underscore}=", value)
+ end
end
- end
- def method_missing(method_name, *args, &block)
- if method_name.to_s =~ /_(path|url)$/
- # Delegate all named routes to the controller
- controller.send(method_name, *args)
- elsif presented_attribute?(method_name)
- delegate_message(method_name, *args, &block)
- else
- super
+ def method_missing(method_name, *args, &block)
+ if method_name.to_s =~ /_(path|url)$/
+ # Delegate all named routes to the controller
+ controller.send(method_name, *args)
+ elsif presented_attribute?(method_name)
+ delegate_message(method_name, *args, &block)
+ else
+ super
+ end
end
- end
- protected
+ # The current controller performing the request is accessible with this.
+ #
def controller
self.class.controller
end
- def delegate_message(method_name, *args, &block)
- presentable = presentable_for(method_name)
- send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
- end
+ protected
+ def delegate_message(method_name, *args, &block) #:nodoc:
+ presentable = presentable_for(method_name)
+ send(presentable).send(flatten_attribute_name(method_name, presentable), *args, &block)
+ end
- def presentable_for(method_name)
- presented.sort_by { |k| k.to_s.size }.reverse.detect do |type|
- method_name.to_s.starts_with?(attribute_prefix(type))
+ def presentable_for(method_name) #:nodoc:
+ presented.sort_by { |k| k.to_s.size }.reverse.detect do |type|
+ method_name.to_s.starts_with?(attribute_prefix(type))
+ end
end
- end
- def presented_attribute?(method_name)
- p = presentable_for(method_name)
- !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
- end
+ def presented_attribute?(method_name) #:nodoc:
+ p = presentable_for(method_name)
+ !p.nil? && send(p).respond_to?(flatten_attribute_name(method_name,p))
+ end
- def flatten_attribute_name(name, type)
- name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
- end
+ def flatten_attribute_name(name, type) #:nodoc:
+ name.to_s.gsub(/^#{attribute_prefix(type)}/, '')
+ end
- def attribute_prefix(type)
- "#{type}_"
- end
+ def attribute_prefix(type) #:nodoc:
+ "#{type}_"
+ end
+ end
end
View
15 lib/viewtastic/test_case.rb
@@ -0,0 +1,15 @@
+module Viewtastic
+ module TestCase
+ include Authlogic::TestCase
+
+ def activate_viewtastic
+ if @request && ! @request.respond_to?(:params)
+ class <<@request
+ alias_method :params, :parameters
+ end
+ end
+
+ Viewtastic::Base.controller = (@request && Authlogic::TestCase::RailsRequestAdapter.new(@request)) || controller
+ end
+ end
+end
View
12 spec/spec_helper.rb
@@ -31,17 +31,7 @@ class UserPresenter < Viewtastic::Base
end
Spec::Runner.configure do |config|
- include Authlogic::TestCase
-
- def activate_viewtastic
- if @request && ! @request.respond_to?(:params)
- class <<@request
- alias_method :params, :parameters
- end
- end
-
- Viewtastic::Base.controller = (@request && Authlogic::TestCase::RailsRequestAdapter.new(@request)) || controller
- end
+ include Viewtastic::TestCase
config.before(:each) do
activate_viewtastic
View
42 viewtastic.gemspec
@@ -0,0 +1,42 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{viewtastic}
+ s.version = "0.1.0"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Istvan Hoka"]
+ s.date = %q{2009-11-30}
+ s.email = %q{istvan.hoka@gmail.com}
+ s.extra_rdoc_files = [
+ "LICENSE",
+ "README"
+ ]
+ s.files = [
+ "LICENSE",
+ "lib/duck_punches/array/each_with_presenter.rb",
+ "lib/viewtastic.rb",
+ "lib/viewtastic/activation.rb",
+ "lib/viewtastic/base.rb",
+ "lib/viewtastic/test_case.rb"
+ ]
+ s.homepage = %q{http://github.com/ihoka/viewtastic}
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_paths = ["lib"]
+ s.rubygems_version = %q{1.3.5}
+ s.summary = %q{Presenter plugin for Ruby on Rails}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ else
+ end
+ else
+ end
+end
+
Please sign in to comment.
Something went wrong with that request. Please try again.