seoable 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0577d6ed10e221b6cc4f7b5d9ffefbc47d610b93
4
+ data.tar.gz: 10595cecad4276633a6ebded8e78abe493a3f937
5
+ SHA512:
6
+ metadata.gz: ed0f7c01da7fb91ddbdcdc423ef223b1dcc67b9c5c16be4278883402fcf247743f6f9619c83c22c80ba326334d8bd685f4b241a20bc82416ffe2910e257aba37
7
+ data.tar.gz: 93db9f50947c61bef94d9437c2a7eecf4ed1910ec7e4fca76f1b9b15af9ff4356a4873a944a4557790b6255bb801a3e4ddaebdc63090622c879cf5604222eab2
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in seoable.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,46 @@
1
+
2
+ # A sample Guardfile
3
+ # More info at https://github.com/guard/guard#readme
4
+
5
+ ## Uncomment and set this to only include directories you want to watch
6
+ # directories %w(app lib config test spec features) \
7
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
8
+
9
+ ## Note: if you are using the `directories` clause above and you are not
10
+ ## watching the project directory ('.'), then you will want to move
11
+ ## the Guardfile to a watched dir and symlink it back, e.g.
12
+ #
13
+ # $ mkdir config
14
+ # $ mv Guardfile config/
15
+ # $ ln -s config/Guardfile .
16
+ #
17
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
18
+
19
+ # Note: The cmd option is now required due to the increasing number of ways
20
+ # rspec may be run, below are examples of the most common uses.
21
+ # * bundler: 'bundle exec rspec'
22
+ # * bundler binstubs: 'bin/rspec'
23
+ # * spring: 'bin/rspec' (This will use spring if running and you have
24
+ # installed the spring binstubs per the docs)
25
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
26
+ # * 'just' rspec: 'rspec'
27
+
28
+ guard :rspec, cmd: 'bundle exec rspec' do
29
+ require 'guard/rspec/dsl'
30
+ dsl = Guard::RSpec::Dsl.new(self)
31
+
32
+ # RSpec files
33
+ rspec = dsl.rspec
34
+ watch(rspec.spec_helper) { rspec.spec_dir }
35
+ watch(rspec.spec_support) { rspec.spec_dir }
36
+ watch(rspec.spec_files)
37
+
38
+ # Ruby files
39
+ ruby = dsl.ruby
40
+ dsl.watch_spec_files_for(ruby.lib_files)
41
+
42
+ # watch /app files
43
+ watch(%r{^app/(.+)/seoable/(.+).rb$}) do |m|
44
+ "spec/#{m[1]}/#{m[2]}_spec.rb"
45
+ end
46
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Viktor Fonic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Seoable
2
+
3
+ Make your ActiveRecords SEO friendly.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'seoable'
11
+ ```
12
+
13
+ Execute:
14
+
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Run the `install generator`:
20
+
21
+ ```sh
22
+ $ rails generate seoable:install
23
+ ```
24
+
25
+ The generator:
26
+
27
+ * Creates an initializer to allow further configuration
28
+ * Creates a migration for seo_details table
29
+
30
+ ## Configure
31
+
32
+ Override the defaults in `config/initializers/seoable.rb`:
33
+
34
+ ```ruby
35
+ Seoable.configure do |config|
36
+ config.default_title = 'My app name'
37
+ config.default_description = 'The best app in the known universe'
38
+ config.sluggable_attributes = [:title, :headline]
39
+ end
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ Add `include Seoable::ActsAsSeoable` to any ActiveRecord you want to make Seoable:
45
+
46
+ ```ruby
47
+ class Post < ActiveRecord::Base
48
+ include Seoable::ActsAsSeoable
49
+ end
50
+ ```
51
+
52
+ In your application layout file (probably `app/views/layouts/application.html.erb`):
53
+
54
+ Replace this line:
55
+
56
+ ```erb
57
+ <title>ApplicationName</title>
58
+ ```
59
+
60
+ With this line:
61
+
62
+ ```erb
63
+ <title><%= seoable_title %></title>
64
+ ```
65
+
66
+ Add the following line below `<title>`:
67
+
68
+ ```erb
69
+ <meta name="description" content="<%= seoable_description %>" />
70
+ ```
71
+
72
+ ## Adding to existing app
73
+
74
+ If you’re adding seoable to existing app and want to generate SeoDetails for existing records, perform save for every model that includes ActsAsSeoable. You can do this from the console, runner or add a Rake task. For example:
75
+
76
+ ```ruby
77
+ Post.find_each(&:save)
78
+ ```
79
+
80
+ ## Troubleshooting
81
+
82
+ ### Column reference is ambiguous
83
+
84
+ If you see the error similar to `column reference "id" is ambiguous`, it’s due to including `seo_details` table through `default_scope`. To fix this, specify table name in your queries, like this:
85
+
86
+ ```ruby
87
+ scope :only_big_ids, -> { where('"posts"."id" > 3') }
88
+ ```
89
+
90
+ ## Development
91
+
92
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec` to run the tests.
93
+
94
+ To install the gem with your changes onto your local machine, run `rake install`.
95
+
96
+ ## TODO
97
+
98
+ You’re more than welcome to send us pull-requests. Here’s the list of TODO items we’re looking to work on in the future:
99
+
100
+ * Add functionality to set default_title and default_description per model
101
+ * Add title_format configuration variable
102
+ * Create redirect on Seoable model save
103
+ * Add caching
104
+ * Integrate with ActiveAdmin (but have it optional)
105
+
106
+ ## Contributing
107
+
108
+ Bug reports and pull requests are welcome on GitHub at https://github.com/DVELP/seoable. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
109
+
110
+ ## License
111
+
112
+ Seoable is copyright of DVELP Ltd. It is free software and available to distribute under the terms of the [MIT License](http://opensource.org/licenses/MIT).
113
+
114
+ <br></br>
115
+ [![DVELP logo](https://raw.githubusercontent.com/DVELP/cookbook/master/assets/dvelp-logo.png "DVELP logo")](http://dvelp.co.uk)
116
+
117
+ Seoable was created and is maintained by DVELP Ltd.
118
+
119
+ If you like what you see and would like to hire us or join us, [get in touch](http://dvelp.co.uk)!
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,15 @@
1
+ module Seoable
2
+ module ApplicationHelper
3
+ def seoable_title
4
+ @seo_detail ? @seo_detail.meta_title : Seoable.configuration.default_title
5
+ end
6
+
7
+ def seoable_description
8
+ if @seo_detail && @seo_detail.meta_description.present?
9
+ @seo_detail.meta_description
10
+ else
11
+ Seoable.configuration.default_description
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ module Seoable
2
+ module ActsAsSeoable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ cattr_accessor :acts_as_seoable
7
+
8
+ extend FriendlyId
9
+ friendly_id :slug, use: :finders
10
+
11
+ default_scope { joins_seo_detail }
12
+ scope :joins_seo_detail, -> { includes(:seo_detail) }
13
+
14
+ has_one :seo_detail,
15
+ as: :seoable,
16
+ dependent: :destroy,
17
+ class_name: SeoDetail
18
+
19
+ accepts_nested_attributes_for :seo_detail, reject_if: :all_blank
20
+
21
+ delegate :meta_title, to: :seo_detail, allow_nil: true
22
+ delegate :meta_description, to: :seo_detail, allow_nil: true
23
+ delegate :slug, to: :seo_detail, allow_nil: true
24
+ end
25
+
26
+ def seo_detail
27
+ super || build_seo_detail(seo_detail_attributes)
28
+ end
29
+
30
+ def seo_detail_attributes
31
+ {
32
+ meta_title: sluggable,
33
+ seoable: self,
34
+ slug: sluggable.to_slug
35
+ }
36
+ end
37
+
38
+ private
39
+
40
+ def sluggable
41
+ attribute = Seoable.configuration
42
+ .sluggable_attributes.find do |sluggable_attribute|
43
+ self.respond_to?(sluggable_attribute)
44
+ end
45
+ send(attribute).to_s
46
+ end
47
+ end
48
+ end
49
+
50
+ module FriendlyId
51
+ module FinderMethods
52
+ def first_by_friendly_id(id)
53
+ find_by('"seo_details".' + friendly_id_config.query_field => id)
54
+ end
55
+ end
56
+ end
57
+
58
+ class String
59
+ def to_slug
60
+ parameterize
61
+ end
62
+ end
@@ -0,0 +1,13 @@
1
+ module Seoable
2
+ class SeoDetail < ActiveRecord::Base
3
+ cattr_accessor :permitted_attribute_names
4
+ @@permitted_attribute_names = [:meta_title, :meta_description, :slug]
5
+
6
+ belongs_to :seoable, polymorphic: true
7
+
8
+ validates :meta_title, presence: true, uniqueness: { scope: :seoable_type }
9
+ validates :slug,
10
+ uniqueness: { scope: :seoable_type },
11
+ format: /\A[a-z0-9-]+\z/
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ module Seoable
2
+ class Loader
3
+ def initialize(controller_name, slug)
4
+ @model_name = controller_name.classify
5
+ @slug = slug
6
+ end
7
+
8
+ def load
9
+ return nil unless seoable_model?
10
+
11
+ SeoDetail.where(seoable_type: model, slug: @slug).first
12
+ end
13
+
14
+ private
15
+
16
+ def model
17
+ model = @model_name.constantize
18
+ model = model.superclass if model.superclass != ActiveRecord::Base
19
+ model
20
+ end
21
+
22
+ def seoable_model?
23
+ return false unless Object.const_defined?(@model_name)
24
+ const = Object.const_get(@model_name)
25
+ const.respond_to?(:acts_as_seoable)
26
+ end
27
+ end
28
+ end
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'seoable'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require 'pry'
10
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/config.ru ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require :default, :development
5
+
6
+ Combustion.initialize! :all
7
+ run Combustion::Application
@@ -0,0 +1,26 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Seoable
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include ::Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ desc 'Installs Seoable and generates the necessary migrations'
11
+
12
+ def create_migrations
13
+ migration_template 'create_seo_details.rb',
14
+ 'db/migrate/create_seo_details.rb'
15
+ end
16
+
17
+ def create_initializer
18
+ copy_file 'initializers/seoable.rb', 'config/initializers/seoable.rb'
19
+ end
20
+
21
+ def self.next_migration_number(dirname)
22
+ ActiveRecord::Generators::Base.next_migration_number(dirname)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ class CreateSeoDetails < ActiveRecord::Migration
2
+ def change
3
+ create_table :seo_details do |t|
4
+ t.string :meta_title
5
+ t.text :meta_description
6
+ t.string :slug
7
+ t.string :seoable_type
8
+ t.integer :seoable_id
9
+
10
+ t.timestamps null: false
11
+ end
12
+
13
+ add_index :seo_details, :seoable_type
14
+ add_index :seo_details, [:seoable_type, :seoable_id], unique: true
15
+ add_index :seo_details, [:seoable_type, :slug], unique: true
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ Seoable.configure do |config|
2
+ # config.default_title = Rails.application.class.parent_name
3
+ # config.default_description = config.default_title
4
+ # config.sluggable_attributes = [:full_name, :name, :title]
5
+ end
@@ -0,0 +1,23 @@
1
+ module Seoable
2
+ class Configuration
3
+ attr_accessor :default_title, :default_description, :sluggable_attributes
4
+
5
+ def initialize
6
+ @default_title = Rails.application.class.parent_name
7
+ @default_description = @default_title
8
+ @sluggable_attributes = [:full_name, :name, :title]
9
+ end
10
+ end
11
+
12
+ def self.configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def self.configuration=(config)
17
+ @configuration = config
18
+ end
19
+
20
+ def self.configure
21
+ yield configuration
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails/engine'
2
+ require 'seoable/seo_loader'
3
+
4
+ module Seoable
5
+ class Engine < ::Rails::Engine
6
+ initializer 'seoable.action_controller' do
7
+ ActiveSupport.on_load(:action_controller) do
8
+ include SeoLoader
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Seoable
2
+ module SeoLoader
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ prepend_before_action :load_seo_detail, only: [:index, :show]
7
+ end
8
+
9
+ def load_seo_detail
10
+ seo_detail_loader = Loader.new(controller_name, params[:id])
11
+ @seo_detail = seo_detail_loader.load
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Seoable
2
+ VERSION = '0.1.6'
3
+ end
data/lib/seoable.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'seoable/configuration'
2
+ require 'seoable/engine'
3
+ require 'friendly_id'
4
+
5
+ module Seoable
6
+ end
data/seoable.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'seoable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'seoable'
8
+ spec.version = Seoable::VERSION
9
+ spec.authors = ['Viktor Fonic', 'Tom Mullen']
10
+ spec.email = ['viktor@dvelp.co.uk', 'tom@dvelp.co.uk']
11
+
12
+ spec.summary = 'Make your webapp Search Engine friendly'
13
+ spec.homepage = 'http://dvelp.co.uk'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_dependency 'friendly_id', '>= 5.0.0'
25
+ spec.add_dependency 'rails'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.10'
28
+ spec.add_development_dependency 'combustion'
29
+ spec.add_development_dependency 'factory_girl_rails'
30
+ spec.add_development_dependency 'guard'
31
+ spec.add_development_dependency 'guard-rspec'
32
+ spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'pry'
34
+ spec.add_development_dependency 'rspec'
35
+ spec.add_development_dependency 'rspec-rails'
36
+ spec.add_development_dependency 'shoulda-matchers'
37
+ spec.add_development_dependency 'sqlite3'
38
+ end
metadata ADDED
@@ -0,0 +1,253 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seoable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - Viktor Fonic
8
+ - Tom Mullen
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-11-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: friendly_id
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 5.0.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 5.0.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.10'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.10'
56
+ - !ruby/object:Gem::Dependency
57
+ name: combustion
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: factory_girl_rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: guard
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: guard-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '10.0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '10.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: pry
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: rspec
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: rspec-rails
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: shoulda-matchers
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: sqlite3
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ description:
197
+ email:
198
+ - viktor@dvelp.co.uk
199
+ - tom@dvelp.co.uk
200
+ executables: []
201
+ extensions: []
202
+ extra_rdoc_files: []
203
+ files:
204
+ - ".gitignore"
205
+ - ".rspec"
206
+ - CODE_OF_CONDUCT.md
207
+ - Gemfile
208
+ - Guardfile
209
+ - LICENSE.txt
210
+ - README.md
211
+ - Rakefile
212
+ - app/helpers/seoable/application_helper.rb
213
+ - app/models/concerns/seoable/acts_as_seoable.rb
214
+ - app/models/seoable/seo_detail.rb
215
+ - app/services/seoable/loader.rb
216
+ - bin/console
217
+ - bin/setup
218
+ - config.ru
219
+ - lib/generators/seoable/install_generator.rb
220
+ - lib/generators/seoable/templates/create_seo_details.rb
221
+ - lib/generators/seoable/templates/initializers/seoable.rb
222
+ - lib/seoable.rb
223
+ - lib/seoable/configuration.rb
224
+ - lib/seoable/engine.rb
225
+ - lib/seoable/seo_loader.rb
226
+ - lib/seoable/version.rb
227
+ - seoable.gemspec
228
+ homepage: http://dvelp.co.uk
229
+ licenses:
230
+ - MIT
231
+ metadata: {}
232
+ post_install_message:
233
+ rdoc_options: []
234
+ require_paths:
235
+ - lib
236
+ required_ruby_version: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ required_rubygems_version: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ version: '0'
246
+ requirements: []
247
+ rubyforge_project:
248
+ rubygems_version: 2.4.6
249
+ signing_key:
250
+ specification_version: 4
251
+ summary: Make your webapp Search Engine friendly
252
+ test_files: []
253
+ has_rdoc: