showcase 0.2.0.pre → 0.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72574756357dcfeea3882c9cc85310c932bc272d
4
- data.tar.gz: 98f5d60b67e5dba3f0d870ae033b9dacc6ffad28
3
+ metadata.gz: 987858bde075b1173d6c229fd861b25c165ca851
4
+ data.tar.gz: daf57836d8e3159f20d2b2034368eb49d9e28c5d
5
5
  SHA512:
6
- metadata.gz: 7b49b695ea0301b22c47239c144ceaf4ccfa7a22c6ec1ab809f7660581792c196953060183064a7a9e2d61a230d2fbd7ceccc3ce9ce2289e617f6457e39d1b86
7
- data.tar.gz: dcfd53204bc986fc2389707a130afe5d7395b110f34d30b63cd562375f12140a7f03474f07c2d88a987304da6bc9fac29d81875eec3dcc8e45c25ba624886a2a
6
+ metadata.gz: 1893aeaf728470b953c32d835cfbff594a835d97f9af45c63cd80ed0d1afa16f867daab34a6c2051552c0c8c19580e75ffcd12f5727b031b622242fccfd39272
7
+ data.tar.gz: 0a673a3d06105364974135115fe9b3c99de98d9945ce8b3c7a74bee4d2180bb03b03c4cd43fc7235601eacbd48f1d4be7cc6f6c5da661742e3e06de985f54d47
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ gemfiles/*.gemfile.lock
19
+
data/.travis.yml CHANGED
@@ -1,6 +1,12 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
4
  - "1.9.3"
4
5
  - "2.0.0"
5
- script: "bundle exec rspec spec"
6
+
7
+ gemfile:
8
+ - "gemfiles/rails_32.gemfile"
9
+ - "gemfiles/rails_4.gemfile"
10
+
11
+ script: "bundle exec rake spec"
6
12
 
data/Appraisals ADDED
@@ -0,0 +1,8 @@
1
+ appraise "rails-32" do
2
+ gem "rails", "3.2.14"
3
+ end
4
+
5
+ appraise "rails-4" do
6
+ gem "rails", "4.0.0"
7
+ end
8
+
data/Gemfile CHANGED
@@ -2,3 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in basic_presenter.gemspec
4
4
  gemspec
5
+
6
+ gem "appraisal"
7
+
data/README.md CHANGED
@@ -3,36 +3,42 @@
3
3
  A simple (< 100 lines of code) but powerful exhibit/presenter implementation.
4
4
  It's framework agnostic: works with Rails, Padrino or just Sinatra.
5
5
 
6
- Since version 0.2.0 Showcase is bundled with [a set of "traits"](https://github.com/stefanoverna/showcase#traits)
6
+ Since version 0.2.0 Showcase is bundled with [a set of optional "traits"](https://github.com/stefanoverna/showcase#traits)
7
7
  you can pick and choose to augment your presenters with additional sugar
8
- (available in Rails only).
8
+ (available in Rails 3+ only).
9
9
 
10
- ## Why should I use the Exhibit pattern in my Rails app?
10
+ ## Why should I use presenters in my Rails app?
11
11
 
12
- See [Avdi's introductory post](http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/).
12
+ See [Avdi's Exhibits introductory post](http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/).
13
13
 
14
14
  ## Installation
15
15
 
16
16
  Add this line to your application's Gemfile:
17
17
 
18
- gem 'showcase'
18
+ ```ruby
19
+ gem 'showcase'
20
+ ```
19
21
 
20
22
  And then execute:
21
23
 
22
- $ bundle
24
+ ```
25
+ $ bundle
26
+ ```
23
27
 
24
28
  Or install it yourself as:
25
29
 
26
- $ gem install showcase
30
+ ```
31
+ $ gem install showcase
32
+ ```
27
33
 
28
34
  ## Usage
29
35
 
30
- With Rails, you're already set, move on! With Padrino, include `Showcase::Helpers`
36
+ With Rails, you're already set, move on! With Padrino, include `Showcase::Helpers::Present`
31
37
  in your app `helpers` block.
32
38
 
33
39
  ```ruby
34
40
  helpers do
35
- include Showcase::Helpers
41
+ include Showcase::Helpers::Present
36
42
  end
37
43
  ```
38
44
 
@@ -82,16 +88,15 @@ end
82
88
 
83
89
  ### Generators
84
90
 
85
- Showcase comes with a generator to make the Presenter creation process a little
86
- faster:
91
+ Showcase comes with a generator to create new presenters a little faster:
87
92
 
88
93
  ```
89
94
  rails generate showcase:presenter User
90
95
  ```
91
96
 
92
- Will generate `app/presenters/user_presenter.rb`. If your app has a file called
97
+ Will generate `app/presenters/user_presenter.rb`. If your Rails app has the file
93
98
  `app/presenters/base_presenter.rb`, the newly created presenter will inherit
94
- form `BasePresenter` instead of `Shocase::Presenter`.
99
+ from `BasePresenter` instead of `Showcase::Presenter`.
95
100
 
96
101
  ### Traits
97
102
 
@@ -127,7 +132,7 @@ Super useful in acceptance testing to check the presence of a record inside a
127
132
  view:
128
133
 
129
134
  ```erb
130
- <% present(@project).box do %>
135
+ <% present(@project, class: 'big').box do %>
131
136
  <p>Hi there!</p>
132
137
  <% end %>
133
138
  ```
@@ -135,11 +140,24 @@ view:
135
140
  Produces the following:
136
141
 
137
142
  ```html
138
- <div class="project" id="project_12">
143
+ <div class="project big" id="project_12">
139
144
  <p>Hi there</p>
140
145
  </div>
141
146
  ```
142
147
 
148
+ Additional HTML attributes can be optionally specified within a config block
149
+ inside the presenter:
150
+
151
+ ```ruby
152
+ class ProjectPresenter < Showcase::Presenter
153
+ include Showcase::Traits::Record
154
+
155
+ box do |c|
156
+ c.html_options class: 'another-class', role: 'project'
157
+ end
158
+ end
159
+ ```
160
+
143
161
  #### `Showcase::Traits::LinkTo`
144
162
 
145
163
  Adds a nice DSL to declare links within your presenter.
@@ -149,15 +167,16 @@ class ProjectPresenter < Showcase::Presenter
149
167
  include Showcase::Traits::LinkTo
150
168
 
151
169
  link_to do |c|
152
- c.url h.project_path(self)
153
- c.label name
154
- c.active h.controller_name == 'projects'
170
+ c.url h.project_path(self)
171
+ c.label name
172
+ c.active h.controller_name == 'projects'
173
+ c.active_class 'current'
174
+ c.html_options role: 'label'
155
175
  end
156
176
 
157
177
  link_to :tasks do
158
178
  c.url h.project_tasks_path(self)
159
179
  c.label "Tasks"
160
- c.active h.controller_name == 'tasks'
161
180
  end
162
181
  end
163
182
  ```
@@ -216,7 +235,7 @@ In your views:
216
235
  #### `Showcase::Traits::Seo`
217
236
 
218
237
  Useful to produce SEO meta tags (title, description, Facebook OpenGraph,
219
- Twitter cards, and canonical URL):
238
+ Twitter cards, and canonical URLs):
220
239
 
221
240
  ```ruby
222
241
  class ProjectPresenter < Showcase::Presenter
@@ -230,6 +249,7 @@ class ProjectPresenter < Showcase::Presenter
230
249
  end
231
250
  end
232
251
  ```
252
+
233
253
  In your views:
234
254
 
235
255
  ```erb
data/Rakefile CHANGED
@@ -1 +1,14 @@
1
- require "bundler/gem_tasks"
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'appraisal'
4
+
5
+ desc 'Default: run specs'
6
+ task default: :spec
7
+
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "spec/**/*_spec.rb"
11
+ end
12
+
13
+ Bundler::GemHelper.install_tasks
14
+
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "3.2.14"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "4.0.0"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,22 @@
1
+ class HtmlOptions
2
+ def initialize(options = {})
3
+ @options = (options || {}).symbolize_keys
4
+ end
5
+
6
+ def add_class!(css_class)
7
+ @options[:class] ||= ""
8
+ css_classes = @options[:class].split(/\s+/)
9
+ css_classes << css_class
10
+ @options[:class] = css_classes.join(" ")
11
+ end
12
+
13
+ def merge_attrs!(options = {})
14
+ options = (options || {}).symbolize_keys
15
+ @options.merge!(options)
16
+ end
17
+
18
+ def to_h
19
+ @options.dup
20
+ end
21
+ end
22
+
@@ -0,0 +1,19 @@
1
+ module Showcase
2
+ module Helpers
3
+ module ModuleMethodBuilder
4
+ def define_module_method(name_chunks, &block)
5
+ method_name = Array(name_chunks).map(&:to_s).map(&:presence).compact.join("_")
6
+ if method_defined?(method_name)
7
+ false
8
+ else
9
+ method_module = Module.new do
10
+ define_method(method_name, &block)
11
+ end
12
+ include(method_module)
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,35 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/inflector'
3
+ require 'active_support/core_ext/hash/keys'
4
+
5
+ module Showcase
6
+ module Helpers
7
+ module Present
8
+ extend ActiveSupport::Concern
9
+
10
+ def presenter_context
11
+ if respond_to? :view_context
12
+ view_context
13
+ else
14
+ self
15
+ end
16
+ end
17
+
18
+ def present(obj, klass = nil, context = presenter_context, options = {})
19
+ options.assert_valid_keys(:nil_presenter)
20
+
21
+ if obj || options.fetch(:nil_presenter, false)
22
+ klass ||= "#{obj.class.name}Presenter".constantize
23
+ klass.new(obj, context)
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def present_collection(obj, klass = nil, context = presenter_context, options = {})
30
+ obj.map { |o| present(o, klass, context, options) }
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -12,26 +12,51 @@ module Showcase
12
12
  title += options[:title_suffix] if options[:title_suffix]
13
13
 
14
14
  context.content_tag(:title, title) <<
15
- seo_meta_tags(:og_title, :twitter_title, values)
15
+ seo_meta_tags('og:title', 'twitter:title', values)
16
16
  end
17
17
 
18
18
  def description(values, options = {})
19
- seo_meta_tags(:description, :og_description, :twitter_description, values)
19
+ seo_meta_tags('description', 'og:description', 'twitter:description', values)
20
20
  end
21
21
 
22
22
  def image_url(image_url, options = {})
23
- seo_meta_tags(:og_image, :twitter_image, image_url)
23
+ seo_meta_tags('og:image', 'twitter:image', image_url)
24
+ end
25
+
26
+ def iframe_video_url(video_url, options = {})
27
+ seo_meta_tags('og:video:url', video_url) <<
28
+ seo_meta_tags('og:video:type', 'text/html') <<
29
+ seo_meta_tags('twitter:player', video_url)
30
+ end
31
+
32
+ def stream_video_url(video_url, options = {})
33
+ seo_meta_tags('og:video:url', video_url) <<
34
+ seo_meta_tags('og:video:type', 'video/mp4') <<
35
+ seo_meta_tags('twitter:player:stream', video_url)
36
+ end
37
+
38
+ def card_type(type, options = {})
39
+ seo_meta_tags('twitter:card', type)
40
+ end
41
+
42
+ def video_size(size, options = {})
43
+ seo_meta_tags('twitter:player:width', size.first) <<
44
+ seo_meta_tags('twitter:player:height', size.last)
45
+ end
46
+
47
+ def site_name(name, options = {})
48
+ seo_meta_tags('og:site_name', name)
24
49
  end
25
50
 
26
51
  def canonical_url(url, options = {})
27
- seo_meta_tags(:og_url, url) <<
52
+ seo_meta_tags('og:url', 'twitter:url', url) <<
28
53
  context.tag(:link, rel: "canonical", "href" => url)
29
54
  end
30
55
 
31
56
  private
32
57
 
33
58
  def first_nonblank(values)
34
- Array(values).map(&:presence).compact.first
59
+ Array(values).find(&:presence)
35
60
  end
36
61
 
37
62
  def seo_meta_tags(*args)
@@ -40,8 +65,14 @@ module Showcase
40
65
  return nil unless value.present?
41
66
 
42
67
  args.map do |name|
43
- name = name.to_s.sub(/_/, ":")
44
- context.tag(:meta, name: name, content: value)
68
+ chunks = name.to_s.split(":")
69
+ attr_name = if chunks.first == 'og'
70
+ 'property'
71
+ else
72
+ 'name'
73
+ end
74
+ name = chunks.join(':')
75
+ context.tag(:meta, attr_name => name, content: value)
45
76
  end.join.html_safe
46
77
  end
47
78
  end
@@ -1,17 +1,20 @@
1
1
  require 'delegate'
2
- require 'showcase/helpers'
2
+ require 'showcase/helpers/present'
3
+ require 'showcase/helpers/module_method_builder'
3
4
  require 'active_support/core_ext/array/extract_options'
4
5
  require 'active_support/core_ext/hash/keys'
5
6
 
6
7
  module Showcase
7
8
  class Presenter < SimpleDelegator
8
- include Helpers
9
+ include Helpers::Present
10
+ extend Helpers::ModuleMethodBuilder
9
11
 
10
12
  attr_reader :view_context
11
13
 
12
14
  alias_method :object, :__getobj__
13
15
  alias_method :h, :view_context
14
16
  alias_method :try, :__send__
17
+ alias_method :__decorator_class__, :class
15
18
 
16
19
  def initialize(obj, context)
17
20
  super(obj)
@@ -46,19 +49,15 @@ module Showcase
46
49
  options.assert_valid_keys(:with, :nil_presenter)
47
50
  presenter_klass = options.fetch(:with, nil)
48
51
 
49
- methods_module = Module.new do
50
- args.each do |attr|
51
- define_method attr do
52
- send(method,
53
- object.send(attr),
54
- presenter_klass,
55
- view_context,
56
- options.slice(:nil_presenter))
57
- end
52
+ args.each do |attr|
53
+ define_module_method attr do
54
+ send(method,
55
+ object.send(attr),
56
+ presenter_klass,
57
+ view_context,
58
+ options.slice(:nil_presenter))
58
59
  end
59
60
  end
60
-
61
- include(methods_module)
62
61
  end
63
62
  end
64
63
  end
@@ -4,7 +4,7 @@ module Showcase
4
4
  class Railtie < Rails::Railtie
5
5
  initializer "action_view.initialize_showcase" do
6
6
  ActiveSupport.on_load(:action_view) do
7
- ActionView::Base.send :include, Showcase::Helpers
7
+ ActionView::Base.send :include, Showcase::Helpers::Present
8
8
  end
9
9
  end
10
10
  end
@@ -3,20 +3,9 @@ module Showcase
3
3
  module Base
4
4
  extend ActiveSupport::Concern
5
5
 
6
- module ClassMethods
7
- private
8
-
9
- def define_method?(name_chunks, &block)
10
- method_name = Array(name_chunks).map(&:to_s).map(&:presence).compact.join("_")
11
- if method_defined?(method_name)
12
- false
13
- else
14
- define_method(method_name, &block)
15
- true
16
- end
17
- end
6
+ included do
7
+ extend Helpers::ModuleMethodBuilder
18
8
  end
19
-
20
9
  end
21
10
  end
22
11
  end
@@ -1,4 +1,5 @@
1
1
  require 'showcase/helpers/config_object'
2
+ require 'showcase/helpers/html_options'
2
3
 
3
4
  module Showcase
4
5
  module Traits
@@ -9,31 +10,24 @@ module Showcase
9
10
 
10
11
  module ClassMethods
11
12
  def link_to(name = nil, &block)
12
-
13
- define_method? [name, :url] do
13
+ define_module_method [name, :url] do
14
14
  Helpers::ConfigObject.new(self, &block).to_struct.url
15
15
  end
16
16
 
17
- define_method? [name, :link_active?] do
17
+ define_module_method [name, :link_active?] do
18
18
  Helpers::ConfigObject.new(self, &block).to_struct.active
19
19
  end
20
20
 
21
- define_method? [name, :link] do |*args, &link_block|
21
+ define_module_method [name, :link] do |*args, &link_block|
22
22
  config = Helpers::ConfigObject.new(self, &block).to_struct
23
- options = args.extract_options!.symbolize_keys
24
- options.reverse_merge!(config.html_options) if config.html_options
25
23
 
26
- if config.active
27
- options[:class] ||= ""
28
- css_classes = options[:class].split(/\s+/)
29
- css_classes << "active"
30
- options[:class] = css_classes.join(" ")
31
- end
24
+ html_options = HtmlOptions.new(config.html_options)
25
+ html_options.merge_attrs!(args.extract_options!)
26
+ html_options.add_class!(config.active_class || 'active') if config.active
32
27
 
33
28
  args = Array(config.label) if args.empty? && !link_block
34
- h.link_to *args, config.url, options, &link_block
29
+ h.link_to *args, config.url, html_options.to_h, &link_block
35
30
  end
36
-
37
31
  end
38
32
  end
39
33
  end
@@ -1,35 +1,59 @@
1
- require 'action_view/record_identifier'
2
-
3
1
  module Showcase
4
2
  module Traits
5
3
 
6
4
  module Record
7
5
  extend ActiveSupport::Concern
8
6
 
7
+ module ClassMethods
8
+ def box(&block)
9
+ @box_config_block = block
10
+ end
11
+
12
+ def __box_config_block__
13
+ @box_config_block
14
+ end
15
+ end
16
+
9
17
  def dom_id
10
- ActionView::RecordIdentifier.dom_id(self)
18
+ record_identifier.dom_id(self)
11
19
  end
12
20
 
13
21
  def dom_class
14
- ActiveModel::Naming.param_key(self)
22
+ record_identifier.dom_class(self)
15
23
  end
16
24
 
17
25
  def box(*args, &block)
18
26
  options = args.extract_options!
19
- options.symbolize_keys!
20
-
21
27
  tag = args.pop || :div
22
28
 
23
- options[:class] ||= ""
24
- css_classes = options[:class].split(/\s+/) << dom_class
25
- options[:class] = css_classes.join(" ")
29
+ config_block = self.__decorator_class__.__box_config_block__
30
+ config_options = if config_block
31
+ Helpers::ConfigObject.new(self, &config_block).to_struct.html_options
32
+ else
33
+ {}
34
+ end
26
35
 
27
- options[:id] = dom_id
36
+ html_options = HtmlOptions.new(config_options)
37
+ html_options.merge_attrs!(options)
38
+ html_options.add_class!(dom_class)
39
+ html_options.merge_attrs!(id: dom_id)
28
40
 
29
- h.content_tag(tag, options) do
41
+ h.content_tag(tag, html_options.to_h) do
30
42
  h.capture(self, &block)
31
43
  end
32
44
  end
45
+
46
+ private
47
+
48
+ def record_identifier
49
+ if defined?(ActionView::RecordIdentifier)
50
+ ActionView::RecordIdentifier
51
+ elsif defined?(ActionController::RecordIdentifier)
52
+ ActionController::RecordIdentifier
53
+ else
54
+ raise 'No RecordIdentifier found!'
55
+ end
56
+ end
33
57
  end
34
58
 
35
59
  end
@@ -9,13 +9,27 @@ module Showcase
9
9
 
10
10
  module ClassMethods
11
11
 
12
+ def default_seo_options(&block)
13
+ define_module_method :default_seo_options do
14
+ Helpers::ConfigObject.new(self, &block).to_hash
15
+ end
16
+ end
17
+
12
18
  def seo(name = nil, options = {}, &block)
13
- define_method? [name, :seo_tags] do |options = {}|
14
- meta = Helpers::ConfigObject.new(self, &block).to_hash
19
+ define_module_method [name, :seo_tags] do |options = {}|
20
+ meta = respond_to?(:default_seo_options) ? default_seo_options : {}
21
+ meta.merge!(Helpers::ConfigObject.new(self, &block).to_hash)
22
+ meta.merge!(options.symbolize_keys) if options
23
+
15
24
  builder = Helpers::SeoMetaBuilder.new(view_context)
16
- parts = %w(title description canonical_url image_url canonical_url).map(&:to_sym)
25
+ parts = %w(
26
+ title description site_name
27
+ canonical_url
28
+ image_url iframe_video_url stream_video_url
29
+ ).map(&:to_sym)
30
+
17
31
  parts.map do |tag|
18
- builder.send(tag, meta[tag], options) if meta[tag]
32
+ builder.send(tag, meta[tag], meta.except(*parts)) if meta[tag]
19
33
  end.compact.join.html_safe
20
34
  end
21
35
  end
@@ -1,4 +1,5 @@
1
1
  require 'showcase/helpers/config_object'
2
+ require 'active_support/core_ext/object/to_query'
2
3
 
3
4
  module Showcase
4
5
  module Traits
@@ -41,14 +42,17 @@ module Showcase
41
42
 
42
43
  link_to link_name do |c|
43
44
  meta = Helpers::ConfigObject.new(self, &block).to_struct
45
+ html_options = meta.html_options || {}
44
46
  params = Hash[
45
47
  settings[:params].map do |param, meta_key|
46
- [ param, meta.send(meta_key) ]
48
+ values = [:"#{social}_#{meta_key}", meta_key].map { |key| meta.send(key) }
49
+ [ param, values.find(&:presence) ]
47
50
  end
48
51
  ]
52
+
49
53
  c.url "#{settings[:url]}?#{params.to_query}"
50
54
  c.label settings[:label]
51
- c.html_options = { target: :blank }
55
+ c.html_options = html_options.reverse_merge(target: '_blank')
52
56
  end
53
57
  end
54
58
  end
@@ -1,4 +1,4 @@
1
1
  module Showcase
2
- VERSION = "0.2.0.pre"
2
+ VERSION = "0.2.0.rc.1"
3
3
  end
4
4
 
data/showcase.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.name = 'showcase'
8
8
  gem.version = Showcase::VERSION
9
9
  gem.authors = ['Stefano Verna']
10
- gem.email = ['stefano.verna@welaika.com']
10
+ gem.email = ['stefano.verna@gmail.com']
11
11
  gem.description = %q{A barebone and framework agnostic presenter implementation}
12
12
  gem.summary = %q{A barebone and framework agnostic presenter implementation}
13
13
  gem.homepage = 'https://github.com/welaika/showcase'
data/spec/fixtures.rb CHANGED
@@ -87,7 +87,7 @@ class NilClassPresenter < Showcase::Presenter
87
87
  end
88
88
 
89
89
  class Context
90
- include Showcase::Helpers
90
+ include Showcase::Helpers::Present
91
91
 
92
92
  def bold(text)
93
93
  "**#{text}**"
@@ -13,8 +13,8 @@ module Showcase::Helpers
13
13
  expect(subject.title('foo')).to have_tag(:title, text: 'foo')
14
14
  end
15
15
 
16
- it 'produces a ug:title meta tag' do
17
- expect(subject.title('foo')).to have_tag(:meta, with: { name: 'og:title', content: 'foo' })
16
+ it 'produces a og:title meta tag' do
17
+ expect(subject.title('foo')).to have_tag(:meta, with: { property: 'og:title', content: 'foo' })
18
18
  end
19
19
 
20
20
  it 'produces a twitter:title meta tag' do
@@ -32,7 +32,7 @@ module Showcase::Helpers
32
32
  expect(subject.title('foo', title_suffix: ' - bar')).to have_tag(:title, text: 'foo - bar')
33
33
  end
34
34
  it 'does not suffix meta tags' do
35
- expect(subject.title('foo')).to have_tag(:meta, with: { name: 'og:title', content: 'foo' })
35
+ expect(subject.title('foo')).to have_tag(:meta, with: { property: 'og:title', content: 'foo' })
36
36
  expect(subject.title('foo')).to have_tag(:meta, with: { name: 'twitter:title', content: 'foo' })
37
37
  end
38
38
  end
@@ -44,7 +44,7 @@ module Showcase::Helpers
44
44
  end
45
45
 
46
46
  it 'produces a og:description meta tag' do
47
- expect(subject.description('foo')).to have_tag(:meta, with: { name: 'og:description', content: 'foo' })
47
+ expect(subject.description('foo')).to have_tag(:meta, with: { property: 'og:description', content: 'foo' })
48
48
  end
49
49
 
50
50
  it 'produces a twitter:description meta tag' do
@@ -60,7 +60,7 @@ module Showcase::Helpers
60
60
 
61
61
  describe '#image_url' do
62
62
  it 'produces a og:image meta tag' do
63
- expect(subject.image_url('foo')).to have_tag(:meta, with: { name: 'og:image', content: 'foo' })
63
+ expect(subject.image_url('foo')).to have_tag(:meta, with: { property: 'og:image', content: 'foo' })
64
64
  end
65
65
 
66
66
  it 'produces a twitter:image meta tag' do
@@ -69,14 +69,18 @@ module Showcase::Helpers
69
69
 
70
70
  context 'with multiple values' do
71
71
  it 'uses the first non-blank' do
72
- expect(subject.image_url(['', nil, 'foo'])).to have_tag(:meta, with: { name: 'og:image', content: 'foo' })
72
+ expect(subject.image_url(['', nil, 'foo'])).to have_tag(:meta, with: { property: 'og:image', content: 'foo' })
73
73
  end
74
74
  end
75
75
  end
76
76
 
77
77
  describe '#canonical_url' do
78
78
  it 'produces a og:url meta tag' do
79
- expect(subject.canonical_url('foo')).to have_tag(:meta, with: { name: 'og:url', content: 'foo' })
79
+ expect(subject.canonical_url('foo')).to have_tag(:meta, with: { property: 'og:url', content: 'foo' })
80
+ end
81
+
82
+ it 'produces a twitter:url meta tag' do
83
+ expect(subject.canonical_url('foo')).to have_tag(:meta, with: { name: 'twitter:url', content: 'foo' })
80
84
  end
81
85
 
82
86
  it 'produces a canonical link tag' do
@@ -85,11 +89,58 @@ module Showcase::Helpers
85
89
 
86
90
  context 'with multiple values' do
87
91
  it 'uses the first non-blank' do
88
- expect(subject.canonical_url(['', nil, 'foo'])).to have_tag(:meta, with: { name: 'og:url', content: 'foo' })
92
+ expect(subject.canonical_url(['', nil, 'foo'])).to have_tag(:meta, with: { property: 'og:url', content: 'foo' })
89
93
  end
90
94
  end
91
95
  end
92
96
 
97
+ describe '#iframe_video_url' do
98
+ it 'produces a og:video:url meta tag' do
99
+ expect(subject.iframe_video_url('foo')).to have_tag(:meta, with: { property: 'og:video:url', content: 'foo' })
100
+ end
101
+
102
+ it 'produces a twitter:player meta tag' do
103
+ expect(subject.iframe_video_url('foo')).to have_tag(:meta, with: { name: 'twitter:player', content: 'foo' })
104
+ end
105
+
106
+ it 'produces a og:video:type meta tag' do
107
+ expect(subject.iframe_video_url('foo')).to have_tag(:meta, with: { property: 'og:video:type', content: 'text/html' })
108
+ end
109
+ end
110
+
111
+ describe '#stream_video_url' do
112
+ it 'produces a og:video:url meta tag' do
113
+ expect(subject.stream_video_url('foo')).to have_tag(:meta, with: { property: 'og:video:url', content: 'foo' })
114
+ end
115
+
116
+ it 'produces a twitter:player:stream meta tag' do
117
+ expect(subject.stream_video_url('foo')).to have_tag(:meta, with: { name: 'twitter:player:stream', content: 'foo' })
118
+ end
119
+
120
+ it 'produces a og:video:type meta tag' do
121
+ expect(subject.stream_video_url('foo')).to have_tag(:meta, with: { property: 'og:video:type', content: 'video/mp4' })
122
+ end
123
+ end
124
+
125
+ describe '#site_name' do
126
+ it 'produces a og:site_name meta tag' do
127
+ expect(subject.site_name('foo')).to have_tag(:meta, with: { property: 'og:site_name', content: 'foo' })
128
+ end
129
+ end
130
+
131
+ describe '#card_type' do
132
+ it 'produces a twitter:card meta tag' do
133
+ expect(subject.card_type('foo')).to have_tag(:meta, with: { name: 'twitter:card', content: 'foo' })
134
+ end
135
+ end
136
+
137
+ describe '#video_size' do
138
+ it 'produces twitter:player meta tags' do
139
+ result = subject.video_size([10, 20])
140
+ expect(result).to have_tag(:meta, with: { name: 'twitter:player:width', content: '10' })
141
+ expect(result).to have_tag(:meta, with: { name: 'twitter:player:height', content: '20' })
142
+ end
143
+ end
93
144
  end
94
145
  end
95
146
 
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  module Showcase::Traits
4
4
  describe Base do
5
- describe '.define_method?' do
5
+ describe '.define_module_method' do
6
6
 
7
7
  it 'defines an instance method' do
8
8
  klass = Class.new do
9
9
  include Base
10
- define_method? :foo do
10
+ define_module_method :foo do
11
11
  true
12
12
  end
13
13
  end
@@ -15,6 +15,22 @@ module Showcase::Traits
15
15
  expect(klass.new.foo).to be_true
16
16
  end
17
17
 
18
+ it 'overriding the method allows to call super' do
19
+ klass = Class.new do
20
+ include Base
21
+
22
+ define_module_method :foo do
23
+ true
24
+ end
25
+
26
+ def foo
27
+ super
28
+ end
29
+ end
30
+
31
+ expect(klass.new.foo).to be_true
32
+ end
33
+
18
34
  context 'if the method is already present' do
19
35
  it 'no-ops ' do
20
36
  klass = Class.new do
@@ -30,7 +46,7 @@ module Showcase::Traits
30
46
  it 'joins them in snake case' do
31
47
  klass = Class.new do
32
48
  include Base
33
- define_method? [:foo, :bar] do
49
+ define_module_method [:foo, :bar] do
34
50
  true
35
51
  end
36
52
  end
@@ -41,7 +57,7 @@ module Showcase::Traits
41
57
  it 'ignores blank chunks' do
42
58
  klass = Class.new do
43
59
  include Base
44
- define_method? ["", :bar] do
60
+ define_module_method ["", :bar] do
45
61
  true
46
62
  end
47
63
  end
@@ -20,10 +20,13 @@ module Showcase::Traits
20
20
  c.url = url
21
21
  c.label = 'Label'
22
22
  c.active = active
23
+ c.html_options role: 'label'
23
24
  end
24
25
 
25
- link_to :foo do
26
+ link_to :foo do |c|
26
27
  c.url = '#foo'
28
+ c.active_class = 'current'
29
+ c.active = active
27
30
  end
28
31
 
29
32
  def url
@@ -43,6 +46,10 @@ module Showcase::Traits
43
46
  expect(subject.link).to have_tag(:a, text: 'Label')
44
47
  end
45
48
 
49
+ it 'with the specified html attributes' do
50
+ expect(subject.link).to have_tag(:a, with: { role: 'label' })
51
+ end
52
+
46
53
  context 'with a different label as parameter' do
47
54
  it 'uses it' do
48
55
  expect(subject.link('Foo')).to have_tag(:a, text: 'Foo')
@@ -65,12 +72,18 @@ module Showcase::Traits
65
72
  let(:active) { true }
66
73
 
67
74
  it 'adds an active class to the link' do
68
- expect(subject.link).to have_tag(:a, with: { class: 'active' })
75
+ expect(subject.link('label')).to have_tag(:a, with: { class: 'active' })
69
76
  end
70
77
 
71
78
  context 'with additional classes' do
72
79
  it 'it sums them' do
73
- expect(subject.link(class: 'extra')).to have_tag(:a, with: { class: 'extra active' })
80
+ expect(subject.link('label', class: 'extra')).to have_tag(:a, with: { class: 'extra active' })
81
+ end
82
+ end
83
+
84
+ context 'if a different CSS class was specified' do
85
+ it 'adds it to the link' do
86
+ expect(subject.foo_link('label')).to have_tag(:a, with: { class: 'current' })
74
87
  end
75
88
  end
76
89
  end
@@ -8,6 +8,10 @@ module Showcase::Traits
8
8
  let(:presenter) {
9
9
  Class.new(Showcase::Presenter) do
10
10
  include Record
11
+
12
+ box do |c|
13
+ c.html_options role: 'actor', class: 'first'
14
+ end
11
15
  end
12
16
  }
13
17
  subject { presenter.new(record, view) }
@@ -30,6 +34,11 @@ module Showcase::Traits
30
34
  expect(result).to have_tag(:div, with: { class: 'model', id: 'model_1' })
31
35
  end
32
36
 
37
+ it 'adds attributes specified within box block' do
38
+ result = subject.box { "foo" }
39
+ expect(result).to have_tag(:div, with: { role: 'actor', class: 'first' })
40
+ end
41
+
33
42
  context 'with a specified tag' do
34
43
  it 'uses it' do
35
44
  result = subject.box(:span) { "foo" }
@@ -12,6 +12,10 @@ module Showcase::Traits
12
12
  Class.new(Showcase::Presenter) do
13
13
  include Seo
14
14
 
15
+ default_seo_options do |c|
16
+ c.title_suffix = ' - qux'
17
+ end
18
+
15
19
  seo do |c|
16
20
  c.title = 'foo'
17
21
  c.description 'bar'
@@ -19,16 +23,27 @@ module Showcase::Traits
19
23
  end
20
24
  }
21
25
 
22
- describe '#seo' do
23
- let(:options) { double('options') }
26
+ describe '.seo' do
27
+ let(:expected_options) { { title_suffix: ' - qux' } }
28
+ let(:expected_description) { 'bar' }
29
+ let(:expected_title) { 'foo' }
30
+
24
31
  before do
25
32
  Showcase::Helpers::SeoMetaBuilder.stub(:new).with(view).and_return(builder)
26
- builder.stub(:title).with('foo', options).and_return('<title>')
27
- builder.stub(:description).with('bar', options).and_return('<description>')
33
+ builder.stub(:title).with(expected_title, expected_options).and_return('<title>')
34
+ builder.stub(:description).with(expected_description, expected_options).and_return('<description>')
28
35
  end
29
36
 
30
37
  it 'defines a seo_tags method that ouputs seo meta tags' do
31
- expect(subject.seo_tags(options)).to eq '<title><description>'
38
+ expect(subject.seo_tags).to eq '<title><description>'
39
+ end
40
+
41
+ describe '#seo_tags' do
42
+ let(:expected_title) { 'other' }
43
+
44
+ it 'allows to override options' do
45
+ expect(subject.seo_tags(title: 'other')).to eq '<title><description>'
46
+ end
32
47
  end
33
48
  end
34
49
 
@@ -14,7 +14,9 @@ module Showcase::Traits
14
14
  share do |c|
15
15
  c.url = 'url'
16
16
  c.text = 'text'
17
+ c.twitter_text = 'twitter text'
17
18
  c.image_url = 'image'
19
+ c.html_options = { role: 'share' }
18
20
  end
19
21
 
20
22
  share :foo do |c|
@@ -28,7 +30,7 @@ module Showcase::Traits
28
30
 
29
31
  describe '#social_share' do
30
32
  expected_urls = {
31
- twitter: "https://twitter.com/intent/tweet?text=text&url=url",
33
+ twitter: "https://twitter.com/intent/tweet?text=twitter+text&url=url",
32
34
  facebook: "http://www.facebook.com/sharer/sharer.php?u=url",
33
35
  gplus: "https://plus.google.com/share?url=url",
34
36
  pinterest: "http://www.pinterest.com/pin/create/button/?media=image&title=text&url=url",
@@ -39,10 +41,19 @@ module Showcase::Traits
39
41
  it "produces a #{provider} share link" do
40
42
  expect(subject.send("#{provider}_share_link")).to have_tag(:a)
41
43
  end
44
+
42
45
  it "produces a #{provider} share url" do
43
46
  expect(subject.send("#{provider}_share_url")).to eq url
44
47
  end
45
48
 
49
+ it "adds a target :blank to the link" do
50
+ expect(subject.send("#{provider}_share_link")).to have_tag(:a, with: { target: '_blank' })
51
+ end
52
+
53
+ it "merges additional html_options" do
54
+ expect(subject.send("#{provider}_share_link")).to have_tag(:a, with: { role: 'share' })
55
+ end
56
+
46
57
  context 'with prefix' do
47
58
  it 'prefixes link method' do
48
59
  expect(subject).to respond_to "foo_#{provider}_share_link"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: showcase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre
4
+ version: 0.2.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Verna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-21 00:00:00.000000000 Z
11
+ date: 2013-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -82,7 +82,7 @@ dependencies:
82
82
  version: '0'
83
83
  description: A barebone and framework agnostic presenter implementation
84
84
  email:
85
- - stefano.verna@welaika.com
85
+ - stefano.verna@gmail.com
86
86
  executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
@@ -90,16 +90,21 @@ files:
90
90
  - .gitignore
91
91
  - .rspec
92
92
  - .travis.yml
93
+ - Appraisals
93
94
  - Gemfile
94
95
  - LICENSE.txt
95
96
  - README.md
96
97
  - Rakefile
98
+ - gemfiles/rails_32.gemfile
99
+ - gemfiles/rails_4.gemfile
97
100
  - lib/generators/showcase/presenter/USAGE
98
101
  - lib/generators/showcase/presenter/presenter_generator.rb
99
102
  - lib/generators/showcase/presenter/templates/presenter.rb
100
103
  - lib/showcase.rb
101
- - lib/showcase/helpers.rb
102
104
  - lib/showcase/helpers/config_object.rb
105
+ - lib/showcase/helpers/html_options.rb
106
+ - lib/showcase/helpers/module_method_builder.rb
107
+ - lib/showcase/helpers/present.rb
103
108
  - lib/showcase/helpers/seo_meta_builder.rb
104
109
  - lib/showcase/presenter.rb
105
110
  - lib/showcase/railtie.rb
@@ -1,33 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/inflector'
3
- require 'active_support/core_ext/hash/keys'
4
-
5
- module Showcase
6
- module Helpers
7
- extend ActiveSupport::Concern
8
-
9
- def presenter_context
10
- if respond_to? :view_context
11
- view_context
12
- else
13
- self
14
- end
15
- end
16
-
17
- def present(obj, klass = nil, context = presenter_context, options = {})
18
- options.assert_valid_keys(:nil_presenter)
19
-
20
- if obj || options.fetch(:nil_presenter, false)
21
- klass ||= "#{obj.class.name}Presenter".constantize
22
- klass.new(obj, context)
23
- else
24
- nil
25
- end
26
- end
27
-
28
- def present_collection(obj, klass = nil, context = presenter_context, options = {})
29
- obj.map { |o| present(o, klass, context, options) }
30
- end
31
- end
32
- end
33
-