para-seo_tools 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|