seorel 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +139 -0
- data/Rakefile +40 -0
- data/app/models/seorel/seorel.rb +27 -0
- data/app/uploaders/seorel/image_uploader.rb +53 -0
- data/config/locales/en.seorel.yml +16 -0
- data/config/locales/it.seorel.yml +17 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20120822091543_create_seorel_seorels.rb +16 -0
- data/lib/generators/seorel/USAGE +8 -0
- data/lib/generators/seorel/config_generator.rb +12 -0
- data/lib/generators/seorel/templates/seorel_config.rb +8 -0
- data/lib/seorel/config.rb +46 -0
- data/lib/seorel/controller/class_methods.rb +16 -0
- data/lib/seorel/controller/instance_methods.rb +42 -0
- data/lib/seorel/controller/params.rb +36 -0
- data/lib/seorel/engine.rb +19 -0
- data/lib/seorel/helper.rb +43 -0
- data/lib/seorel/model/base.rb +32 -0
- data/lib/seorel/model/class_methods.rb +12 -0
- data/lib/seorel/model/instance_methods.rb +31 -0
- data/lib/seorel/seorelify.rb +20 -0
- data/lib/seorel/version.rb +3 -0
- data/lib/seorel.rb +16 -0
- data/lib/tasks/seorel_tasks.rake +9 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/seorel/seorels.yml +11 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/seorel_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/seorel/seorel_test.rb +9 -0
- 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 <head></head> 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
|
data/config/routes.rb
ADDED
@@ -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,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,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,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
|