seory 0.0.3 → 0.0.4

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: 31a71be5bea7d32b2895e6b280c50db69074f284
4
- data.tar.gz: e313695b9b65b658367267bcc5c9a89d82b151d9
3
+ metadata.gz: e4ad5a6d00f1d68662b39cb9716d1146b182688c
4
+ data.tar.gz: 847f039ab50d26b966e03b1f1175554d77ee6cb2
5
5
  SHA512:
6
- metadata.gz: 92c72d830486a8487178f108e7d9459c7aad9ebab926668263f1f9460f0846212f17fe2115b88fbeca780fb89a989d3307ce7c93edf97598994381148f701e5c
7
- data.tar.gz: efd6daee3a8d918db5c596adf39f9da80fb4e6ad75825b195e99ca4069e04055bbbec103e20728030ecba3bb7d0cb32e0b5969e62f1f2289f8630ab7b6c78533
6
+ metadata.gz: 912cc7524283289708d5d852510c9a077dd60093521521a3eff1bb759891404abdf405b10e55fdb6e06255124047dcf1a622b00b5fcf50b440acb41e5f85810b
7
+ data.tar.gz: 8f64f9624cc492e8537d2e75b69c77595e4050c44c10d870cef44ac17134b2123a1f78a48467606c0524d2d6466399e802e72089a355592dbb1770013c995a4a
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1
6
+ notifications:
7
+ webhooks:
8
+ - https://idobata.io/hook/061179f9-4f3c-4c8c-bdf9-4efa9821c5c5
9
+
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Seory
1
+ # seory
2
2
 
3
- Manage SEO contets in Rails app. based on controller, action and more complex context.
3
+ Manage SEO contents in Rails app. based on controller, action and more complex context.
4
4
 
5
5
  ## Installation
6
6
 
@@ -22,7 +22,7 @@ Specify SEO content as ruby code. For example, `config/initializers/seory.rb`
22
22
 
23
23
  ```ruby
24
24
  # Specify SEO content based on `controller#action` rule
25
- match %w[products#popular products#new_release], {
25
+ match *%w[products#popular products#new_release] {
26
26
  title: 'Great products | My Great Site[MGS]'
27
27
  desc: 'A lot of greate products'
28
28
 
@@ -32,22 +32,27 @@ match %w[products#popular products#new_release], {
32
32
  }
33
33
 
34
34
  # Can contain dynamic content based on controller using assigned ivar
35
- match 'brands#show' {
35
+ match slug('brands#show') {
36
36
  title { assign(:brand).name }
37
37
  }
38
38
 
39
+ # Match with request fullpath
40
+ match path('/products/special-product') do
41
+ title 'Special Product Detail'
42
+ end
43
+
39
44
  # Custom lookup rule with controller
40
- match ->(controller) { controller.params[:page].to_i == 1 }, {
45
+ match(->(controller) { controller.params[:page].to_i == 1 }) do
41
46
  keywords do
42
47
  search = assign(:search_object)
43
48
 
44
49
  # do something
45
50
  end
46
- }
51
+ end
47
52
 
48
- # [TODO] Use custom word part
49
- match %w[products#index] do
50
- page_name { "#{page_part} Good products") }
53
+ # Use custom word part
54
+ match slug(products#index) do
55
+ misc(:page_name) { "#{controller.params[:page].to_i} page | Good products") }
51
56
 
52
57
  title :page_name
53
58
  h1 :page_name
@@ -69,6 +74,7 @@ module ApplicationHelper
69
74
  # which returns Seory::Runtime object with configured
70
75
  include Seory::Helper
71
76
  end
77
+ ```
72
78
 
73
79
  ```haml
74
80
  %html
data/lib/seory/dsl.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'seory'
2
2
  require 'seory/page_contents'
3
+ require 'seory/page_condition/build_dsl'
3
4
  require 'seory/repository'
4
5
 
5
6
  module Seory
@@ -16,7 +17,12 @@ module Seory
16
17
 
17
18
  class PageContentsBuilder
18
19
  def initialize(*conditions)
19
- @page_contents = PageContents.new(*conditions)
20
+ @page_contents =
21
+ if conditions.size == 1 && (block = conditions.first).is_a?(Proc)
22
+ PageContents.new(&block)
23
+ else
24
+ PageContents.new(*conditions)
25
+ end
20
26
  end
21
27
 
22
28
  def build!(&block)
@@ -35,6 +41,8 @@ module Seory
35
41
  end
36
42
 
37
43
  class Descriptor
44
+ include Seory::PageCondition::BuildDsl
45
+
38
46
  def initialize(repository)
39
47
  @repository = repository
40
48
  end
@@ -0,0 +1,13 @@
1
+ module Seory
2
+ module PageCondition
3
+ class BlockCondition
4
+ def initialize(block)
5
+ @block = block
6
+ end
7
+
8
+ def match?(controller)
9
+ @block.call(controller)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'seory/page_condition'
2
+
3
+ module Seory
4
+ module PageCondition
5
+ module BuildDsl
6
+ def slug(slug)
7
+ SlugCondition.new(slug)
8
+ end
9
+
10
+ def path(path)
11
+ PathCondition.new(path)
12
+ end
13
+
14
+ def params(params)
15
+ ParamsCondition.new(params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ module Seory
2
+ module PageCondition
3
+ class DefaultCondition
4
+ def match?(controller)
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,17 @@
1
+ module Seory
2
+ module PageCondition
3
+ class ParamsCondition
4
+ def self.supposable?(condition_object)
5
+ condition_object.is_a?(Hash)
6
+ end
7
+
8
+ def initialize(params)
9
+ @params = params
10
+ end
11
+
12
+ def match?(controller)
13
+ @params.all? {|k, v| controller.params[k] == v }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Seory
2
+ module PageCondition
3
+ class PathCondition
4
+ def initialize(path, exact_match = false)
5
+ @path = path
6
+ @exact_match = exact_match
7
+ end
8
+
9
+ def match?(controller)
10
+ controller.request.fullpath.start_with?(@path)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module Seory
2
+ module PageCondition
3
+ class SlugCondition
4
+ def self.supposable?(condition_object)
5
+ controller, action = condition_object.to_s.split('#')
6
+ controller && action
7
+ end
8
+
9
+ def initialize(slug)
10
+ @slug = slug
11
+ end
12
+
13
+ def match?(controller)
14
+ action_slug(controller) == @slug
15
+ end
16
+
17
+ def action_slug(controller)
18
+ [controller.controller_name, controller.action_name].join('#')
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ require 'seory'
2
+ require 'seory/page_condition/block_condition'
3
+ require 'seory/page_condition/default_condition'
4
+ require 'seory/page_condition/params_condition'
5
+ require 'seory/page_condition/path_condition'
6
+ require 'seory/page_condition/slug_condition'
7
+
8
+ module Seory
9
+ module PageCondition
10
+ class SupposionFailed < Seory::Error; end
11
+ extend self
12
+
13
+ def [](condition)
14
+ if condition == :default
15
+ DefaultCondition.new
16
+ elsif condition.respond_to?(:match?)
17
+ condition
18
+ else
19
+ suppose(condition)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def suppose(condition)
26
+ klass = [ParamsCondition, SlugCondition].detect {|klass| klass.supposable?(condition) }
27
+ raise SupposionFailed.new(condition.inspect) unless klass
28
+
29
+ klass.new(condition)
30
+ end
31
+ end
32
+ end
@@ -1,4 +1,6 @@
1
1
  require 'seory'
2
+ require 'seory/page_condition'
3
+
2
4
  require 'active_support/all'
3
5
 
4
6
  module Seory
@@ -6,7 +8,13 @@ module Seory
6
8
 
7
9
  class PageContents
8
10
  def initialize(*conditions, &block)
9
- @conditions = block_given? ? block : conditions
11
+ @conditions =
12
+ if block_given?
13
+ [PageCondition::BlockCondition.new(block)]
14
+ else
15
+ conditions.map {|condition| Seory::PageCondition[condition] }
16
+ end
17
+
10
18
  raise EmptyCondition if @conditions.blank?
11
19
 
12
20
  @contents = {}
@@ -21,19 +29,13 @@ module Seory
21
29
  end
22
30
 
23
31
  def match?(controller)
24
- return true if @conditions == [:default]
32
+ return true if default?
25
33
 
26
- if @conditions.respond_to?(:call)
27
- @conditions.call(controller)
28
- else
29
- @conditions.include?(action_slug(controller))
30
- end
34
+ @conditions.any? {|condition| condition.match?(controller) }
31
35
  end
32
36
 
33
- private
34
-
35
- def action_slug(controller)
36
- [controller.controller_name, controller.action_name].join('#')
37
+ def default?
38
+ @conditions.all? {|c| c.is_a?(Seory::PageCondition::DefaultCondition) }
37
39
  end
38
40
  end
39
41
  end
@@ -12,7 +12,12 @@ module Seory
12
12
 
13
13
  def lookup(controller)
14
14
  page_contents = @store.detect {|page| page.match?(controller) }
15
- Seory::Runtime.new(page_contents, controller)
15
+
16
+ Seory::Runtime.new(page_contents, controller, default)
17
+ end
18
+
19
+ def default
20
+ @store.detect(&:default?)
16
21
  end
17
22
  end
18
23
  end
data/lib/seory/runtime.rb CHANGED
@@ -8,9 +8,10 @@ module Seory
8
8
 
9
9
  attr_reader :controller
10
10
 
11
- def initialize(page_contents, controller)
11
+ def initialize(page_contents, controller, fallback = nil)
12
12
  @page_contents = page_contents
13
13
  @controller = controller
14
+ @fallback = fallback
14
15
  end
15
16
 
16
17
  def assigns(name)
@@ -28,14 +29,21 @@ module Seory
28
29
  private
29
30
 
30
31
  def calculate_content_for(name)
31
- case page_content = @page_contents.content_for(name)
32
+ case page_content = lookup_content_for(name)
32
33
  when String
33
34
  page_content
35
+ when Symbol
36
+ calculate_content_for(page_content)
34
37
  when ->(o) { o.respond_to?(:call) }
35
38
  instance_exec(&page_content)
36
39
  else
37
40
  raise 'BUG'
38
41
  end
39
42
  end
43
+
44
+ def lookup_content_for(name)
45
+ @page_contents.content_for(name) || \
46
+ @fallback.try {|fb| fb.content_for(name) }
47
+ end
40
48
  end
41
49
  end
data/lib/seory/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Seory
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -2,39 +2,90 @@ require 'spec_helper'
2
2
  require 'seory/dsl'
3
3
 
4
4
  describe Seory::Dsl do
5
- let(:seory_class) { Object.new.extend(Seory::Dsl) }
6
- before do
7
- seory_class.describe do
8
- match 'products#index' do
9
- title 'My Great Product'
10
- h1 'Great Product Name'
11
-
12
- misc :option, 'static optional val'
13
- end
5
+ subject(:seory) { seory_class.lookup(controller) }
6
+
7
+ context 'with traditional syntax' do
8
+ let(:seory_class) { Object.new.extend(Seory::Dsl) }
9
+ before do
10
+ seory_class.describe do
11
+ match ->(c) { c.controller_name == 'reports' } do
12
+ title 'Useful reports'
13
+ end
14
+
15
+ match 'products#index' do
16
+ title 'My Great Product'
17
+ h1 'Great Product Name'
14
18
 
15
- default do
16
- title 'Misc site'
17
- h1 { controller.controller_name.upcase }
19
+ misc :option, 'static optional val'
20
+ end
18
21
 
19
- misc(:option) { "dynamic option name at #{controller.controller_name}" }
22
+ default do
23
+ title 'Misc site'
24
+ h1 { controller.controller_name.upcase }
25
+ h2 'default h2'
26
+
27
+ misc(:option) { "dynamic option name at #{controller.controller_name}" }
28
+ end
20
29
  end
21
30
  end
22
- end
23
31
 
24
- subject(:seory) { seory_class.lookup(controller) }
32
+ context 'at reports#index / match with proc' do
33
+ let(:controller) { double('controller', controller_name: 'reports', action_name: 'index') }
34
+
35
+ specify { expect(seory.title).to eq 'Useful reports' }
36
+ end
37
+
38
+ context 'at products#index' do
39
+ let(:controller) { double('controller', controller_name: 'products', action_name: 'index') }
40
+
41
+ specify { expect(seory.title).to eq 'My Great Product' }
42
+ specify { expect(seory.h1).to eq 'Great Product Name' }
43
+ specify { expect(seory.misc(:option)).to eq 'static optional val' }
44
+
45
+ specify { expect(seory.h2).to eq 'default h2' }
46
+ end
25
47
 
26
- context 'at products#index' do
27
- let(:controller) { double('controller', controller_name: 'products', action_name: 'index') }
48
+ context 'at misc#show' do
49
+ let(:controller) { double('controller', controller_name: 'misc', action_name: 'show') }
28
50
 
29
- specify { expect(seory.title).to eq 'My Great Product' }
30
- specify { expect(seory.h1).to eq 'Great Product Name' }
31
- specify { expect(seory.misc(:option)).to eq 'static optional val' }
51
+ specify { expect(seory.h1).to eq 'MISC' }
52
+ specify { expect(seory.misc(:option)).to eq 'dynamic option name at misc' }
53
+ end
32
54
  end
33
55
 
34
- context 'at misc#show' do
35
- let(:controller) { double('controller', controller_name: 'misc', action_name: 'show') }
56
+ context 'with matcher build dsl syntax' do
57
+ let(:seory_class) { Object.new.extend(Seory::Dsl) }
58
+ before do
59
+ seory_class.describe do
60
+ match path('/products/special-product') do
61
+ title 'Special Product Detail'
62
+ end
63
+
64
+ match slug('products#show') do
65
+ title 'Great Product Detail'
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'at products#show' do
71
+ let(:controller) do
72
+ double('controller', controller_name: 'products', action_name: 'show', params: {id: 42}).tap do |c|
73
+ allow(c).to receive_message_chain(:request, :fullpath) { '/products/42' }
74
+ end
75
+ end
76
+
77
+ specify { expect(seory.title).to eq 'Great Product Detail' }
78
+ end
79
+
80
+ context 'at special product with path /products/special-product (although products#show)' do
81
+ let(:controller) do
82
+ double('controller', controller_name: 'products', action_name: 'show').tap do |c|
83
+ allow(c).to receive_message_chain(:request, :fullpath) { '/products/special-product' }
84
+ end
85
+ end
36
86
 
37
- specify { expect(seory.h1).to eq 'MISC' }
38
- specify { expect(seory.misc(:option)).to eq 'dynamic option name at misc' }
87
+ specify { expect(seory.title).to eq 'Special Product Detail' }
88
+ end
39
89
  end
90
+
40
91
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'seory/page_condition/path_condition'
3
+
4
+ describe Seory::PageCondition::PathCondition do
5
+ let(:controller) { double('controller') }
6
+ let(:path_condition) do
7
+ Seory::PageCondition::PathCondition.new('/users/alice')
8
+ end
9
+
10
+ context 'Accessed to /users/alice (controller: users, action: show, id: alice)' do
11
+ before do
12
+ allow(controller).to receive_message_chain(:request, :fullpath) { '/users/alice' }
13
+ end
14
+
15
+ specify { expect(path_condition.match?(controller)).to be_truthy }
16
+ end
17
+
18
+ context 'Accessed to /users/bob (controller: users, action: show, id: bob)' do
19
+ before do
20
+ allow(controller).to receive_message_chain(:request, :fullpath) { '/users/bob' }
21
+ end
22
+
23
+ specify { expect(path_condition.match?(controller)).to be_falsy }
24
+ end
25
+ end
@@ -26,6 +26,16 @@ describe Seory::PageContents do
26
26
 
27
27
  specify { expect(seory_def.content_for(:title).call).to eq 'A title' }
28
28
  end
29
+
30
+ context 'define aliased content' do
31
+ before do
32
+ seory_def.define(:title) { 'A title' }
33
+
34
+ seory_def.define(:h1, :title)
35
+ end
36
+
37
+ specify { expect(seory_def.content_for(:h1)).to eq :title }
38
+ end
29
39
  end
30
40
 
31
41
  describe 'condition and #match?' do
@@ -58,5 +68,54 @@ describe Seory::PageContents do
58
68
  expect(page_contents.match?(controller)).to be_truthy
59
69
  end
60
70
  end
71
+
72
+ describe 'hash conditions' do
73
+ let(:controller) { double('controller', params: params.with_indifferent_access) }
74
+
75
+ context 'when the condition exactly equals the params' do
76
+ let(:params) { { "controller" => 'users', "action" => 'show' } }
77
+ let(:condition) { { controller: 'users', action: 'show' } }
78
+
79
+ specify do
80
+ expect(init_with(condition).match?(controller)).to be_truthy
81
+ end
82
+ end
83
+
84
+ context 'when the condition is a sub-hash of the params' do
85
+ let(:params) { { "controller" => 'users', "action" => 'show', "id" => "123" } }
86
+ let(:condition) { { controller: 'users', action: 'show' } }
87
+
88
+ specify do
89
+ expect(init_with(condition).match?(controller)).to be_truthy
90
+ end
91
+ end
92
+
93
+ context 'when the condition differs with the params' do
94
+ let(:params) { { "controller" => 'users', "action" => 'show' } }
95
+ let(:condition) { { controller: 'users', action: 'index' } }
96
+
97
+ specify do
98
+ expect(init_with(condition).match?(controller)).to be_falsy
99
+ end
100
+ end
101
+ end
102
+
103
+ describe 'proc conditions' do
104
+ let(:page_content) do
105
+ init_with {|c| c.controller_name == 'users' }
106
+ end
107
+
108
+ specify 'match UsersController' do
109
+ allow(controller).to receive(:controller_name) { 'users' }
110
+
111
+ expect(page_content.match?(controller)).to be_truthy
112
+ end
113
+
114
+ specify 'not match GoodsController' do
115
+ allow(controller).to receive(:controller_name) { 'goods' }
116
+
117
+ expect(page_content.match?(controller)).to be_falsy
118
+ end
119
+ end
61
120
  end
62
121
  end
@@ -46,4 +46,27 @@ describe Seory::Runtime do
46
46
 
47
47
  specify { expect(seory.title).to eq 'Good Shop with 42 products!' }
48
48
  end
49
+
50
+ context 'Custom content created by misc()' do
51
+ before do
52
+ page_contents.define(:custom, 'custom variable')
53
+
54
+ page_contents.define(:title) { misc(:custom).upcase }
55
+ end
56
+
57
+ specify 'it was also accessible from other content' do
58
+ expect(seory.title).to eq 'CUSTOM VARIABLE'
59
+ end
60
+ end
61
+
62
+ context 'defined aliased content' do
63
+ before do
64
+ page_contents.define(:title) { 'A title' }
65
+ page_contents.define(:h1, :title)
66
+ end
67
+
68
+ specify 'it was also accessible from other content' do
69
+ expect(seory.h1).to eq 'A title'
70
+ end
71
+ end
49
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - moro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-05 00:00:00.000000000 Z
11
+ date: 2014-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -62,18 +62,27 @@ extra_rdoc_files: []
62
62
  files:
63
63
  - ".gitignore"
64
64
  - ".rspec"
65
+ - ".travis.yml"
65
66
  - Gemfile
66
67
  - LICENSE.txt
67
68
  - README.md
68
69
  - Rakefile
69
70
  - lib/seory.rb
70
71
  - lib/seory/dsl.rb
72
+ - lib/seory/page_condition.rb
73
+ - lib/seory/page_condition/block_condition.rb
74
+ - lib/seory/page_condition/build_dsl.rb
75
+ - lib/seory/page_condition/default_condition.rb
76
+ - lib/seory/page_condition/params_condition.rb
77
+ - lib/seory/page_condition/path_condition.rb
78
+ - lib/seory/page_condition/slug_condition.rb
71
79
  - lib/seory/page_contents.rb
72
80
  - lib/seory/repository.rb
73
81
  - lib/seory/runtime.rb
74
82
  - lib/seory/version.rb
75
83
  - seory.gemspec
76
84
  - spec/seory/dsl_spec.rb
85
+ - spec/seory/page_condition/path_condition_spec.rb
77
86
  - spec/seory/page_contents_spec.rb
78
87
  - spec/seory/runtime_spec.rb
79
88
  - spec/spec_helper.rb
@@ -103,6 +112,7 @@ specification_version: 4
103
112
  summary: SEO contents manager for Rails.
104
113
  test_files:
105
114
  - spec/seory/dsl_spec.rb
115
+ - spec/seory/page_condition/path_condition_spec.rb
106
116
  - spec/seory/page_contents_spec.rb
107
117
  - spec/seory/runtime_spec.rb
108
118
  - spec/spec_helper.rb