phaseout 0.0.1.danger.very.unstable → 0.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6fa8557722949165c7d3a73921be87878322dafa
4
- data.tar.gz: ae1aa8325c74c4bd7e52757777ad837f1d5162ec
3
+ metadata.gz: 19abad5ab2f05d4cff49768c76f08060c0af15a4
4
+ data.tar.gz: 32139d3c6d63428be616303683674e8b1719481e
5
5
  SHA512:
6
- metadata.gz: e2b96819f3caebd209b242765d4f1ef28e7066b7b8c4ca32130c510d234b6c5efc8a7de08a43e27532f55b7d846b74446ae58c2a77090fbea02972a3186f0d8d
7
- data.tar.gz: 5775a21c73ba1c49399231b9b9d0af2ca68ee14b910543442983fc4d7f56614b5537b9dbbc4ece3c1ad70e915ab86bc929afa431de629de4e09d005a43636e69
6
+ metadata.gz: b00fcf4de916f4677457785bdd9960e00b4518bb67c4418c87ed20023468e9f010773efef5412af983c7bf5c1877ddfff078e0e3caa953e535c19710d0eabb8a
7
+ data.tar.gz: 87b06a3a15305892f7e9e23c35a9e0ca020210a4ef95ff5daaa195ea8dc060cc61f1f8a0a3769f9d98df3e50952213456e04dfb09df72ae246d01150de070197
data/README.mdown CHANGED
@@ -9,7 +9,10 @@ We are drafting our API, so no tests where written yet, and everything can break
9
9
  Add this line to your application's Gemfile:
10
10
 
11
11
  ```ruby
12
+ source 'https://rails-assets.org'
13
+
12
14
  gem 'phaseout'
15
+ gem 'rails-assets-underscore'
13
16
  ```
14
17
 
15
18
  And then execute:
@@ -0,0 +1,126 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require underscore
4
+ //= require_tree ./templates
5
+
6
+ // TODO: These route methods works, but they're ugly!
7
+ function seo_action_keys_path(key){
8
+ var path = "<%= Phaseout::Engine.routes.url_helpers.seo_action_keys_path('PHASEOUT_ACTION_KEY') %>";
9
+ return path.replace( 'PHASEOUT_ACTION_KEY', key.replace('#', '\%23') );
10
+ }
11
+
12
+ function seo_fields_update_path(key){
13
+ var path = "<%= Phaseout::Engine.routes.url_helpers.seo_fields_update_path('PHASEOUT_ACTION_KEY') %>";
14
+ return path.replace( 'PHASEOUT_ACTION_KEY', key.replace('#', '\%23') );
15
+ }
16
+
17
+ function seo_fields_delete_path(key){
18
+ var path = "<%= Phaseout::Engine.routes.url_helpers.seo_fields_delete_path('PHASEOUT_ACTION_KEY') %>";
19
+ return path.replace( 'PHASEOUT_ACTION_KEY', key.replace('#', '\%23') );
20
+ }
21
+
22
+ function seo_action_list_path(){
23
+ return "<%= Phaseout::Engine.routes.url_helpers.seo_action_list_path %>";
24
+ }
25
+
26
+ var PhaseoutTranslations = <%= I18n.t('seo').to_json %>;
27
+ var PhaseoutFields = <%= Hash[ Phaseout.default_fields.map{ |field| [field, I18n.t( "seo.fields.#{field}" )] } ].to_json %>;
28
+
29
+ function click_on_action_key_handler(_action_key){
30
+ var action_key = _action_key;
31
+ var action_key_html_id = [action_key['action_id'], action_key['id']].join('_');
32
+ var item = $('#'+action_key_html_id);
33
+ var fields_form = item.children('.action_key_fields');
34
+
35
+ $('#'+action_key_html_id+' .seo_action_key_link').click((function(){
36
+ return function(){
37
+ fields_form.toggle();
38
+ item.toggleClass('opened');
39
+ };
40
+ })());
41
+
42
+ fields_form[0].action_key = action_key;
43
+ fields_form.on('ajax:success', function(xhr, response_data, status){
44
+ fields_form[0].action_key = response_data;
45
+ });
46
+
47
+ $('#'+action_key_html_id+'_delete').on('ajax:success', function(xhr, response_data, status){
48
+ $('#'+action_key_html_id).remove();
49
+ if( $('#'+action_key['action_id']+' .action_key_list li').length == 0 ){
50
+ $('#'+action_key['action_id']).remove();
51
+ }
52
+ });
53
+
54
+ $('#'+action_key_html_id+'_button').click(function(){
55
+ var field_key = $('#'+action_key_html_id+' option:selected').attr('value');
56
+
57
+ if( field_key == 'other' ){
58
+ field_key = window.prompt(PhaseoutTranslations.common.add_prompt);
59
+ if( field_key == null ){ return null; }
60
+ }
61
+
62
+ if( $('#'+action_key_html_id+'_'+field_key).length > 0 ){
63
+ alert(PhaseoutTranslations.common.already_added);
64
+ } else {
65
+ var template_data = {
66
+ key: field_key,
67
+ field: '',
68
+ action_key: fields_form[0].action_key
69
+ }
70
+ fields_form.children('.seo_form_fields_list').append( JST['phaseout/templates/action_key_field'](template_data) );
71
+ }
72
+ })
73
+ }
74
+
75
+ function load_action_keys(key, html_id){
76
+ $.ajax({
77
+ url: seo_action_keys_path(key),
78
+ type: 'GET',
79
+ dataType: 'json',
80
+ success: function(data){
81
+ var action_keys = _.sortBy(data, function(obj){ return obj['name']; });
82
+ $('#'+html_id+' ul').append(JST['phaseout/templates/action_key_list']({ action_keys: action_keys }));
83
+ for( var index in action_keys ){ click_on_action_key_handler(action_keys[index]); }
84
+ }
85
+ });
86
+ }
87
+
88
+ function click_on_action_handler(_action){
89
+ var action = _action;
90
+ var header = $('#'+action['id']+'.seo_action_item');
91
+ var list = $('#'+action['id']+' ul.action_key_list');
92
+ $('#'+_action['id']+' .seo_action_item_link').click((function(){
93
+ return function(){
94
+ if( list.fecthedData ){
95
+ list.toggle();
96
+ list.toggleClass('opened');
97
+ header.toggleClass('opened');
98
+ } else {
99
+ header.addClass('opened');
100
+ list.addClass('opened');
101
+ list.show();
102
+ list.fecthedData = true;
103
+ load_action_keys(action['key'], action['id']);
104
+ }
105
+ };
106
+ })());
107
+ }
108
+
109
+ function load_actions(){
110
+ $.ajax({
111
+ url: seo_action_list_path(),
112
+ type: 'GET',
113
+ dataType: 'json',
114
+ success: function(data){
115
+ var actions = _.sortBy(data, function(obj){ return obj['name']; });
116
+ $('.seo_action_list').append(JST['phaseout/templates/action_list']({ actions: actions }));
117
+ for( var index in actions ){ click_on_action_handler(actions[index]); }
118
+ }
119
+ });
120
+
121
+ $(document).delegate('a[data-delete-field]', 'click', function(){
122
+ $('#' + $(this).data('delete-field')).remove();
123
+ });
124
+ }
125
+
126
+ $(document).ready(function(){ load_actions() });
@@ -0,0 +1,9 @@
1
+ <li id="<%- @action_key.action_id %>_<%- @action_key.id %>_<%- @key %>" class="seo_field_item">
2
+ <label for="<%- @action_key.action_id %>_<%- @action_key.id %>_<%- @key %>_textarea">
3
+ <%- PhaseoutFields[@key] || @key %>
4
+ </label>
5
+ <textarea id="<%- @action_key.action_id %>_<%- @action_key.id %>_<%- @key %>_textarea" name="seo_field[<%- @key %>]"><%- @field %></textarea>
6
+ <a href="javascript:void(0)" class="delete_field" data-delete-field="<%- @action_key.action_id %>_<%- @action_key.id %>_<%- @key %>" data-confirm="<%- PhaseoutTranslations.common.are_you_sure %>">
7
+ <%- PhaseoutTranslations.common.delete %>
8
+ </a>
9
+ </li>
@@ -0,0 +1,20 @@
1
+ <li id="<%- @action_id %>_<%- @id %>" class="seo_action_key_item">
2
+ <a id="<%- @action_id %>_<%- @id %>_delete" href="<%- seo_fields_delete_path @key %>" class="seo_action_key_delete" data-method="delete" data-remote="true"><%- PhaseoutTranslations.common.delete %> [X]</a>
3
+ <a id="<%- @action_id %>_<%- @id %>_link" href="javascript:void(0)" class="seo_action_key_link"><%- @name %></a>
4
+ <form action="<%- seo_fields_update_path @key %>" class="action_key_fields" style="display: none" data-method="put" data-remote="true">
5
+ <ul class="seo_form_fields_list">
6
+ <% for key, field of @fields: %>
7
+ <%- JST['phaseout/templates/action_key_field'](action_key: this, key: key, field: field) %>
8
+ <% end %>
9
+ </ul>
10
+ <div class="seo_fields_buttons">
11
+ <select class="seo_fields_to_add">
12
+ <% for field_method, humanized_field of PhaseoutFields : %>
13
+ <option value="<%- field_method %>"><%- humanized_field %></option>
14
+ <% end %>
15
+ </select>
16
+ <input id="<%- @action_id %>_<%- @id %>_button" type="button" value="<%- PhaseoutTranslations.common.add %>" class="seo_fields_add_button"/>
17
+ <input type="submit" value="<%- PhaseoutTranslations.common.update %>" class="submit_seo_fields"/>
18
+ </div>
19
+ </form>
20
+ </li>
@@ -0,0 +1,3 @@
1
+ <% for index, action_key of @action_keys : %>
2
+ <%- JST['phaseout/templates/action_key_item'](action_key) %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% for index, action of @actions : %>
2
+ <%- JST['phaseout/templates/action_list_item'](action) %>
3
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <li id="<%- @id %>" class="seo_action_item">
2
+ <h3>
3
+ <a href="javascript:void(0)" data-action-key="<%- @key %>" class="seo_action_item_link">
4
+ <%- @name %>
5
+ </a>
6
+ </h3>
7
+ <ul class="action_key_list" style="display: none"/>
8
+ </li>
@@ -0,0 +1,150 @@
1
+ body {
2
+ margin: 0px;
3
+ padding: 0px;
4
+ background: #EEFFEE;
5
+ }
6
+
7
+ h1 {
8
+ margin: 0px;
9
+ padding: 5px 40px;
10
+ font: 16pt Arial normal;
11
+ color: #EEFFEE;
12
+ background: #003300;
13
+ }
14
+
15
+ .seo_action_list {
16
+ margin: 20px 20px;
17
+ padding: 0px;
18
+ list-style: none;
19
+ font: 10pt Verdana normal;
20
+ }
21
+
22
+ .seo_action_item {
23
+ margin: 0px;
24
+ padding: 0px;
25
+ background: #CCFFCC;
26
+
27
+ h3 {
28
+ margin: 5px 0px;
29
+ padding: 7px 20px;
30
+ font-size: 12pt;
31
+ font-weight: normal;
32
+ background: #AACCAA;
33
+ a {
34
+ display: block;
35
+ color: #330000;
36
+ text-decoration: none;
37
+ &:hover {
38
+ text-decoration: underline;
39
+ }
40
+ }
41
+ }
42
+
43
+ &.opened {
44
+ h3 {
45
+ background: #669966;
46
+ }
47
+ }
48
+ }
49
+
50
+ .action_key_list {
51
+ padding: 5px 0px;
52
+ list-style: none;
53
+ }
54
+
55
+ .seo_action_key_item {
56
+ margin: 5px 35px;
57
+ position: relative;
58
+
59
+ .seo_action_key_delete {
60
+ top: 3px;
61
+ right: 20px;
62
+ position: absolute;
63
+ color: #330000;
64
+ text-decoration: none;
65
+
66
+ &:hover {
67
+ text-decoration: underline;
68
+ }
69
+
70
+ &:hover + .seo_action_key_link {
71
+ background: #AACCAA;
72
+ }
73
+ }
74
+
75
+ .seo_action_key_link {
76
+ padding: 3px 5px;
77
+ display: block;
78
+ color: #330000;
79
+ text-decoration: none;
80
+
81
+ &:hover {
82
+ background: #AACCAA;
83
+ text-decoration: underline;
84
+ }
85
+ }
86
+
87
+ &.opened {
88
+ background: #FFFFAA;
89
+
90
+ .seo_action_key_link {
91
+ color: #331100;
92
+ background: #FF9933;
93
+
94
+ &:hover {
95
+ color: #FFDDAA;
96
+ background: #AA6633;
97
+ }
98
+ }
99
+
100
+ .seo_action_key_delete {
101
+ color: #331100;
102
+ }
103
+
104
+ .seo_action_key_delete:hover {
105
+ color: #FFDDAA;
106
+
107
+ & + .seo_action_key_link {
108
+ color: #FFDDAA;
109
+ background: #AA6633;
110
+ }
111
+ }
112
+ }
113
+
114
+ .seo_fields_buttons {
115
+ margin: 15px 0px 0px 0px;
116
+ padding: 0px 20px 10px;
117
+ display: block;
118
+ position: relative;
119
+
120
+ .submit_seo_fields {
121
+ right: 20px;
122
+ position: absolute;
123
+ }
124
+ }
125
+ }
126
+
127
+ .seo_form_fields_list {
128
+ margin: 0px 20px 0px -20px;
129
+ list-style: none;
130
+
131
+ label {
132
+ display: block;
133
+ }
134
+
135
+ textarea {
136
+ width: 100%;
137
+ height: 80px;
138
+ }
139
+
140
+ .seo_field_item {
141
+ margin: 15px 0px 0px 0px;
142
+ position: relative;
143
+
144
+ .delete_field {
145
+ top: 0px;
146
+ right: 0px;
147
+ position: absolute;
148
+ }
149
+ }
150
+ }
@@ -1,7 +1,70 @@
1
1
  module Phaseout
2
2
  class PhaseoutController < ::Phaseout::ApplicationController
3
3
 
4
- def index
4
+ def update
5
+ @seo_fields = Phaseout::SEOFields.find params[:key]
6
+ if @seo_fields
7
+ @seo_fields.values = params[:seo_field].to_h.symbolize_keys
8
+ @seo_fields.save
9
+ render json: @seo_fields.to_json
10
+ else
11
+ not_found
12
+ end
13
+ end
14
+
15
+ def delete
16
+ @seo_fields = Phaseout::SEOFields.find params[:key]
17
+ if @seo_fields
18
+ @seo_fields.delete
19
+ render json: { status: :ok }.to_json
20
+ else
21
+ not_found
22
+ end
23
+ end
24
+
25
+ def actions
26
+ streamed_json_response do |stream|
27
+ ::Phaseout::SEOAction.all do |seo_action|
28
+ stream.call seo_action
29
+ end
30
+ end
31
+ end
32
+
33
+ def action_keys
34
+ streamed_json_response do |stream|
35
+ ::Phaseout::SEOFields.all(params[:key]) do |fields|
36
+ stream.call fields
37
+ end
38
+ end
39
+ end
40
+
41
+ protected
42
+ def streamed_json_response(&block)
43
+ headers['Content-Type'] = 'application/json'
44
+ headers['X-Accel-Buffering'] = 'no'
45
+ headers['Cache-Control'] ||= 'no-cache'
46
+ headers.delete 'Content-Length'
47
+
48
+ response.stream.write '['
49
+
50
+ first = true
51
+ stream_block = lambda do |data|
52
+ if first
53
+ first = false
54
+ response.stream.write data.to_json
55
+ else
56
+ response.stream.write ",#{data.to_json}"
57
+ end
58
+ end
59
+
60
+ yield stream_block
61
+
62
+ response.stream.write ']'
63
+ response.stream.close
64
+ end
65
+
66
+ def not_found(data = { status: :not_found })
67
+ render json: data.to_json, status: 404
5
68
  end
6
69
 
7
70
  end
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>Phaseout SEO Management</title>
4
+ <title>phaSEOut Management</title>
5
5
  <%= stylesheet_link_tag 'phaseout/application', media: 'all' %>
6
6
  <%= javascript_include_tag 'phaseout/application' %>
7
7
  <%= csrf_meta_tags %>
@@ -1 +1,3 @@
1
- Index!
1
+ <h1>phaSEOut Management</h1>
2
+
3
+ <ul class="seo_action_list"/>
@@ -0,0 +1,36 @@
1
+ pt-BR:
2
+ seo:
3
+ common:
4
+ add: 'Adicionar'
5
+ update: 'Atualizar'
6
+ delete: 'Apagar'
7
+ add_prompt: 'Adicione um campo customizado:'
8
+ are_you_sure: 'Tem certeza?'
9
+ already_added: 'Campo já adicionado!'
10
+ fields:
11
+ page_title: 'Título da Página'
12
+ meta_description: 'Meta Descrição'
13
+ meta_keywords: 'Meta Palavras Chave'
14
+ og_url: 'Facebook URL'
15
+ og_title: 'Facebook Título'
16
+ og_image: 'Facebook Imagem'
17
+ og_description: 'Facebook Descrição'
18
+ other: 'Outro'
19
+ en:
20
+ seo:
21
+ common:
22
+ add: 'Add'
23
+ update: 'Update'
24
+ delete: 'Delete'
25
+ add_prompt: 'Add a custom field:'
26
+ are_you_sure: 'Are you sure?'
27
+ already_added: 'Field already added!'
28
+ fields:
29
+ page_title: 'Page Title'
30
+ meta_description: 'Meta Description'
31
+ meta_keywords: 'Meta Keywords'
32
+ og_url: 'Facebook URL'
33
+ og_title: 'Facebook Title'
34
+ og_image: 'Facebook Image'
35
+ og_description: 'Facebook Description'
36
+ other: 'Other'
data/config/routes.rb CHANGED
@@ -1,3 +1,8 @@
1
1
  Phaseout::Engine.routes.draw do
2
2
  root to: 'phaseout#index'
3
+
4
+ get '/actions', to: 'phaseout#actions', as: :seo_action_list
5
+ get '/action/:key/keys', to: 'phaseout#action_keys', as: :seo_action_keys
6
+ put '/fields/:key/update', to: 'phaseout#update', as: :seo_fields_update
7
+ delete '/fields/:key/delete', to: 'phaseout#delete', as: :seo_fields_delete
3
8
  end
data/lib/phaseout.rb CHANGED
@@ -3,6 +3,9 @@ require 'redis-namespace'
3
3
 
4
4
  require 'phaseout/version'
5
5
  require 'phaseout/engine'
6
+ require 'phaseout/seo_action'
7
+ require 'phaseout/seo_fields'
8
+ require 'phaseout/seo_helper'
6
9
  require 'phaseout/seo'
7
10
  require 'phaseout/handler'
8
11
 
@@ -14,8 +17,10 @@ module Phaseout
14
17
  def self.redis
15
18
  @redis ||= config_redis(Redis.new)
16
19
  end
17
- end
18
20
 
19
- ActiveSupport.on_load(:action_view) do
20
- include Phaseout::SEOHelper
21
+ def self.default_fields
22
+ @default_fields ||= ::Phaseout::SEOHelper.instance_methods + [:other]
23
+ end
21
24
  end
25
+
26
+ ActiveSupport.on_load(:action_view){ include Phaseout::SEOHelper }
@@ -9,12 +9,12 @@ module Phaseout
9
9
 
10
10
  def call(&action_block)
11
11
  if seo_fields
12
- @controller.seo_tags = seo_fields.to_html(@controller)
12
+ @controller.seo_tags = seo_fields.to_html @controller
13
13
  else
14
- @controller.seo_tags = @default.to_html(@controller)
15
- set_blank_field if @blank_field && @editable
14
+ @controller.seo_tags = @default.to_html @controller
16
15
  end
17
16
  action_block.call
17
+ set_blank_field if @controller.status == 200 && @blank_field && @editable
18
18
  true
19
19
  end
20
20
 
@@ -23,7 +23,7 @@ module Phaseout
23
23
  end
24
24
 
25
25
  def key
26
- @key ||= [ 'seo_key:', @controller.class.name, '#', @action, '/', eval_pattern(@key_pattern) ].join
26
+ @key ||= I18n.transliterate( [ 'seo_key:', @controller.class.name, '#', @action, ':', eval_pattern(@key_pattern) ].join.gsub(/\s+/, '_').underscore )
27
27
  end
28
28
 
29
29
  def seo_fields
@@ -40,13 +40,13 @@ module Phaseout
40
40
  end
41
41
 
42
42
  def class_index_key
43
- ['action:', @controller.class.name, '#', @action].join
43
+ ['action:', @controller.class.name, '#', @action].join.gsub(/\s+/, '_').underscore
44
44
  end
45
45
 
46
46
  protected
47
47
  def set_blank_field
48
- Phaseout.redis.sadd class_index_key, key
49
- Phaseout.redis.set key, Phaseout::SEOFields.new(key, as).dump
48
+ Phaseout::SEOAction.new(class_index_key).add key
49
+ Phaseout::SEOFields.new(key, as).save
50
50
  end
51
51
 
52
52
  def eval_pattern(pattern)
data/lib/phaseout/seo.rb CHANGED
@@ -1,12 +1,9 @@
1
- require 'phaseout/seo_fields'
2
- require 'phaseout/seo_helper'
3
-
4
1
  module Phaseout
5
2
  module SEO
6
3
  extend ActiveSupport::Concern
7
4
 
8
5
  def seo_tags
9
- @_seo_tags ||= ''
6
+ @_seo_tags || ''
10
7
  end
11
8
 
12
9
  def seo_tags=(value)
@@ -18,8 +15,15 @@ module Phaseout
18
15
  end
19
16
 
20
17
  module ClassMethods
21
- def seo_tags_for(action, as: action, key: action, editable: true, &block)
18
+ def seo_group_name
19
+ @_seo_group_name ||= Hash.new
20
+ end
21
+
22
+ def seo_tags_for(action, as: action, key: as, editable: true, grouped_as: nil, &block)
23
+ seo_action = Phaseout::SEOAction.new self.name, action
24
+ seo_group_name[seo_action.key] = grouped_as || seo_action.key
22
25
  around_block = lambda do |controller, action_block|
26
+ return action_block.call unless request.format.html?
23
27
  Phaseout::Handler.new(controller, action, as, key, editable, &block).call &action_block
24
28
  end
25
29
  around_action around_block, only: action
@@ -0,0 +1,68 @@
1
+ module Phaseout
2
+ class SEOAction
3
+ attr_reader :controller, :action
4
+
5
+ def initialize(controller_or_key, action = nil)
6
+ if action
7
+ @controller, @action = controller_or_key, action
8
+ else
9
+ @controller, @action = controller_or_key.split '#'
10
+ end
11
+ end
12
+
13
+ def key
14
+ I18n.transliterate([ @controller, @action ].join '#' ).gsub(/\s+/, '_').underscore
15
+ end
16
+
17
+ def id
18
+ I18n.transliterate([ @controller, @action ].join '-' ).gsub(/\s+/, '_').underscore
19
+ end
20
+
21
+ def fields(&block)
22
+ if block_given?
23
+ SEOFields.all self.key, &block
24
+ else
25
+ @fields ||= SEOFields.all self.key
26
+ end
27
+ end
28
+
29
+ def name
30
+ controller.camelize.constantize.seo_group_name[key] || key
31
+ end
32
+
33
+ def add(field_key)
34
+ Phaseout.redis.sadd key, field_key
35
+ end
36
+
37
+ def remove(field_key)
38
+ Phaseout.redis.srem key, field_key
39
+ end
40
+
41
+ def to_json
42
+ {
43
+ id: id,
44
+ key: key,
45
+ name: name,
46
+ action: action,
47
+ controller: controller
48
+ }.to_json
49
+ end
50
+
51
+ def self.find(key)
52
+ self.new "action:#{key}"
53
+ end
54
+
55
+ def self.all(&block)
56
+ unless block_given?
57
+ values = []
58
+ self.all{ |action| values << action }
59
+ return values
60
+ end
61
+
62
+ pattern = "#{Phaseout.redis.namespace}:action:*"
63
+ Phaseout.redis.scan_each(match: pattern) do |value|
64
+ yield self.new( value.match(/#{ Phaseout.redis.namespace }\:action\:/).post_match )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -2,9 +2,10 @@ module Phaseout
2
2
  class SEOFields
3
3
  attr_reader :key, :human_name
4
4
  attr_accessor :values, :default
5
+ alias :fields :values
5
6
 
6
7
  def initialize(key, human_name, values = Hash.new, &block)
7
- @key, @human_name, @values = key, human_name, values
8
+ @key, @human_name, @values = I18n.transliterate(key).gsub(/\s+/, '_').underscore, human_name, values
8
9
  yield(self) if block_given?
9
10
  end
10
11
 
@@ -14,6 +15,29 @@ module Phaseout
14
15
  end.join.html_safe
15
16
  end
16
17
 
18
+ def action_key
19
+ @action_key ||= @key.match('seo_key:').post_match.match(':').pre_match
20
+ end
21
+
22
+ def action
23
+ @action ||= ::Phaseout::SEOAction.new action_key
24
+ end
25
+
26
+ def id
27
+ @key.match(/\#.+\:/).post_match.gsub(/\s+/, '_').underscore
28
+ end
29
+
30
+ def to_json
31
+ {
32
+ id: id,
33
+ key: @key.match('seo_key:').post_match,
34
+ fields: @values,
35
+ name: @human_name,
36
+ action_id: action_key.gsub('#', '_').underscore,
37
+ action_key: action_key
38
+ }.to_json
39
+ end
40
+
17
41
  def dump
18
42
  Marshal.dump self
19
43
  end
@@ -22,6 +46,11 @@ module Phaseout
22
46
  Phaseout.redis.set key, self.dump
23
47
  end
24
48
 
49
+ def delete
50
+ Phaseout::SEOAction.find(action_key).remove key
51
+ Phaseout.redis.del key
52
+ end
53
+
25
54
  def evaluated_values(controller)
26
55
  @_values ||= if @default
27
56
  @default.evaluated_values(controller).merge @values
@@ -47,7 +76,7 @@ module Phaseout
47
76
  end
48
77
 
49
78
  def inspect
50
- "#<Phaseout::SEO #{ @key.match('seo_key:').post_match.match('/').pre_match } #{@human_name}>"
79
+ "#<Phaseout::SEO #{action_key} #{@human_name}>"
51
80
  end
52
81
  alias :to_s :inspect
53
82
 
@@ -55,7 +84,7 @@ module Phaseout
55
84
  if block_given?
56
85
  @values[method.to_sym] = block
57
86
  else
58
- @values[method.to_sym] = args
87
+ @values[method.to_sym] = args unless args.empty?
59
88
  end
60
89
  end
61
90
 
@@ -72,29 +101,17 @@ module Phaseout
72
101
  dump ? Marshal.load(dump) : nil
73
102
  end
74
103
 
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
104
+ def self.all(action_key, &block)
105
+ unless block_given?
106
+ values = []
107
+ self.all(action_key){ |field| values << field }
108
+ return values
85
109
  end
86
- end
87
110
 
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
111
+ class_index_key = "#{Phaseout.redis.namespace}:action:#{action_key}"
112
+ Phaseout.redis.sscan_each(class_index_key) do |value|
113
+ yield self.find value.match('seo_key:').post_match
96
114
  end
97
115
  end
98
-
99
116
  end
100
117
  end
@@ -1,3 +1,3 @@
1
1
  module Phaseout
2
- VERSION = '0.0.1.danger.very.unstable'
2
+ VERSION = '0.0.1'
3
3
  end
data/phaseout.gemspec CHANGED
@@ -22,6 +22,9 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency 'redis'
23
23
  spec.add_dependency 'redis-namespace'
24
24
 
25
+ spec.add_dependency 'eco'
26
+ spec.add_dependency 'coffee-script'
27
+
25
28
  spec.add_development_dependency 'rake'
26
29
  spec.add_development_dependency 'bundler'
27
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phaseout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.danger.very.unstable
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dalton Pinto
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-24 00:00:00.000000000 Z
12
+ date: 2014-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -39,6 +39,34 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: eco
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
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: coffee-script
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
42
70
  - !ruby/object:Gem::Dependency
43
71
  name: rake
44
72
  requirement: !ruby/object:Gem::Requirement
@@ -79,15 +107,24 @@ files:
79
107
  - LICENSE.txt
80
108
  - README.mdown
81
109
  - Rakefile
110
+ - app/assets/javascripts/phaseout/application.js.erb
111
+ - app/assets/javascripts/phaseout/templates/action_key_field.jst.eco
112
+ - app/assets/javascripts/phaseout/templates/action_key_item.jst.eco
113
+ - app/assets/javascripts/phaseout/templates/action_key_list.jst.eco
114
+ - app/assets/javascripts/phaseout/templates/action_list.jst.eco
115
+ - app/assets/javascripts/phaseout/templates/action_list_item.jst.eco
116
+ - app/assets/stylesheets/phaseout/application.css.scss
82
117
  - app/controllers/phaseout/application_controller.rb
83
118
  - app/controllers/phaseout/phaseout_controller.rb
84
119
  - app/views/layouts/phaseout/application.html.erb
85
120
  - app/views/phaseout/phaseout/index.html.erb
121
+ - config/locales/phaseout.yml
86
122
  - config/routes.rb
87
123
  - lib/phaseout.rb
88
124
  - lib/phaseout/engine.rb
89
125
  - lib/phaseout/handler.rb
90
126
  - lib/phaseout/seo.rb
127
+ - lib/phaseout/seo_action.rb
91
128
  - lib/phaseout/seo_fields.rb
92
129
  - lib/phaseout/seo_helper.rb
93
130
  - lib/phaseout/version.rb
@@ -107,9 +144,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
144
  version: '0'
108
145
  required_rubygems_version: !ruby/object:Gem::Requirement
109
146
  requirements:
110
- - - ">"
147
+ - - ">="
111
148
  - !ruby/object:Gem::Version
112
- version: 1.3.1
149
+ version: '0'
113
150
  requirements: []
114
151
  rubyforge_project:
115
152
  rubygems_version: 2.4.2