seorel 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +139 -0
  3. data/Rakefile +40 -0
  4. data/app/models/seorel/seorel.rb +27 -0
  5. data/app/uploaders/seorel/image_uploader.rb +53 -0
  6. data/config/locales/en.seorel.yml +16 -0
  7. data/config/locales/it.seorel.yml +17 -0
  8. data/config/routes.rb +2 -0
  9. data/db/migrate/20120822091543_create_seorel_seorels.rb +16 -0
  10. data/lib/generators/seorel/USAGE +8 -0
  11. data/lib/generators/seorel/config_generator.rb +12 -0
  12. data/lib/generators/seorel/templates/seorel_config.rb +8 -0
  13. data/lib/seorel/config.rb +46 -0
  14. data/lib/seorel/controller/class_methods.rb +16 -0
  15. data/lib/seorel/controller/instance_methods.rb +42 -0
  16. data/lib/seorel/controller/params.rb +36 -0
  17. data/lib/seorel/engine.rb +19 -0
  18. data/lib/seorel/helper.rb +43 -0
  19. data/lib/seorel/model/base.rb +32 -0
  20. data/lib/seorel/model/class_methods.rb +12 -0
  21. data/lib/seorel/model/instance_methods.rb +31 -0
  22. data/lib/seorel/seorelify.rb +20 -0
  23. data/lib/seorel/version.rb +3 -0
  24. data/lib/seorel.rb +16 -0
  25. data/lib/tasks/seorel_tasks.rake +9 -0
  26. data/test/dummy/README.rdoc +261 -0
  27. data/test/dummy/Rakefile +7 -0
  28. data/test/dummy/app/assets/javascripts/application.js +15 -0
  29. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  30. data/test/dummy/app/controllers/application_controller.rb +3 -0
  31. data/test/dummy/app/helpers/application_helper.rb +2 -0
  32. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  33. data/test/dummy/config/application.rb +59 -0
  34. data/test/dummy/config/boot.rb +10 -0
  35. data/test/dummy/config/database.yml +25 -0
  36. data/test/dummy/config/environment.rb +5 -0
  37. data/test/dummy/config/environments/development.rb +37 -0
  38. data/test/dummy/config/environments/production.rb +67 -0
  39. data/test/dummy/config/environments/test.rb +37 -0
  40. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/test/dummy/config/initializers/inflections.rb +15 -0
  42. data/test/dummy/config/initializers/mime_types.rb +5 -0
  43. data/test/dummy/config/initializers/secret_token.rb +7 -0
  44. data/test/dummy/config/initializers/session_store.rb +8 -0
  45. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  46. data/test/dummy/config/locales/en.yml +5 -0
  47. data/test/dummy/config/routes.rb +4 -0
  48. data/test/dummy/config.ru +4 -0
  49. data/test/dummy/public/404.html +26 -0
  50. data/test/dummy/public/422.html +26 -0
  51. data/test/dummy/public/500.html +25 -0
  52. data/test/dummy/public/favicon.ico +0 -0
  53. data/test/dummy/script/rails +6 -0
  54. data/test/fixtures/seorel/seorels.yml +11 -0
  55. data/test/integration/navigation_test.rb +10 -0
  56. data/test/seorel_test.rb +7 -0
  57. data/test/test_helper.rb +15 -0
  58. data/test/unit/seorel/seorel_test.rb +9 -0
  59. metadata +200 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Andrea Dal Ponte
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # Seorel
2
+
3
+ Ruby on Rails SEO Metatags plugins for ActiveRecord models
4
+
5
+ ## Rails Setup
6
+
7
+
8
+ `Gemfile.rb`:
9
+
10
+ ```ruby
11
+ gem 'seorel', github: 'dalpo/seorel'
12
+ ```
13
+
14
+ `Console`:
15
+ ```bash
16
+ % bundle install
17
+ % bundle exec rake seorel:install:migrations
18
+ % bundle exec rake db:migrate
19
+ ```
20
+
21
+ ## Default configuration options
22
+
23
+ ```bash
24
+ % rails generate seorel:config
25
+ ```
26
+
27
+ Will generate the `seorel_config.rb` initializer to customize the default values:
28
+
29
+ ```ruby
30
+ Seorel.configure do |config|
31
+ # config.default_title = nil
32
+ # config.default_description = nil
33
+ # config.default_image = nil
34
+ # config.prepend_title = nil
35
+ # config.append_title = nil
36
+ end
37
+ ```
38
+
39
+
40
+ ## Usage
41
+
42
+ ### Extending model
43
+
44
+ For instance generate a post model:
45
+ ```ruby
46
+ rails generate model post title:string description:text, publish_date:date
47
+ ```
48
+
49
+ Edit `app/models/post.rb`:
50
+ ```ruby
51
+ class Post < ActiveRecord::Base
52
+
53
+ extend Seorelify
54
+ seorelify title: :customized_title, description: :description
55
+
56
+ def customized_title
57
+ "THE BLOG: #{self.title}"
58
+ end
59
+
60
+ end
61
+ ```
62
+
63
+ This will use the `customized_title` and the `description` methods as references to generate automatically the related metatags.
64
+ Note that the title and description will be sanitized from HTML and truncated to 255 characters.
65
+
66
+
67
+ ### Controllers
68
+ In your controllers you may add\_metatags either like a before\_filter or within a method.
69
+
70
+ ```ruby
71
+ class PostsController < ApplicationController
72
+
73
+ def index
74
+ ###
75
+ # Custom meta tags
76
+ add_metatags({
77
+ title: 'My custom meta title',
78
+ description: 'My custom meta description'
79
+ })
80
+
81
+ ...
82
+ end
83
+
84
+ def show
85
+ @post = Post.find(params[:id])
86
+ ###
87
+ # Extract meta tags info from your Seorelified Model
88
+ add_metatags(@post)
89
+
90
+ ...
91
+ end
92
+
93
+ end
94
+ ```
95
+
96
+ ### Views
97
+
98
+ In your layout &lt;head&gt;&lt;/head&gt; section just call the `render_meta_tags` helper:
99
+
100
+ ```ruby
101
+ <%=render_meta_tags %>
102
+ ```
103
+
104
+
105
+ ## Contributing
106
+ Submitting a Pull Request:
107
+
108
+ 1. [Fork the repository.][fork]
109
+ 2. [Create a topic branch.][branch]
110
+ 3. Implement your feature or bug fix.
111
+ 4. Add, commit, and push your changes.
112
+ 5. [Submit a pull request.][pr]
113
+
114
+ [fork]: http://help.github.com/fork-a-repo/
115
+ [branch]: http://learn.github.com/p/branching.html
116
+ [pr]: http://help.github.com/send-pull-requests/
117
+
118
+ ## This project rocks and uses MIT-LICENSE.
119
+
120
+ Copyright 2013 Andrea Dal Ponte
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining
123
+ a copy of this software and associated documentation files (the
124
+ "Software"), to deal in the Software without restriction, including
125
+ without limitation the rights to use, copy, modify, merge, publish,
126
+ distribute, sublicense, and/or sell copies of the Software, and to
127
+ permit persons to whom the Software is furnished to do so, subject to
128
+ the following conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
135
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
136
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
137
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
138
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
139
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Seorel'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ class Seorel < ActiveRecord::Base
4
+
5
+ belongs_to :seorelable, polymorphic: true
6
+
7
+ mount_uploader :image, Seorel::ImageUploader
8
+
9
+ before_save do
10
+ self.title = ::ActionController::Base.helpers.strip_tags(self.title).first(255) if self.title?
11
+ self.description = ::ActionController::Base.helpers.strip_tags(self.description).first(255) if self.description?
12
+ end
13
+
14
+ def title?
15
+ self.title.present?
16
+ end
17
+
18
+ def description?
19
+ self.description.present?
20
+ end
21
+
22
+ def admin_label
23
+ I18n.t("seorel.admin.label")
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ class ImageUploader < CarrierWave::Uploader::Base
4
+
5
+ # Include RMagick or MiniMagick support:
6
+ # include CarrierWave::RMagick
7
+ # include CarrierWave::Processing::RMagick
8
+ include CarrierWave::MiniMagick
9
+
10
+ # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
11
+ include Sprockets::Helpers::RailsHelper
12
+ include Sprockets::Helpers::IsolatedHelper
13
+
14
+ # Choose what kind of storage to use for this uploader:
15
+ storage :file
16
+ # storage :fog
17
+
18
+ # Override the directory where uploaded files will be stored.
19
+ # This is a sensible default for uploaders that are meant to be mounted:
20
+ def store_dir
21
+ File.join('system', model.class.to_s.underscore.to_s, mounted_as.to_s, model.id.to_s)
22
+ end
23
+
24
+ # Provide a default URL as a default if there hasn't been a file uploaded:
25
+ def default_url
26
+ # For Rails 3.1+ asset pipeline compatibility:
27
+ asset_path('seorel/default.jpg')
28
+ end
29
+
30
+ process convert: 'jpeg'
31
+
32
+ version :thumbnail do
33
+ process resize_to_fill: [150, 150]
34
+ end
35
+
36
+ version :default do
37
+ process resize_and_pad: [300, 300, '#ffffff']
38
+ end
39
+
40
+ # Add a white list of extensions which are allowed to be uploaded.
41
+ # For images you might use something like this:
42
+ def extension_white_list
43
+ %w(jpg jpeg gif png bmp tif tiff)
44
+ end
45
+
46
+ # Override the filename of the uploaded files:
47
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
48
+ # def filename
49
+ # "something.jpg" if original_filename
50
+ # end
51
+
52
+ end
53
+ end
@@ -0,0 +1,16 @@
1
+ en:
2
+ activerecord:
3
+ model:
4
+ seorel: SEO
5
+
6
+ attributes:
7
+ seorel:
8
+ title: Meta title
9
+ desciption: Meta description
10
+
11
+ attributes:
12
+ seorel: SEO
13
+
14
+ seorel:
15
+ admin:
16
+ label: "Advanced options"
@@ -0,0 +1,17 @@
1
+ it:
2
+ activerecord:
3
+ model:
4
+ seorel/seorel: SEO
5
+
6
+ attributes:
7
+ seorel/seorel:
8
+ title: Meta title
9
+ description: Meta description
10
+ image: Immagine share
11
+
12
+ attributes:
13
+ seorel: SEO
14
+
15
+ seorel:
16
+ admin:
17
+ label: Meta tags
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Seorel::Engine.routes.draw do
2
+ # end
@@ -0,0 +1,16 @@
1
+ class CreateSeorelSeorels < ActiveRecord::Migration
2
+ def change
3
+ create_table :seorel_seorels do |t|
4
+ t.string :title
5
+ t.string :description
6
+ t.string :image
7
+ t.references :seorelable, polymorphic: true
8
+
9
+ t.timestamps
10
+ end
11
+
12
+ add_index :seorel_seorels, :seorelable_id
13
+ add_index :seorel_seorels, :seorelable_type
14
+ add_index :seorel_seorels, [:seorelable_id, :seorelable_type]
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Copies Seorel configuration file to your application's initializer directory.
3
+
4
+ Example:
5
+ rails generate seorel:config
6
+
7
+ This will create:
8
+ config/initializers/seorel_config.rb
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ class ConfigGenerator < Rails::Generators::Base
4
+
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def copy_config_file
8
+ template 'seorel_config.rb', 'config/initializers/seorel_config.rb'
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ Seorel.configure do |config|
3
+ # config.default_title = nil
4
+ # config.default_description = nil
5
+ # config.default_image = nil
6
+ # config.prepend_title = nil
7
+ # config.append_title = nil
8
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ require 'active_support/configurable'
3
+
4
+ module Seorel
5
+ # Configures global settings for Seorel
6
+ # Seorel.configure do |config|
7
+ # config.default_default_title = 10
8
+ # end
9
+ def self.configure(&block)
10
+ yield @config ||= Seorel::Configuration.new
11
+ end
12
+
13
+ # Global settings for Seorel
14
+ def self.config
15
+ @config
16
+ end
17
+
18
+ # need a Class for 3.0
19
+ class Configuration #:nodoc:
20
+ include ActiveSupport::Configurable
21
+
22
+ config_accessor :default_title
23
+ config_accessor :default_description
24
+ config_accessor :default_image
25
+ config_accessor :prepend_title
26
+ config_accessor :append_title
27
+
28
+ def param_name
29
+ config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name
30
+ end
31
+
32
+ # define param_name writer (copied from AS::Configurable)
33
+ writer, line = 'def param_name=(value); config.param_name = value; end', __LINE__
34
+ singleton_class.class_eval writer, __FILE__, line
35
+ class_eval writer, __FILE__, line
36
+ end
37
+
38
+ # this is ugly. why can't we pass the default value to config_accessor...?
39
+ configure do |config|
40
+ config.default_title = nil
41
+ config.default_description = nil
42
+ config.default_image = nil
43
+ config.prepend_title = nil
44
+ config.append_title = nil
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Controller
4
+ module ClassMethods
5
+
6
+ def add_seorel_meta(values = {})
7
+ class_name = self.name
8
+
9
+ before_filter options do |controller|
10
+ controller.send :add_meta, values
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Controller
4
+ module InstanceMethods
5
+
6
+ def add_seorel_meta(obj = {})
7
+ if obj.class.name == 'Hash'
8
+ add_seorel_hash obj
9
+ elsif obj.respond_to? :seorel
10
+ add_seorel_model obj
11
+ else
12
+ raise "Seorel `add_seorel_meta` invalid argument"
13
+ end
14
+ end
15
+
16
+ def add_seorel_hash(values = {})
17
+ seorel_params.title = values[:title] if values[:title].present?
18
+ seorel_params.description = values[:description] if values[:description].present?
19
+ seorel_params.image = values[:image] if values[:image].present?
20
+ seorel_params
21
+ end
22
+
23
+ def add_seorel_model(model)
24
+ seorel_params.title = model.seo_title
25
+ seorel_params.description = model.seo_description
26
+ seorel_params.image = model.seo_image.default.url if model.seo_image?
27
+ seorel_params
28
+ end
29
+
30
+ def seorel_params
31
+ @seosel_metatags ||= ::Seorel::Controller::Params.new
32
+ end
33
+
34
+ def self.included(klass)
35
+ return if klass.respond_to? :add_metatags
36
+ alias_method :add_metatags, :add_seorel_meta
37
+ protected :add_seorel_meta, :add_seorel_hash, :add_seorel_model, :seorel_params
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require 'active_support/configurable'
3
+
4
+ module Seorel
5
+ module Controller
6
+ class Params
7
+
8
+ include ActiveSupport::Configurable
9
+
10
+ config_accessor :title
11
+ config_accessor :description
12
+ config_accessor :image
13
+
14
+ def full_title
15
+ [default_options.prepend_title, self.title, default_options.append_title].compact.join
16
+ end
17
+
18
+ def title
19
+ config.title || default_options.default_title
20
+ end
21
+
22
+ def description
23
+ config.description || default_options.default_description
24
+ end
25
+
26
+ def image
27
+ config.image || default_options.default_image
28
+ end
29
+
30
+ def default_options
31
+ ::Seorel.config
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ class Engine < ::Rails::Engine
4
+
5
+ isolate_namespace Seorel
6
+
7
+ initializer 'Seorel Setup' do |app|
8
+ app.config.to_prepare do
9
+ ActionController::Base.send :extend, ::Seorel::Controller::ClassMethods
10
+ ActionController::Base.send :include, ::Seorel::Controller::InstanceMethods
11
+
12
+ ActionController::Base.send :helper_method, :seorel_params
13
+
14
+ ActionView::Base.send :include, ::Seorel::Helper
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Helper
4
+
5
+ def render_meta_tags
6
+ metas = ''
7
+ metas+= render_title
8
+ metas+= render_description
9
+ metas+= render_open_graph
10
+ metas+= render_twitter_cards
11
+ metas.html_safe
12
+ end
13
+
14
+ def render_title
15
+ content_tag :title, seorel_params.full_title
16
+ end
17
+
18
+ def render_description
19
+ content_tag :meta, nil, name: 'description', content: seorel_params.description
20
+ end
21
+
22
+ def render_open_graph
23
+ metas = ''
24
+ metas+= content_tag :meta, nil, name: 'og:type', content: 'website'
25
+ metas+= content_tag :meta, nil, name: 'og:title', content: seorel_params.full_title
26
+ metas+= content_tag :meta, nil, name: 'og:description', content: seorel_params.description
27
+ metas+= content_tag :meta, nil, name: 'og:image', content: seorel_params.image
28
+ metas+= content_tag :meta, nil, name: 'og:locale', content: I18n.locale.to_s
29
+ metas.html_safe
30
+ end
31
+
32
+ def render_twitter_cards
33
+ metas = ''
34
+ metas+= content_tag :meta, nil, name: 'twitter:card', content: 'summary'
35
+ metas+= content_tag :meta, nil, name: 'twitter:url', content: url_for
36
+ metas+= content_tag :meta, nil, name: 'twitter:title', content: seorel_params.full_title
37
+ metas+= content_tag :meta, nil, name: 'twitter:description', content: seorel_params.description
38
+ metas+= content_tag :meta, nil, name: 'twitter:image', content: seorel_params.image
39
+ metas.html_safe
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Model
4
+ module Base
5
+
6
+ def seorelify(*args)
7
+ include InstanceMethods
8
+ extend ClassMethods
9
+
10
+ cattr_accessor :seorel_title_field, :seorel_description_field, :seorel_image_field
11
+
12
+ if args[0].class.name == 'Hash'
13
+ class_variable_set '@@seorel_title_field', args[0][:title]
14
+ class_variable_set '@@seorel_description_field', args[0][:description] || args[0][:title]
15
+ class_variable_set '@@seorel_image_field', args[0][:image]
16
+ else
17
+ class_variable_set '@@seorel_title_field', args[0]
18
+ class_variable_set '@@seorel_description_field', args[1] || args[0]
19
+ class_variable_set '@@seorel_image_field', args[2]
20
+ end
21
+
22
+ has_one :seorel, as: :seorelable, dependent: :destroy, class_name: 'Seorel::Seorel'
23
+ accepts_nested_attributes_for :seorel, allow_destroy: false
24
+
25
+ before_save :set_seorel_default_values
26
+
27
+ delegate :title, :title?, :description, :description?, :image, :image?, to: :seorel, prefix: :seo, allow_nil: true
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Model
4
+ module ClassMethods
5
+
6
+ def seorel?
7
+ true
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Seorel
3
+ module Model
4
+ module InstanceMethods
5
+
6
+ def seorel?
7
+ self.try(:seorel).present?
8
+ end
9
+
10
+ def set_seorel_default_values
11
+ self.build_seorel unless self.seorel?
12
+
13
+ self.seorel.title = self.seorel_title_value if self.seorel_title_value.present?
14
+ self.seorel.description = self.seorel_description_value if self.seorel_description_value.present?
15
+ end
16
+
17
+ def seorel_title_value
18
+ self.class.seorel_title_field && self.send(self.class.seorel_title_field)
19
+ end
20
+
21
+ def seorel_description_value
22
+ self.class.seorel_description_field && self.send(self.class.seorel_description_field)
23
+ end
24
+
25
+ def seorel_default_value?
26
+ self.class.seorel_base_field.present?
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Seorelify
3
+
4
+ def self.extended(model_class)
5
+ return if model_class.respond_to? :seorel
6
+
7
+ model_class.instance_eval do
8
+ extend ::Seorel::Model::Base
9
+ end
10
+ end
11
+
12
+ def self.included(model_class)
13
+ return if model_class.respond_to? :seorel
14
+
15
+ model_class.instance_eval do
16
+ extend ::Seorel::Model::Base
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,3 @@
1
+ module Seorel
2
+ VERSION = "0.0.1"
3
+ end