phaseout 0.0.1.danger.very.unstable → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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