seory 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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