phaseout 0.0.1.danger.very.unstable
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 +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.mdown +63 -0
- data/Rakefile +2 -0
- data/app/controllers/phaseout/application_controller.rb +4 -0
- data/app/controllers/phaseout/phaseout_controller.rb +8 -0
- data/app/views/layouts/phaseout/application.html.erb +12 -0
- data/app/views/phaseout/phaseout/index.html.erb +1 -0
- data/config/routes.rb +3 -0
- data/lib/phaseout/engine.rb +5 -0
- data/lib/phaseout/handler.rb +65 -0
- data/lib/phaseout/seo.rb +29 -0
- data/lib/phaseout/seo_fields.rb +100 -0
- data/lib/phaseout/seo_helper.rb +31 -0
- data/lib/phaseout/version.rb +3 -0
- data/lib/phaseout.rb +21 -0
- data/phaseout.gemspec +27 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6fa8557722949165c7d3a73921be87878322dafa
|
4
|
+
data.tar.gz: ae1aa8325c74c4bd7e52757777ad837f1d5162ec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e2b96819f3caebd209b242765d4f1ef28e7066b7b8c4ca32130c510d234b6c5efc8a7de08a43e27532f55b7d846b74446ae58c2a77090fbea02972a3186f0d8d
|
7
|
+
data.tar.gz: 5775a21c73ba1c49399231b9b9d0af2ca68ee14b910543442983fc4d7f56614b5537b9dbbc4ece3c1ad70e915ab86bc929afa431de629de4e09d005a43636e69
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Dalton
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.mdown
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Phaseout
|
2
|
+
|
3
|
+
## Unstable, don't use it yet!
|
4
|
+
|
5
|
+
We are drafting our API, so no tests where written yet, and everything can break or can be broken on this repository.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'phaseout'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install phaseout
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Config Redis storage at some initializer:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
Phaseout.redis = Redis.new redis_config
|
29
|
+
```
|
30
|
+
|
31
|
+
Maybe it will be something like that on controllers:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
seo_tags_for :show, key: 'product/:@product.slug', as: 'Product @product.humanized_full_name' do |seo|
|
35
|
+
seo.meta_keywords{ |c| c.some_method_from_controller }
|
36
|
+
seo.og_url "raw_og_url"
|
37
|
+
seo.any_helper "with it's", "arguments"
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
On views, just add this:
|
42
|
+
|
43
|
+
```html_ruby
|
44
|
+
<%= seo_tags %>
|
45
|
+
```
|
46
|
+
|
47
|
+
On routes, add something like that:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
mount Phaseout::Engine => 'seo'
|
51
|
+
```
|
52
|
+
|
53
|
+
And if something doesn't work, remember what I said: "UNSTABLE, DON'T USE IT YET!".
|
54
|
+
|
55
|
+
And we will be glad to hear opinions and even more happier to receive pull requests!
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
|
59
|
+
1. Fork it ( https://github.com/akidog/phaseout/fork )
|
60
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
61
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
62
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
63
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Phaseout SEO Management</title>
|
5
|
+
<%= stylesheet_link_tag 'phaseout/application', media: 'all' %>
|
6
|
+
<%= javascript_include_tag 'phaseout/application' %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<%= yield %>
|
11
|
+
</body>
|
12
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
Index!
|
data/config/routes.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Phaseout
|
2
|
+
class Handler
|
3
|
+
attr_reader :controller, :action, :default
|
4
|
+
|
5
|
+
def initialize(controller, action, as_pattern, key_pattern, editable, &block)
|
6
|
+
@controller, @action, @as_pattern, @key_pattern, @editable = controller, action, as_pattern, key_pattern, editable
|
7
|
+
@default = Phaseout::SEOFields.new key, as, &block
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(&action_block)
|
11
|
+
if seo_fields
|
12
|
+
@controller.seo_tags = seo_fields.to_html(@controller)
|
13
|
+
else
|
14
|
+
@controller.seo_tags = @default.to_html(@controller)
|
15
|
+
set_blank_field if @blank_field && @editable
|
16
|
+
end
|
17
|
+
action_block.call
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def as
|
22
|
+
@as ||= eval_pattern @as_pattern
|
23
|
+
end
|
24
|
+
|
25
|
+
def key
|
26
|
+
@key ||= [ 'seo_key:', @controller.class.name, '#', @action, '/', eval_pattern(@key_pattern) ].join
|
27
|
+
end
|
28
|
+
|
29
|
+
def seo_fields
|
30
|
+
return @seo_fields if @seo_fields
|
31
|
+
dump = Phaseout.redis.get key
|
32
|
+
if dump.blank?
|
33
|
+
@blank_field = true
|
34
|
+
return nil
|
35
|
+
else
|
36
|
+
@seo_fields = Marshal.load dump
|
37
|
+
@seo_fields.default = @default
|
38
|
+
@seo_fields
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def class_index_key
|
43
|
+
['action:', @controller.class.name, '#', @action].join
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
def set_blank_field
|
48
|
+
Phaseout.redis.sadd class_index_key, key
|
49
|
+
Phaseout.redis.set key, Phaseout::SEOFields.new(key, as).dump
|
50
|
+
end
|
51
|
+
|
52
|
+
def eval_pattern(pattern)
|
53
|
+
pattern.to_s.gsub( /\@([\w\d\.\_])+/ ) do |subpattern|
|
54
|
+
varname, *methods = subpattern.split '.'
|
55
|
+
if @controller.instance_variable_defined? varname.to_sym
|
56
|
+
[ *methods, :to_s ].inject( @controller.instance_variable_get varname.to_sym ) do |result, method|
|
57
|
+
result.public_send method
|
58
|
+
end
|
59
|
+
else
|
60
|
+
''
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/phaseout/seo.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'phaseout/seo_fields'
|
2
|
+
require 'phaseout/seo_helper'
|
3
|
+
|
4
|
+
module Phaseout
|
5
|
+
module SEO
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def seo_tags
|
9
|
+
@_seo_tags ||= ''
|
10
|
+
end
|
11
|
+
|
12
|
+
def seo_tags=(value)
|
13
|
+
@_seo_tags = value
|
14
|
+
end
|
15
|
+
|
16
|
+
included do
|
17
|
+
helper_method :seo_tags
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def seo_tags_for(action, as: action, key: action, editable: true, &block)
|
22
|
+
around_block = lambda do |controller, action_block|
|
23
|
+
Phaseout::Handler.new(controller, action, as, key, editable, &block).call &action_block
|
24
|
+
end
|
25
|
+
around_action around_block, only: action
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Phaseout
|
2
|
+
class SEOFields
|
3
|
+
attr_reader :key, :human_name
|
4
|
+
attr_accessor :values, :default
|
5
|
+
|
6
|
+
def initialize(key, human_name, values = Hash.new, &block)
|
7
|
+
@key, @human_name, @values = key, human_name, values
|
8
|
+
yield(self) if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_html(controller)
|
12
|
+
evaluated_values(controller).map do |helper, argument|
|
13
|
+
controller.view_context.send helper, *argument
|
14
|
+
end.join.html_safe
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump
|
18
|
+
Marshal.dump self
|
19
|
+
end
|
20
|
+
|
21
|
+
def save
|
22
|
+
Phaseout.redis.set key, self.dump
|
23
|
+
end
|
24
|
+
|
25
|
+
def evaluated_values(controller)
|
26
|
+
@_values ||= if @default
|
27
|
+
@default.evaluated_values(controller).merge @values
|
28
|
+
else
|
29
|
+
Hash[
|
30
|
+
@values.map do |helper, argument|
|
31
|
+
if argument.is_a? Proc
|
32
|
+
[ helper, argument.call(controller) ]
|
33
|
+
else
|
34
|
+
[ helper, argument ]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](index)
|
42
|
+
values[index.to_sym]
|
43
|
+
end
|
44
|
+
|
45
|
+
def []=(index, value)
|
46
|
+
values[index.to_sym] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
def inspect
|
50
|
+
"#<Phaseout::SEO #{ @key.match('seo_key:').post_match.match('/').pre_match } #{@human_name}>"
|
51
|
+
end
|
52
|
+
alias :to_s :inspect
|
53
|
+
|
54
|
+
def method_missing(method, *args, &block)
|
55
|
+
if block_given?
|
56
|
+
@values[method.to_sym] = block
|
57
|
+
else
|
58
|
+
@values[method.to_sym] = args
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def marshal_dump
|
63
|
+
[ @key, @human_name, @values ]
|
64
|
+
end
|
65
|
+
|
66
|
+
def marshal_load(dump_array)
|
67
|
+
@key, @human_name, @values = dump_array
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.find(key)
|
71
|
+
dump = Phaseout.redis.get "seo_key:#{key}"
|
72
|
+
dump ? Marshal.load(dump) : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.actions(&block)
|
76
|
+
pattern = "#{Phaseout.redis.namespace}:action:*"
|
77
|
+
cursor, values = Phaseout.redis.scan 0, match: pattern
|
78
|
+
while cursor != 0
|
79
|
+
cursor = cursor.to_i
|
80
|
+
values.each do |value|
|
81
|
+
yield value.match(/#{ Phaseout.redis.namespace }\:action\:/).post_match
|
82
|
+
end
|
83
|
+
cursor, values = Phaseout.redis.scan cursor, match: pattern
|
84
|
+
cursor = cursor.to_i
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.fields_for(action_signature, &block)
|
89
|
+
class_index_key = "#{Phaseout.redis.namespace}:action:#{action_signature}"
|
90
|
+
cursor, keys = Phaseout.redis.sscan class_index_key, 0
|
91
|
+
while cursor != 0
|
92
|
+
cursor = cursor.to_i
|
93
|
+
keys.each{ |value| yield self.find(value.match('seo_key:').post_match) }
|
94
|
+
cursor, keys = Phaseout.redis.sscan class_index_key, cursor
|
95
|
+
cursor = cursor.to_i
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Phaseout
|
2
|
+
module SEOHelper
|
3
|
+
def page_title(content)
|
4
|
+
content_tag 'title', content
|
5
|
+
end
|
6
|
+
|
7
|
+
def meta_description(content)
|
8
|
+
tag 'meta', name: 'description', content: content
|
9
|
+
end
|
10
|
+
|
11
|
+
def meta_keywords(content)
|
12
|
+
tag 'meta', name: 'keywords', content: content
|
13
|
+
end
|
14
|
+
|
15
|
+
def og_url(content)
|
16
|
+
tag 'meta', property: 'og:url', content: content
|
17
|
+
end
|
18
|
+
|
19
|
+
def og_title(content)
|
20
|
+
tag 'meta', property: 'og:title', content: content
|
21
|
+
end
|
22
|
+
|
23
|
+
def og_image(content)
|
24
|
+
tag 'meta', property: 'og:image', content: content
|
25
|
+
end
|
26
|
+
|
27
|
+
def og_description(content)
|
28
|
+
tag 'meta', property: 'og:description', content: content
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/phaseout.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis-namespace'
|
3
|
+
|
4
|
+
require 'phaseout/version'
|
5
|
+
require 'phaseout/engine'
|
6
|
+
require 'phaseout/seo'
|
7
|
+
require 'phaseout/handler'
|
8
|
+
|
9
|
+
module Phaseout
|
10
|
+
def self.config_redis(connection, namespace = :phaseout)
|
11
|
+
@redis = Redis::Namespace.new namespace, redis: connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.redis
|
15
|
+
@redis ||= config_redis(Redis.new)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveSupport.on_load(:action_view) do
|
20
|
+
include Phaseout::SEOHelper
|
21
|
+
end
|
data/phaseout.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path '../lib', __FILE__
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'phaseout/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'phaseout'
|
8
|
+
spec.version = Phaseout::VERSION
|
9
|
+
spec.authors = ['Dalton Pinto', 'Felipe JAPM']
|
10
|
+
spec.email = ['dalthon@dlt.local', 'felipe@japm.local']
|
11
|
+
spec.summary = %q{SEO Management for Rails}
|
12
|
+
spec.description = %q{SEO Tags Management for Rails}
|
13
|
+
spec.homepage = 'https://github.com/akidog/phaseout'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = Dir['{app,config,bin,lib,test,spec,features}/**/*'] + [ 'phaseout.gemspec', 'LICENSE.txt', 'Rakefile', 'Gemfile', 'README.mdown' ]
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'redis'
|
23
|
+
spec.add_dependency 'redis-namespace'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'bundler'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: phaseout
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.danger.very.unstable
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dalton Pinto
|
8
|
+
- Felipe JAPM
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-12-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redis
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: redis-namespace
|
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: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: bundler
|
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
|
+
description: SEO Tags Management for Rails
|
71
|
+
email:
|
72
|
+
- dalthon@dlt.local
|
73
|
+
- felipe@japm.local
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.mdown
|
81
|
+
- Rakefile
|
82
|
+
- app/controllers/phaseout/application_controller.rb
|
83
|
+
- app/controllers/phaseout/phaseout_controller.rb
|
84
|
+
- app/views/layouts/phaseout/application.html.erb
|
85
|
+
- app/views/phaseout/phaseout/index.html.erb
|
86
|
+
- config/routes.rb
|
87
|
+
- lib/phaseout.rb
|
88
|
+
- lib/phaseout/engine.rb
|
89
|
+
- lib/phaseout/handler.rb
|
90
|
+
- lib/phaseout/seo.rb
|
91
|
+
- lib/phaseout/seo_fields.rb
|
92
|
+
- lib/phaseout/seo_helper.rb
|
93
|
+
- lib/phaseout/version.rb
|
94
|
+
- phaseout.gemspec
|
95
|
+
homepage: https://github.com/akidog/phaseout
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.3.1
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.4.2
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: SEO Management for Rails
|
119
|
+
test_files: []
|