seory 0.0.4 → 0.1.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +1 -0
  4. data/README.md +20 -17
  5. data/lib/seory.rb +25 -4
  6. data/lib/seory/condition.rb +29 -0
  7. data/lib/seory/{page_condition/block_condition.rb → condition/block.rb} +2 -2
  8. data/lib/seory/condition/build_dsl.rb +19 -0
  9. data/lib/seory/{page_condition/params_condition.rb → condition/params.rb} +2 -2
  10. data/lib/seory/{page_condition/path_condition.rb → condition/path.rb} +2 -2
  11. data/lib/seory/{page_condition/slug_condition.rb → condition/slug.rb} +5 -3
  12. data/lib/seory/dsl.rb +12 -49
  13. data/lib/seory/dsl/descriptor.rb +29 -0
  14. data/lib/seory/dsl/page_builder.rb +35 -0
  15. data/lib/seory/page.rb +53 -0
  16. data/lib/seory/page_group.rb +15 -0
  17. data/lib/seory/rails_helper.rb +7 -0
  18. data/lib/seory/railtie.rb +11 -0
  19. data/lib/seory/repository.rb +40 -6
  20. data/lib/seory/runtime.rb +13 -6
  21. data/lib/seory/version.rb +1 -1
  22. data/seory.gemspec +1 -0
  23. data/spec/seory/{page_condition/path_condition_spec.rb → condition/path_spec.rb} +3 -3
  24. data/spec/seory/condition/slug_spec.rb +18 -0
  25. data/spec/seory/dsl_spec.rb +23 -5
  26. data/spec/seory/{page_contents_spec.rb → page_spec.rb} +12 -12
  27. data/spec/seory/rails_helper_spec.rb +62 -0
  28. data/spec/seory/repository_spec.rb +103 -0
  29. data/spec/seory/runtime_spec.rb +25 -6
  30. data/spec/spec_helper.rb +8 -0
  31. data/spec/support/controller_double.rb +37 -0
  32. data/spec/support/testing_dsl.rb +7 -0
  33. data/spec/support/view_context_double.rb +13 -0
  34. metadata +44 -14
  35. data/lib/seory/page_condition.rb +0 -32
  36. data/lib/seory/page_condition/build_dsl.rb +0 -19
  37. data/lib/seory/page_condition/default_condition.rb +0 -10
  38. data/lib/seory/page_contents.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4ad5a6d00f1d68662b39cb9716d1146b182688c
4
- data.tar.gz: 847f039ab50d26b966e03b1f1175554d77ee6cb2
3
+ metadata.gz: 679ed7e93f25e0539660873f3b4ad92d89327082
4
+ data.tar.gz: 514f420b0f775555ee3d736120aa7c4a898e1bd1
5
5
  SHA512:
6
- metadata.gz: 912cc7524283289708d5d852510c9a077dd60093521521a3eff1bb759891404abdf405b10e55fdb6e06255124047dcf1a622b00b5fcf50b440acb41e5f85810b
7
- data.tar.gz: 8f64f9624cc492e8537d2e75b69c77595e4050c44c10d870cef44ac17134b2123a1f78a48467606c0524d2d6466399e802e72089a355592dbb1770013c995a4a
6
+ metadata.gz: 66e97190536b1dd87c7b3396a9d3c93e23da823530965565e399266d2a9f8680c358f1b00ec7ed19a8da1687902d2403ac4ef46c96e5119fb50f563368a2b19e
7
+ data.tar.gz: 50eb55d2c9df67fd68c8c2fb0e6b6271a96b32cda1dedac10a09fd6e0e6f3e61704594f3e46b125f1076640786d5f9225088e7af5190fac436caa9034dca4ac1
@@ -3,6 +3,8 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1
6
+ env:
7
+ - secure: "d3P4g1NRNxoCuhCHaqpNI6Khe6d/5jYpR0VJoxAvw5n2c46KuMn91IMTmTAF73vb7n8kQAXA347x53KBdgsBlmm6upaBKG8NrWiLgO16frTlmtUf1ng6VZzM3vqQjjo1YZLhM+kk3AoXgqZsSMwfgOo9BFQj6fYRwlveuJ+vrVM="
6
8
  notifications:
7
9
  webhooks:
8
10
  - https://idobata.io/hook/061179f9-4f3c-4c8c-bdf9-4efa9821c5c5
data/Gemfile CHANGED
@@ -4,3 +4,4 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'rspec', '>= 3.0.0'
7
+ gem 'codeclimate-test-reporter', group: :test, require: false
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # seory
2
2
 
3
+ [![Build Status](https://travis-ci.org/esminc/seory.svg?branch=master)](https://travis-ci.org/esminc/seory)
4
+ [![Code Climate](https://codeclimate.com/github/esminc/seory.png)](https://codeclimate.com/github/esminc/seory)
5
+
3
6
  Manage SEO contents in Rails app. based on controller, action and more complex context.
4
7
 
5
8
  ## Installation
@@ -22,19 +25,19 @@ Specify SEO content as ruby code. For example, `config/initializers/seory.rb`
22
25
 
23
26
  ```ruby
24
27
  # Specify SEO content based on `controller#action` rule
25
- match *%w[products#popular products#new_release] {
26
- title: 'Great products | My Great Site[MGS]'
27
- desc: 'A lot of greate products'
28
+ match *%w[products#popular products#new_release] do
29
+ title 'Great products | My Great Site[MGS]'
30
+ meta_description 'A lot of great products'
28
31
 
29
- keywords: %w[Software Internet Service]
32
+ meta_keywords %w[Software Internet Service].join(',')
30
33
 
31
- h1: 'Most popular products'
32
- }
34
+ h1 'Most popular products'
35
+ end
33
36
 
34
37
  # Can contain dynamic content based on controller using assigned ivar
35
- match slug('brands#show') {
36
- title { assign(:brand).name }
37
- }
38
+ match slug('brands#show') do
39
+ title { assigns(:brand).name }
40
+ end
38
41
 
39
42
  # Match with request fullpath
40
43
  match path('/products/special-product') do
@@ -43,26 +46,26 @@ end
43
46
 
44
47
  # Custom lookup rule with controller
45
48
  match(->(controller) { controller.params[:page].to_i == 1 }) do
46
- keywords do
47
- search = assign(:search_object)
49
+ meta_keywords do
50
+ search = assigns(:search_object)
48
51
 
49
52
  # do something
50
53
  end
51
54
  end
52
55
 
53
56
  # Use custom word part
54
- match slug(products#index) do
57
+ match slug('products#index') do
55
58
  misc(:page_name) { "#{controller.params[:page].to_i} page | Good products") }
56
59
 
57
- title :page_name
58
- h1 :page_name
60
+ title :page_name
61
+ h1 :page_name
59
62
 
60
- desc { "Page for #{page_name}" }
63
+ meta_description { "Page for #{page_name}" }
61
64
  }
62
65
 
63
66
  default do
64
- title 'My Great Service'
65
- h1 { I18n.t("#{controller_name}.h1", scope: 'label.misc_pages' }
67
+ title 'My Great Service'
68
+ h1 { I18n.t("#{controller_name}.h1", scope: 'label.misc_pages' }
66
69
  end
67
70
  ```
68
71
 
@@ -1,10 +1,31 @@
1
- require "seory/version"
1
+ require 'seory/version'
2
+ require 'seory/railtie' if defined?(Rails)
3
+ require 'active_support/all'
2
4
 
3
5
  module Seory
4
6
  CONTENTS = %w[title h1 h2 meta_description meta_keywords canonical_url og_image_url].map(&:to_sym)
5
7
 
6
- class Error < RuntimeError
7
- end
8
+ class Error < RuntimeError; end
9
+
10
+ autoload :Dsl,'seory/dsl'
11
+
12
+ mattr_accessor(:config_dir) { 'config/seory' }
13
+ self.config_dir = 'config/seory'
14
+
15
+ class << self
16
+ def describe(*args, &block)
17
+ @object ||= Object.new.tap {|obj| obj.extend Seory::Dsl }
8
18
 
9
- autoload :Dsl, 'seory/dsl'
19
+ @object.describe(*args, &block)
20
+ end
21
+ alias seo_content describe
22
+
23
+ def helper(&block)
24
+ @object.helper(&block)
25
+ end
26
+
27
+ def default_repository
28
+ @object.send(:seory_repository)
29
+ end
30
+ end
10
31
  end
@@ -0,0 +1,29 @@
1
+ require 'seory'
2
+ require 'seory/condition/block'
3
+ require 'seory/condition/params'
4
+ require 'seory/condition/path'
5
+ require 'seory/condition/slug'
6
+
7
+ module Seory
8
+ module Condition
9
+ class SupposionFailed < Seory::Error; end
10
+ extend self
11
+
12
+ def [](condition)
13
+ if condition.respond_to?(:match?)
14
+ condition
15
+ else
16
+ suppose(condition)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def suppose(condition)
23
+ condition_class = [Params, Slug].detect {|klass| klass.supposable?(condition) }
24
+ raise SupposionFailed.new(condition.inspect) unless condition_class
25
+
26
+ condition_class.new(condition)
27
+ end
28
+ end
29
+ end
@@ -1,6 +1,6 @@
1
1
  module Seory
2
- module PageCondition
3
- class BlockCondition
2
+ module Condition
3
+ class Block
4
4
  def initialize(block)
5
5
  @block = block
6
6
  end
@@ -0,0 +1,19 @@
1
+ require 'seory/condition'
2
+
3
+ module Seory
4
+ module Condition
5
+ module BuildDsl
6
+ def slug(slug)
7
+ Slug.new(slug)
8
+ end
9
+
10
+ def path(path)
11
+ Path.new(path)
12
+ end
13
+
14
+ def params(params)
15
+ Params.new(params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,6 @@
1
1
  module Seory
2
- module PageCondition
3
- class ParamsCondition
2
+ module Condition
3
+ class Params
4
4
  def self.supposable?(condition_object)
5
5
  condition_object.is_a?(Hash)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  module Seory
2
- module PageCondition
3
- class PathCondition
2
+ module Condition
3
+ class Path
4
4
  def initialize(path, exact_match = false)
5
5
  @path = path
6
6
  @exact_match = exact_match
@@ -1,6 +1,6 @@
1
1
  module Seory
2
- module PageCondition
3
- class SlugCondition
2
+ module Condition
3
+ class Slug
4
4
  def self.supposable?(condition_object)
5
5
  controller, action = condition_object.to_s.split('#')
6
6
  controller && action
@@ -14,8 +14,10 @@ module Seory
14
14
  action_slug(controller) == @slug
15
15
  end
16
16
 
17
+ private
18
+
17
19
  def action_slug(controller)
18
- [controller.controller_name, controller.action_name].join('#')
20
+ [controller.controller_path, controller.action_name].join('#')
19
21
  end
20
22
  end
21
23
  end
@@ -1,65 +1,28 @@
1
1
  require 'seory'
2
- require 'seory/page_contents'
3
- require 'seory/page_condition/build_dsl'
4
2
  require 'seory/repository'
5
3
 
6
4
  module Seory
7
5
  module Dsl
6
+ def describe(group_name = Repository.extract_label_from_trace(caller), &block)
7
+ seory_repository << Descriptor.new(group_name, seory_repository).describe(&block)
8
+ end
9
+ alias seo_content describe
8
10
 
9
- def describe(&block)
10
- @repository = Repository.new
11
- Descriptor.new(@repository).describe(&block)
11
+ def helper(&block)
12
+ seory_repository.helper = Module.new(&block)
12
13
  end
13
14
 
14
15
  def lookup(controller)
15
- @repository.lookup(controller)
16
+ seory_repository.lookup(controller)
16
17
  end
17
18
 
18
- class PageContentsBuilder
19
- def initialize(*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
26
- end
27
-
28
- def build!(&block)
29
- instance_exec(&block)
30
-
31
- @page_contents
32
- end
19
+ private
33
20
 
34
- def misc(name, val = nil, &block)
35
- @page_contents.define(name, val, &block)
36
- end
37
-
38
- Seory::CONTENTS.each do |name|
39
- define_method(name) {|val = nil, &block| misc(name, val, &block) }
40
- end
21
+ def seory_repository
22
+ @__seory_repository ||= Repository.new
41
23
  end
42
24
 
43
- class Descriptor
44
- include Seory::PageCondition::BuildDsl
45
-
46
- def initialize(repository)
47
- @repository = repository
48
- end
49
-
50
- def describe(&block)
51
- instance_exec(&block)
52
-
53
- @repository
54
- end
55
-
56
- def match(*conditions, &def_builder)
57
- @repository << PageContentsBuilder.new(*conditions).build!(&def_builder)
58
- end
59
-
60
- def default(&def_builder)
61
- match(:default, &def_builder)
62
- end
63
- end
25
+ autoload :PageBuilder, 'seory/dsl/page_builder'
26
+ autoload :Descriptor, 'seory/dsl/descriptor'
64
27
  end
65
28
  end
@@ -0,0 +1,29 @@
1
+ require 'seory/page_group'
2
+ require 'seory/condition/build_dsl'
3
+
4
+ module Seory
5
+ module Dsl
6
+ class Descriptor
7
+ include Seory::Condition::BuildDsl
8
+
9
+ def initialize(group_name, repository)
10
+ @page_group = PageGroup.new(group_name)
11
+ @repository = repository
12
+ end
13
+
14
+ def describe(&block)
15
+ instance_exec(&block)
16
+
17
+ @page_group
18
+ end
19
+
20
+ def match(*conditions, &def_builder)
21
+ @page_group.add PageBuilder.new(*conditions).build!(&def_builder)
22
+ end
23
+
24
+ def default(&def_builder)
25
+ @page_group.default = PageBuilder.new(:default).build!(&def_builder)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require 'seory'
2
+ require 'seory/page'
3
+
4
+ module Seory
5
+ module Dsl
6
+ class PageBuilder
7
+ def initialize(*conditions)
8
+ @page_contents =
9
+ if conditions.size == 1 && (block = conditions.first).is_a?(Proc)
10
+ Page.new(&block)
11
+ else
12
+ Page.new(*conditions)
13
+ end
14
+ end
15
+
16
+ def build!(&block)
17
+ instance_exec(&block)
18
+
19
+ @page_contents
20
+ end
21
+
22
+ def misc(name, val = nil, &block)
23
+ @page_contents.define(name, val, &block)
24
+ end
25
+
26
+ def assign_reader(*names)
27
+ @page_contents.assign_reader(*names)
28
+ end
29
+
30
+ Seory::CONTENTS.each do |name|
31
+ define_method(name) {|val = nil, &block| misc(name, val, &block) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,53 @@
1
+ require 'seory'
2
+ require 'seory/condition'
3
+
4
+ module Seory
5
+ class EmptyCondition < ::Seory::Error; end
6
+ class AccessorNameTaken < ::Seory::Error; end
7
+
8
+ class Page
9
+
10
+ attr_reader :assign_name_accessors
11
+
12
+ def initialize(*conditions, &block)
13
+ @conditions =
14
+ if block_given?
15
+ [Condition::Block.new(block)]
16
+ elsif conditions.first == :default
17
+ :default
18
+ else
19
+ conditions.map {|condition| Seory::Condition[condition] }
20
+ end
21
+
22
+ raise EmptyCondition if @conditions.blank?
23
+
24
+ @contents, @assign_name_accessors = {}, []
25
+ end
26
+
27
+ def define(name, value = nil, &block)
28
+ @contents[name] = block_given? ? block : value
29
+ end
30
+
31
+ def assign_reader(*assign_names)
32
+ if (taken = Seory::CONTENTS & assign_names).size > 0
33
+ raise AccessorNameTaken, taken.join(', ')
34
+ end
35
+
36
+ assign_name_accessors.concat(assign_names)
37
+ end
38
+
39
+ def content_for(name)
40
+ @contents[name]
41
+ end
42
+
43
+ def match?(controller)
44
+ return true if default?
45
+
46
+ @conditions.any? {|condition| condition.match?(controller) }
47
+ end
48
+
49
+ def default?
50
+ @conditions == :default
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,15 @@
1
+ module Seory
2
+ class PageGroup
3
+ attr_accessor :default
4
+ attr_reader :name, :pages
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ @pages = []
9
+ end
10
+
11
+ def add(page)
12
+ @pages << page
13
+ end
14
+ end
15
+ end