para-seo_tools 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +161 -1
- data/app/models/para/seo_tools/page.rb +47 -0
- data/db/migrate/20160930064950_add_config_to_seo_tools_pages.rb +5 -0
- data/lib/para/seo_tools.rb +7 -0
- data/lib/para/seo_tools/controller.rb +5 -1
- data/lib/para/seo_tools/page_scoping.rb +39 -0
- data/lib/para/seo_tools/sitemap.rb +25 -2
- data/lib/para/seo_tools/skeleton.rb +10 -5
- data/lib/para/seo_tools/skeleton/{page.rb → page_builder.rb} +39 -15
- data/lib/para/seo_tools/skeleton/site.rb +13 -3
- data/lib/para/seo_tools/version.rb +1 -1
- data/lib/tasks/para_seo_tools_tasks.rake +22 -0
- metadata +6 -5
- data/lib/tasks/sitemap.rake +0 -17
- data/lib/tasks/skeleton.rake +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4b8959221c49d287170b758d7dbe9a0e2bb291b
|
4
|
+
data.tar.gz: 2c9f4d8e455c31bf0f47c7c1cdb1dffdd54a571f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd129c962571f25f126aeafed737ef17e86fb2e2ef73351bf1b416a4372c4a917f80b41017a614506001a2a2fe26ba829b7108e2675df715fe99015bea4ddc73
|
7
|
+
data.tar.gz: 0880f858c0a6db534a542182e456f46f126a2ce4271bef67fc19a7e62297fb1b1330b297b4278db6f435866bc564e280f631fcd71b61816ab1278e75989b1c07
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -87,6 +87,166 @@ by default.
|
|
87
87
|
page :posts, priority: 1, change_frequency: 'weekly'
|
88
88
|
```
|
89
89
|
|
90
|
+
#### Default meta tag values
|
91
|
+
|
92
|
+
The `page` method allows to define default data for seo_tools to use as default
|
93
|
+
values for the title and description meta tags.
|
94
|
+
|
95
|
+
For example, using your post title as default meta title and its excerpt as the
|
96
|
+
default description meta tag value is as easy as :
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
Posts.find_each do |post|
|
100
|
+
page :post, resource: post, defaults: { title: post.title, description: post.excerpt }
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
#### Arbitrary scoping of pages
|
105
|
+
|
106
|
+
SeoTools ensures your page identifiers are unique. This avoids duplicating pages
|
107
|
+
and unwanted side effects. This identifier is generated with the first argument
|
108
|
+
of the `#page` method (`:post` in our examples), and the id of the resource
|
109
|
+
passed in the `:resource` argument, when present.
|
110
|
+
|
111
|
+
For a `:post` with id `25`, this results in an identifier containing :
|
112
|
+
`"post:25"`.
|
113
|
+
|
114
|
+
Sometimes you'll need to have multiple pages that allows accessing a single
|
115
|
+
resource, and your identifier would be duplicated. In this case, you can use
|
116
|
+
the `:scope` argument, which will allow to create multiple identifiers with
|
117
|
+
the same value, scoped to the given arguments.
|
118
|
+
|
119
|
+
As an example, you can this of posts belonging to multiple categories, which
|
120
|
+
would result in a structure where a post could appear under multiple categories.
|
121
|
+
|
122
|
+
To handle this case, we would write :
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
Categories.each do |category|
|
126
|
+
category.posts.each do |post|
|
127
|
+
page :post, resource: post, path: category_post_path(category, post), scope: :category_id, category_id: post.category_id
|
128
|
+
end
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
As a side effect, you can find all "sibling" pages of a given page, allowing
|
133
|
+
you to handle canonical URLs or HREFLANG meta tags with ease.
|
134
|
+
|
135
|
+
#### Batch scoping and params forwarding
|
136
|
+
|
137
|
+
When you have many pages scoped with the same parameters, you may want to DRY
|
138
|
+
out scope params passing to the `#page` method calls.
|
139
|
+
|
140
|
+
This can be accomplished with the `#with_params` helper method. When used,
|
141
|
+
every call to the `#page` method would automatically fetch params passed to the
|
142
|
+
`#with_params` method as default params to build or update the underlying page
|
143
|
+
object.
|
144
|
+
|
145
|
+
Below's an example of a situation where you would have a multi-store shop, and
|
146
|
+
want to scope all product categories and products pages depending on their
|
147
|
+
belonging store, given that some products and categories could exist in multiple
|
148
|
+
stores, requiring you to scope them.
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
Stores.each do |store|
|
152
|
+
with_params store_id: store.id, scope: :store_id do
|
153
|
+
store.product_categories.each do |product_category|
|
154
|
+
page :product_category, resource: product_category
|
155
|
+
|
156
|
+
product_category.products.each do |product|
|
157
|
+
page :product, resource: product
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
164
|
+
Global skeleton-wide default params can also be passed to the
|
165
|
+
`Para::SeoTools::Skeleton.draw` call at the top of the skeleton file :
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
Para::SeoTools::Skeleton.draw(scope: :store_id) do
|
169
|
+
# You code scoped by store_id here
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
#### Locales support
|
174
|
+
|
175
|
+
SeoTools comes with multi-locale support built-in. By default, each call to the
|
176
|
+
`page` method assigns the current `I18n.locale` to the created page resource.
|
177
|
+
|
178
|
+
Localized page path handling is dependent on your app logic, but you can easily
|
179
|
+
generate pages for each locale.
|
180
|
+
|
181
|
+
If routing to a specific locale only needs a `:locale` argument passed to your
|
182
|
+
URL helpers, and you want to create a page for each available locale, here how
|
183
|
+
you'd do it :
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
Para::SeoTools::Skeleton.draw(scope: :locale) do
|
187
|
+
I18n.available_locales.each do |locale|
|
188
|
+
I18n.with_locale(locale) do
|
189
|
+
Posts.find_each do |post|
|
190
|
+
page :post, resource: post, path: post_path(post, locale: locale)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
By using `I18n.with_locale`, we force the current locale in the block, and
|
197
|
+
SeoTools automatically assigns the locale to the page resource.
|
198
|
+
|
199
|
+
#### Lazy skeleton building.
|
200
|
+
|
201
|
+
On large applications, building the skeleton with all its pages at application
|
202
|
+
boot time is not an option. You can opt out from this strategy and choose to
|
203
|
+
build it yourself from a rake task by using the `Para::SeoTools::Skeleton.draw`
|
204
|
+
`:lazy` param and calling the rake task from a CRON or similar job.
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
Para::SeoTools::Skeleton.draw(lazy: true) do
|
208
|
+
# ...
|
209
|
+
end
|
210
|
+
```
|
211
|
+
|
212
|
+
Then use the following rake task :
|
213
|
+
|
214
|
+
```bash
|
215
|
+
rake seo_tools:skeleton:build
|
216
|
+
```
|
217
|
+
|
218
|
+
#### Domain and subdomains handling
|
219
|
+
|
220
|
+
By default, SeoTools doesn't handle specifically domains and subdomains, since
|
221
|
+
it stores the page paths with a leading `/`.
|
222
|
+
|
223
|
+
You can tell it to take those parameters into account when building the
|
224
|
+
skeleton, and when fetching data during the request.
|
225
|
+
|
226
|
+
The first step is to activate one or both of domain and subdomain handling, use
|
227
|
+
the `#handle_domain` and `#handle_subdomain` in the para initializer file :
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
Para.config do |config|
|
231
|
+
config.seo_tools do |seo_tools|
|
232
|
+
seo_tools.handle_domain = true
|
233
|
+
seo_tools.handle_subdomain = true
|
234
|
+
end
|
235
|
+
end
|
236
|
+
```
|
237
|
+
|
238
|
+
Then, you need to pass the domain and subdomain as parameters of the `#page`
|
239
|
+
call of your skeleton.rb, or with batch params assignation as described above
|
240
|
+
[Batch scoping and params forwarding](#batch-scoping-and-params-forwarding)
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
page :post, resource: post, subdomain: 'blog', domain: 'example.com'
|
244
|
+
```
|
245
|
+
|
246
|
+
Now, when the page data is fetched during the request, the `request.subdomain`
|
247
|
+
and `request.domain` will be used.
|
248
|
+
|
249
|
+
|
90
250
|
### 2. Display the meta tags admin panel
|
91
251
|
|
92
252
|
For the admin panel to display, all you'll need to do is create the component
|
@@ -103,7 +263,7 @@ section :your_section do
|
|
103
263
|
end
|
104
264
|
```
|
105
265
|
|
106
|
-
|
266
|
+
Then go to the admin panel, and click the **Sitemap** menu link.
|
107
267
|
|
108
268
|
### 3. Generate a sitemap.xml
|
109
269
|
|
@@ -3,9 +3,16 @@ module Para
|
|
3
3
|
class Page < ActiveRecord::Base
|
4
4
|
META_TAGS = :title, :description, :keywords, :image, :canonical
|
5
5
|
|
6
|
+
store_accessor :config, :scope
|
7
|
+
|
6
8
|
has_attached_file :image, styles: { thumb: '200x200#' }
|
7
9
|
validates_attachment :image, content_type: { content_type: /\Aimage\/.*\Z/ }
|
8
10
|
|
11
|
+
validate :identifier_uniqueness
|
12
|
+
|
13
|
+
scope :with_subdomain, ->(subdomain) { where("config->>'subdomain' = ?", subdomain) }
|
14
|
+
scope :with_domain, ->(domain) { where("config->>'domain' = ?", domain) }
|
15
|
+
|
9
16
|
def meta_tag(name)
|
10
17
|
if (value = send(name).presence) && (meta = process(name, value)).present?
|
11
18
|
return meta
|
@@ -44,6 +51,29 @@ module Para
|
|
44
51
|
Arel::Nodes::SqlLiteral.new(expr.to_sql)
|
45
52
|
end
|
46
53
|
|
54
|
+
def scope_attributes
|
55
|
+
scope.each_with_object({}) do |attribute, hash|
|
56
|
+
hash[attribute] = if self.class.column_names.include?(attribute.to_s)
|
57
|
+
send(attribute)
|
58
|
+
else
|
59
|
+
config[attribute.to_s]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def sitemap_host
|
65
|
+
host = []
|
66
|
+
host << config['subdomain'] if Para::SeoTools.handle_subdomain
|
67
|
+
|
68
|
+
if Para::SeoTools.handle_domain
|
69
|
+
host << config['domain']
|
70
|
+
else
|
71
|
+
host << Para::SeoTools.host
|
72
|
+
end
|
73
|
+
|
74
|
+
host.join('.')
|
75
|
+
end
|
76
|
+
|
47
77
|
private
|
48
78
|
|
49
79
|
def process(name, value)
|
@@ -53,6 +83,23 @@ module Para
|
|
53
83
|
value
|
54
84
|
end
|
55
85
|
end
|
86
|
+
|
87
|
+
def identifier_uniqueness
|
88
|
+
conditions = PageScoping.new(self).uniqueness_scope_conditions
|
89
|
+
conditions = conditions.where.not(id: id) if persisted?
|
90
|
+
|
91
|
+
if conditions.where(identifier: identifier).exists?
|
92
|
+
errors.add(:identifier, :taken)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def method_missing(method_name, *args, &block)
|
97
|
+
if config.key?(method_name.to_s)
|
98
|
+
config[method_name.to_s]
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
56
103
|
end
|
57
104
|
end
|
58
105
|
end
|
data/lib/para/seo_tools.rb
CHANGED
@@ -12,6 +12,7 @@ module Para
|
|
12
12
|
autoload :Routes
|
13
13
|
autoload :Skeleton
|
14
14
|
autoload :Sitemap
|
15
|
+
autoload :PageScoping
|
15
16
|
|
16
17
|
autoload :MetaTaggable
|
17
18
|
autoload :MetaTaggableMacro
|
@@ -20,6 +21,12 @@ module Para
|
|
20
21
|
mattr_writer :host
|
21
22
|
@@host = ENV['APP_DOMAIN']
|
22
23
|
|
24
|
+
mattr_accessor :handle_domain
|
25
|
+
@@handle_domain = false
|
26
|
+
|
27
|
+
mattr_accessor :handle_subdomain
|
28
|
+
@@handle_subdomain = false
|
29
|
+
|
23
30
|
mattr_accessor :title_methods
|
24
31
|
@@title_methods = %w(title name)
|
25
32
|
|
@@ -37,7 +37,11 @@ module Para
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def fetch_meta_tags_page
|
40
|
-
|
40
|
+
page_conditions = Para::SeoTools::Page.where(path: request.path)
|
41
|
+
page_conditions = page_conditions.with_subdomain(request.subdomain) if Para::SeoTools.handle_subdomain
|
42
|
+
page_conditions = page_conditions.with_domain(request.domain) if Para::SeoTools.handle_domain
|
43
|
+
|
44
|
+
if (page = page_conditions.first)
|
41
45
|
set_meta_tags_from_page(page)
|
42
46
|
end
|
43
47
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Common class used by the Page model and PageBuilder to build and handle
|
2
|
+
# pages scoping and building their unique identifiers
|
3
|
+
#
|
4
|
+
module Para
|
5
|
+
module SeoTools
|
6
|
+
class PageScoping
|
7
|
+
attr_reader :resource
|
8
|
+
|
9
|
+
def initialize(resource)
|
10
|
+
@resource = resource
|
11
|
+
end
|
12
|
+
|
13
|
+
def scoped?
|
14
|
+
resource.scope.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def column?(attribute)
|
18
|
+
resource.class.column_names.include?(attribute.to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
def uniqueness_scope_conditions
|
22
|
+
return resource.class unless scoped?
|
23
|
+
|
24
|
+
resource.scope_attributes.reduce(resource.class) do |query, (attribute, value)|
|
25
|
+
if column?(attribute)
|
26
|
+
query.where(attribute => value)
|
27
|
+
else
|
28
|
+
query.where("config->>'#{ attribute }' = ?", value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def unique_identifier
|
34
|
+
return resource.identifier unless scoped?
|
35
|
+
resource.scope_attributes.merge(identifier: resource.identifier).to_json
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,10 +1,33 @@
|
|
1
1
|
module Para
|
2
2
|
module SeoTools
|
3
3
|
class Sitemap
|
4
|
+
def self.generate!
|
5
|
+
puts " * GENERATE SITEMAP ..."
|
6
|
+
|
7
|
+
build
|
8
|
+
|
9
|
+
puts " * BUILD ..."
|
10
|
+
|
11
|
+
::Sitemap::Generator.instance.build!
|
12
|
+
|
13
|
+
puts " * SAVE ..."
|
14
|
+
|
15
|
+
::Sitemap::Generator.instance.save(path)
|
16
|
+
|
17
|
+
puts " * SAVED !"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.path
|
21
|
+
@path ||= begin
|
22
|
+
root = ::Sitemap.configuration.save_path || ENV["LOCATION"] || Rails.public_path
|
23
|
+
File.join(root, "sitemap.xml")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
4
27
|
def self.build
|
5
|
-
::Sitemap::Generator.instance.load
|
28
|
+
::Sitemap::Generator.instance.load do
|
6
29
|
Para::SeoTools::Page.find_each do |page|
|
7
|
-
literal page.path
|
30
|
+
literal page.path, host: page.sitemap_host
|
8
31
|
end
|
9
32
|
end
|
10
33
|
end
|
@@ -4,10 +4,10 @@ module Para
|
|
4
4
|
extend ActiveSupport::Autoload
|
5
5
|
|
6
6
|
autoload :Site
|
7
|
-
autoload :
|
7
|
+
autoload :PageBuilder
|
8
8
|
autoload :Worker
|
9
9
|
|
10
|
-
mattr_accessor :site, :config, :enable_logging
|
10
|
+
mattr_accessor :site, :config, :options, :enable_logging
|
11
11
|
|
12
12
|
def self.with_logging(&block)
|
13
13
|
self.enable_logging = true
|
@@ -25,18 +25,23 @@ module Para
|
|
25
25
|
require skeleton_path if File.exists?(skeleton_path)
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.draw(lazy: false, &block)
|
28
|
+
def self.draw(lazy: false, **options, &block)
|
29
29
|
self.config = block
|
30
|
+
self.options = options
|
30
31
|
build unless lazy
|
31
32
|
end
|
32
33
|
|
33
|
-
def self.build
|
34
|
+
def self.build(load_skeleton: false)
|
34
35
|
return if migrating?
|
35
36
|
return unless ActiveRecord::Base.connection.table_exists?(Para::SeoTools::Page.table_name)
|
36
37
|
|
38
|
+
load if load_skeleton
|
39
|
+
|
37
40
|
log " * Building app skeleton pages ..."
|
38
41
|
|
39
|
-
|
42
|
+
site_options = options.merge(enable_logging: enable_logging)
|
43
|
+
self.site = Skeleton::Site.new(site_options)
|
44
|
+
|
40
45
|
# Evaluate the configuration block
|
41
46
|
site.instance_exec(&config)
|
42
47
|
|
@@ -1,27 +1,50 @@
|
|
1
1
|
module Para
|
2
2
|
module SeoTools
|
3
3
|
module Skeleton
|
4
|
-
class
|
4
|
+
class ScopeAttributeUndefined < StandardError; end
|
5
|
+
|
6
|
+
class PageBuilder
|
5
7
|
include Rails.application.routes.url_helpers
|
6
8
|
|
7
|
-
attr_reader :name, :resource, :
|
9
|
+
attr_reader :name, :resource, :locale, :defaults, :config
|
8
10
|
|
9
11
|
def initialize(name, path: nil, resource: nil, **options)
|
10
12
|
@name = name
|
11
13
|
@path = path
|
12
14
|
@resource = resource
|
13
|
-
@options = options
|
14
15
|
|
15
16
|
# Fetch locale on page build to allow calling the `page` skeleton
|
16
17
|
# method inside a `I18n.with_locale` block
|
17
18
|
#
|
18
|
-
@locale = options.
|
19
|
+
@locale = options.delete(:locale) || I18n.locale
|
20
|
+
@defaults = options.delete(:defaults) || {}
|
21
|
+
|
22
|
+
# Remaining options will be stored as config in a JSONB attribute
|
23
|
+
@config = options
|
19
24
|
end
|
20
25
|
|
21
26
|
def identifier
|
22
27
|
@identifier ||= [name, resource.try(:id)].compact.join(':')
|
23
28
|
end
|
24
29
|
|
30
|
+
def scope
|
31
|
+
@scope ||= config[:scope]
|
32
|
+
end
|
33
|
+
|
34
|
+
def scope_attributes
|
35
|
+
scope.each_with_object({}) do |attribute, hash|
|
36
|
+
hash[attribute] = if (value = config[attribute])
|
37
|
+
value
|
38
|
+
elsif respond_to?(attribute)
|
39
|
+
send(attribute)
|
40
|
+
else
|
41
|
+
raise ScopeAttributeUndefined, "Your Skeleton page is scoped " +
|
42
|
+
"with the '#{ attribute }' attribute but you did not pass it " +
|
43
|
+
"as a parameter of the #page : #{ inspect }"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
25
48
|
def display_name
|
26
49
|
@display_name ||= [name, resource.try(:id)].compact.join(' #').humanize
|
27
50
|
end
|
@@ -31,18 +54,13 @@ module Para
|
|
31
54
|
end
|
32
55
|
|
33
56
|
def model
|
34
|
-
@model ||= self.class.model_for(
|
57
|
+
@model ||= self.class.model_for(self).tap do |page|
|
35
58
|
# Override path (i.e.: slug changed)
|
36
59
|
page.path = path if path.to_s != page.path
|
37
60
|
page.locale = locale
|
38
61
|
# Do not override meta tags if already present
|
39
|
-
page.defaults =
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def sitemap_options
|
44
|
-
[:priority, :change_frequency].each_with_object({}) do |param, hash|
|
45
|
-
hash[param] = options[param] if options.key?(param)
|
62
|
+
page.defaults = defaults
|
63
|
+
page.config = config
|
46
64
|
end
|
47
65
|
end
|
48
66
|
|
@@ -56,15 +74,21 @@ module Para
|
|
56
74
|
end
|
57
75
|
end
|
58
76
|
|
59
|
-
def self.model_for(
|
60
|
-
models[
|
77
|
+
def self.model_for(page)
|
78
|
+
models[unique_identifier_for(page)] ||= ::Para::SeoTools::Page.new(
|
79
|
+
identifier: page.identifier
|
80
|
+
)
|
61
81
|
end
|
62
82
|
|
63
83
|
def self.models
|
64
84
|
@models ||= Para::SeoTools::Page.all.each_with_object({}) do |page, hash|
|
65
|
-
hash[page
|
85
|
+
hash[unique_identifier_for(page)] = page
|
66
86
|
end
|
67
87
|
end
|
88
|
+
|
89
|
+
def self.unique_identifier_for(page)
|
90
|
+
Para::SeoTools::PageScoping.new(page).unique_identifier
|
91
|
+
end
|
68
92
|
end
|
69
93
|
end
|
70
94
|
end
|
@@ -3,19 +3,29 @@ module Para
|
|
3
3
|
module Skeleton
|
4
4
|
class Site
|
5
5
|
include Rails.application.routes.url_helpers
|
6
|
-
attr_reader :enable_logging
|
6
|
+
attr_reader :enable_logging, :default_page_options
|
7
7
|
|
8
8
|
def initialize(options = {})
|
9
|
-
@enable_logging = options
|
9
|
+
@enable_logging = options.delete(:enable_logging)
|
10
|
+
@default_page_options = options
|
10
11
|
end
|
11
12
|
|
12
13
|
def page(name, options = {} , &block)
|
13
|
-
|
14
|
+
options.reverse_merge!(default_page_options)
|
15
|
+
|
16
|
+
Skeleton::PageBuilder.new(name, options).tap do |page|
|
14
17
|
pages << page
|
15
18
|
save if pages.length == max_pages_before_save
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
22
|
+
def with_params(params = {}, &block)
|
23
|
+
previous_default_page_options = default_page_options
|
24
|
+
@default_page_options = default_page_options.dup.merge(params)
|
25
|
+
block.call
|
26
|
+
@default_page_options = previous_default_page_options
|
27
|
+
end
|
28
|
+
|
19
29
|
def pages
|
20
30
|
@pages ||= []
|
21
31
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
namespace :para do
|
2
|
+
namespace :seo_tools do
|
3
|
+
namespace :skeleton do
|
4
|
+
desc "Builds or refreshes the app skeleton."
|
5
|
+
task build: :environment do
|
6
|
+
Para::SeoTools::Skeleton.build(load_skeleton: true)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
namespace :sitemap do
|
11
|
+
desc "Generates a new sitemap."
|
12
|
+
task generate: :environment do
|
13
|
+
Para::SeoTools::Sitemap.generate!
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Ping engines."
|
17
|
+
task ping: :environment do
|
18
|
+
::Sitemap::Ping.send_request(Para::SeoTools::Sitemap.path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: para-seo_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valentin Ballestrino
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- db/migrate/20150601085253_create_seo_tools_pages.rb
|
119
119
|
- db/migrate/20160610094032_add_meta_tags_to_seo_tools_pages.rb
|
120
120
|
- db/migrate/20160614081242_add_locale_and_remove_meta_tags_list_to_seo_tools_pages.rb
|
121
|
+
- db/migrate/20160930064950_add_config_to_seo_tools_pages.rb
|
121
122
|
- lib/generators/para/seo_tools/install/install_generator.rb
|
122
123
|
- lib/generators/para/seo_tools/install/templates/initializer.rb
|
123
124
|
- lib/generators/para/seo_tools/install/templates/skeleton.rb
|
@@ -138,17 +139,17 @@ files:
|
|
138
139
|
- lib/para/seo_tools/meta_tags/vendors/base.rb
|
139
140
|
- lib/para/seo_tools/meta_tags/vendors/open_graph.rb
|
140
141
|
- lib/para/seo_tools/meta_tags/vendors/twitter.rb
|
142
|
+
- lib/para/seo_tools/page_scoping.rb
|
141
143
|
- lib/para/seo_tools/routes.rb
|
142
144
|
- lib/para/seo_tools/sitemap.rb
|
143
145
|
- lib/para/seo_tools/skeleton.rb
|
144
|
-
- lib/para/seo_tools/skeleton/
|
146
|
+
- lib/para/seo_tools/skeleton/page_builder.rb
|
145
147
|
- lib/para/seo_tools/skeleton/site.rb
|
146
148
|
- lib/para/seo_tools/skeleton/worker.rb
|
147
149
|
- lib/para/seo_tools/version.rb
|
148
150
|
- lib/para/seo_tools/view_helpers.rb
|
149
151
|
- lib/tasks/migration.rake
|
150
|
-
- lib/tasks/
|
151
|
-
- lib/tasks/skeleton.rake
|
152
|
+
- lib/tasks/para_seo_tools_tasks.rake
|
152
153
|
- para-seo_tools.gemspec
|
153
154
|
- test/fixtures/seo_tools/pages.yml
|
154
155
|
- test/models/seo_tools/page_test.rb
|
data/lib/tasks/sitemap.rake
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
namespace :seo_tools do
|
2
|
-
namespace :sitemap do
|
3
|
-
desc "Generates a new sitemap."
|
4
|
-
task generate: :environment do
|
5
|
-
Para::SeoTools::Sitemap.build
|
6
|
-
root = ::Sitemap.configuration.save_path || ENV["LOCATION"] || Rails.public_path
|
7
|
-
path = File.join(root, "sitemap.xml")
|
8
|
-
::Sitemap::Generator.instance.build!
|
9
|
-
::Sitemap::Generator.instance.save(path)
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Ping engines."
|
13
|
-
task ping: :environment do
|
14
|
-
::Sitemap::Ping.send_request(ENV["LOCATION"])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|