redis_snippets 0.0.10 → 1.0.2

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.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +4 -2
  3. data/.rspec +2 -0
  4. data/.travis.yml +19 -0
  5. data/Gemfile +12 -0
  6. data/README.md +84 -18
  7. data/Rakefile +5 -0
  8. data/app/controllers/redis_snippets/snippets_controller.rb +5 -6
  9. data/app/helpers/redis_snippets/snippets_helper.rb +5 -23
  10. data/app/presenters/snippet_presenter.rb +67 -0
  11. data/app/{models/redis_snippets/snippets.rb → services/snippet_store_service.rb} +9 -1
  12. data/app/views/redis_snippets/snippets/show.html.erb +11 -15
  13. data/config/routes.rb +1 -1
  14. data/lib/redis_snippets/engine.rb +3 -1
  15. data/lib/redis_snippets/redis.rb +10 -5
  16. data/lib/redis_snippets/{help.rb → util.rb} +2 -2
  17. data/lib/redis_snippets/version.rb +1 -1
  18. data/lib/redis_snippets.rb +4 -2
  19. data/redis_snippets.gemspec +5 -4
  20. data/spec/app/helpers/redis_snippets/snippets_helper_spec.rb +38 -0
  21. data/spec/app/presenters/snippet_presenter_spec.rb +53 -0
  22. data/spec/app/presenters/snippet_presenter_transform_spec.rb +45 -0
  23. data/spec/app/services/snippet_store_service_spec.rb +44 -0
  24. data/spec/dummy/.ruby-version +1 -0
  25. data/spec/dummy/Rakefile +6 -0
  26. data/spec/dummy/app/assets/config/manifest.js +3 -0
  27. data/spec/dummy/app/assets/images/.keep +0 -0
  28. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  29. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/spec/dummy/bin/rails +4 -0
  32. data/spec/dummy/bin/rake +4 -0
  33. data/spec/dummy/bin/setup +33 -0
  34. data/spec/dummy/config/application.rb +29 -0
  35. data/spec/dummy/config/boot.rb +5 -0
  36. data/spec/dummy/config/environment.rb +5 -0
  37. data/spec/dummy/config/environments/development.rb +62 -0
  38. data/spec/dummy/config/environments/test.rb +48 -0
  39. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  40. data/spec/dummy/config/initializers/assets.rb +12 -0
  41. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  43. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  44. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  45. data/spec/dummy/config/initializers/inflections.rb +16 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  47. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/spec/dummy/config/puma.rb +38 -0
  49. data/spec/dummy/config/routes.rb +3 -0
  50. data/spec/dummy/config.ru +5 -0
  51. data/spec/dummy/lib/assets/.keep +0 -0
  52. data/spec/dummy/log/.keep +0 -0
  53. data/spec/dummy/tmp/.keep +0 -0
  54. data/spec/dummy/tmp/development_secret.txt +1 -0
  55. data/spec/rails_helper.rb +54 -0
  56. data/spec/spec_helper.rb +13 -0
  57. data/spec/support/simplecov_setup.rb +5 -0
  58. metadata +105 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d57ab380b6653a5a2bbadfd96bcb3f5c2b1033b0
4
- data.tar.gz: c6ef4474551730d558e675fa49fde37e5f20219a
2
+ SHA256:
3
+ metadata.gz: 1157b175b0ce0c3c72be376383f9da2d522999f69304c093cd3ddbc22eb0d25d
4
+ data.tar.gz: 7673c2ffe8fd7b0134847e1de912dd94aadf900a267c937625e3ace993f106ee
5
5
  SHA512:
6
- metadata.gz: c81fa957b20f7e9d1b7cdf0164bae965e85cea2a51f6ad1c65d3ba6f17d24a4e0119cd8f5bd9889dbc9e54c12df67735cd43eac6ab2f84897837925bf90a000a
7
- data.tar.gz: f5ed406436c21e5969129f901fcdea444f89f68b1dd10a17576a60798c7bab9790f542692e7b47823ff4487c49e272bd3614acb02ef5dae6da82a84832b385c0
6
+ metadata.gz: fc847d478f9c40aef9fe2ecb067eee24c700d23b1053bcb09280db46c5025b09a94e6363ecdb2f0d70e567a606b75cb53d0771e16844b3a934b6eb815c4bb44f
7
+ data.tar.gz: fbfc1e84fc0c9794221880574abde61e7d3e2c11720c0c92062be5592c0f15d599f428b556abe777156fc2662790b4386c60cd553720d9567a3664337761602d
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
- *.tmproj
2
- pkg
3
1
  .bundle
2
+ pkg
3
+ spec/dummy/log
4
+ Gemfile.lock
5
+ coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ env:
5
+ global:
6
+ - CC_TEST_REPORTER_ID=aa59e066b7cd7b5477aecc5c17004d78d35012420e791d23b17c0ea705ef9cd7
7
+ before_script:
8
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
9
+ - chmod +x ./cc-test-reporter
10
+ - ./cc-test-reporter before-build
11
+ before_install:
12
+ - gem update --system
13
+ - gem install bundler --version 2.0.2
14
+ rvm:
15
+ - 2.6.5
16
+ script:
17
+ - bundle exec rake
18
+ after_script:
19
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+
4
+ group :test, :development do
5
+ gem "rails", ">= 6.0"
6
+ gem "rspec-rails", ">= 3.9.0"
7
+ end
8
+
9
+ group :test do
10
+ gem "mock_redis"
11
+ gem "simplecov"
12
+ end
data/README.md CHANGED
@@ -1,20 +1,48 @@
1
1
  # Redis Snippets
2
2
 
3
+ [![Version](https://img.shields.io/gem/v/redis_snippets.svg?style=flat-square)](https://rubygems.org/gems/redis_snippets)
4
+ [![Build](https://img.shields.io/travis/wulffeld/redis_snippets.svg?style=flat-square)](https://travis-ci.org/wulffeld/redis_snippets)
5
+ [![Maintainability](https://img.shields.io/codeclimate/maintainability/wulffeld/redis_snippets?style=flat-square)](https://codeclimate.com/github/wulffeld/redis_snippets)
6
+ [![Coverage](https://img.shields.io/codeclimate/coverage/wulffeld/redis_snippets?style=flat-square)](https://codeclimate.com/github/wulffeld/redis_snippets)
7
+
3
8
  ## Background
4
9
 
5
- Easily store snippets of content in Redis.
10
+ Easily store snippets of content in Redis. Inspired by plugin for Wordpress
11
+ named Snippets.
12
+
13
+ With redis_snippets you could for instance store AdSense code snippets or
14
+ other HTML/JS content.
15
+
16
+ ## Requirements
17
+
18
+ Gems:
19
+
20
+ * rails 5.x or higher
21
+ * redis
22
+ * redis-namespace
23
+
24
+ ## Installation
25
+
26
+ Add to your Rails projects Gemfile and bundle install:
27
+
28
+ ```
29
+ gem "redis_snippets"
30
+ ```
6
31
 
7
- ## How
32
+ ## Usage
8
33
 
9
- It's a Rails engine so add redis-snippets to your Gemfile and put this in an initializer:
34
+ It's a Rails engine so add redis-snippets to your Gemfile and put this in an
35
+ initializer:
10
36
 
11
37
  ``` ruby
12
- App::Application.config.redis_snippets = {
13
- :connection => ::Redis::Namespace.new("my_namespace", :redis => ::Redis.new),
14
- :keys => [:key1, :key2]
38
+ Rails.application.config.redis_snippets = {
39
+ connection: ::Redis::Namespace.new("my_namespace", redis: ::Redis.new),
40
+ keys: [:key1, :key2]
15
41
  }
16
42
  ```
17
43
 
44
+ The names of the keys are entirely up to you.
45
+
18
46
  You should then be able to access /admin/snippets/.
19
47
 
20
48
  In your views use helper snippet().
@@ -28,20 +56,63 @@ In your views use helper snippet().
28
56
  One snippet area can include multiple snippets if you separate them with a
29
57
 
30
58
  ```
31
- [snippet]
59
+ [section]
32
60
  ```
33
61
 
34
- The snippet helper will randomly select the snippet. This is convenient for ad delivery for example.
62
+ The snippet helper will randomly select the snippet. This is convenient for ad
63
+ delivery or perhaps A/B testing 🤷‍♂.
35
64
 
36
65
  ## Multi Site
37
66
 
38
- If you're using one app to serve multiple sites a little more configuration is necessary.
67
+ If you're using one app to serve multiple sites a little more configuration is
68
+ necessary.
39
69
 
40
70
  ``` ruby
41
- App::Application.config.redis_snippets = {
42
- :connection => ::Redis::Namespace.new("my_namespace", :redis => ::Redis.new),
43
- :multi_site => true,
44
- :keys => [:key1, :key2]
71
+ Rails.application.config.redis_snippets = {
72
+ connection: ::Redis::Namespace.new("my_namespace", redis: ::Redis.new),
73
+ multi_site: true,
74
+ keys: [:key1, :key2],
75
+ transform: "MySnippetTransform"
76
+ }
77
+ ```
78
+
79
+ ## Transforming Snippets
80
+
81
+ Sometimes you might want to transform snippets. This happens after
82
+ randomization so you get the actual snippet content to be rendered passed to
83
+ your transform class.
84
+
85
+ The transform class must respond to .transforms? and #transform. Example:
86
+
87
+ ``` ruby
88
+ class MySnippetTransform
89
+ def initialize(content:, key:)
90
+ @content = content
91
+ @key = key
92
+ end
93
+
94
+ # Must return content.
95
+ def transform
96
+ @content.gsub("Amazon", "Etsy")
97
+ end
98
+
99
+ class << self
100
+ def transforms?(key:)
101
+ key == :advert_header
102
+ end
103
+ end
104
+ end
105
+ ```
106
+
107
+ I personally use this to insert special CSS code for AdSense. This saves me
108
+ from having to do this manually whenever I update it or add it.
109
+
110
+ ``` ruby
111
+ Rails.application.config.redis_snippets = {
112
+ connection: ::Redis::Namespace.new("my_namespace", redis: ::Redis.new),
113
+ multi_site: true,
114
+ keys: [:key1, :key2],
115
+ transform: "MySnippetTransform"
45
116
  }
46
117
  ```
47
118
 
@@ -53,8 +124,3 @@ def redis_snippet_site_key
53
124
  request.host
54
125
  end
55
126
  ```
56
-
57
- ## Requirements
58
-
59
- * redis
60
- * redis-namespace
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -1,7 +1,7 @@
1
1
  class RedisSnippets::SnippetsController < ApplicationController
2
- include RedisSnippets::Help
3
-
4
- before_filter :redis_snippets_authenticate_admin_user!
2
+ include RedisSnippets::Util
3
+
4
+ before_action :redis_snippets_authenticate_admin_user!
5
5
 
6
6
  layout 'admin'
7
7
 
@@ -10,10 +10,9 @@ class RedisSnippets::SnippetsController < ApplicationController
10
10
 
11
11
  def update
12
12
  params[:snippets].each do |key, content|
13
- raise "#{key} not in the specified keys." unless RedisSnippets::Engine.config.redis_snippets[:keys].include?(key.to_sym)
14
- RedisSnippets::Snippets.update(snippet_key(key), params[:snippets][key])
13
+ SnippetStoreService.update(snippet_key(key), params[:snippets][key])
15
14
  end
16
-
15
+
17
16
  flash[:notice] = 'Snippets updated.'
18
17
  redirect_to redis_snippets.snippets_path
19
18
  end
@@ -1,32 +1,14 @@
1
1
  module RedisSnippets
2
2
  module SnippetsHelper
3
- include RedisSnippets::Help
4
-
5
- def snippet_content(snippet_name)
6
- RedisSnippets::Snippets.send(snippet_key(snippet_name))
7
- end
3
+ include RedisSnippets::Util
8
4
 
9
5
  # Return true if snippet has content.
10
- def snippet_has_content?(snippet_name)
11
- !snippet_content(snippet_name).blank?
12
- end
13
-
14
- def snippet(snippet_name, classes=nil)
15
- return '' if controller.status == 404
16
- snippet = snippet_content(snippet_name)
17
- return '' if snippet.blank?
18
- snippets = snippet.split("[section]")
19
- build_snippet(snippets[rand(snippets.length)], snippet_class_list(snippet_name, classes))
20
- end
21
-
22
- def snippet_class_list(snippet_name, classes)
23
- ['snippet', classes || snippet_name.to_s].compact.join(' ').html_safe
6
+ def snippet_has_content?(key)
7
+ !SnippetStoreService.send(snippet_key(key)).blank?
24
8
  end
25
9
 
26
- def build_snippet(content, classes)
27
- content_tag(:div,
28
- content.html_safe,
29
- :class => classes)
10
+ def snippet(key, classes = nil)
11
+ SnippetPresenter.new(view: self, key: key, classes: classes).call
30
12
  end
31
13
  end
32
14
  end
@@ -0,0 +1,67 @@
1
+
2
+ class SnippetPresenter
3
+ include RedisSnippets::Util
4
+
5
+ SECTION_DELIMITER = "[section]"
6
+
7
+ delegate :random_snippet, to: "self.class"
8
+
9
+ def initialize(view:, key:, classes: nil)
10
+ @view = view
11
+ @key = key
12
+ @classes = classes
13
+ end
14
+
15
+ def call
16
+ prepare_snippet
17
+ render
18
+ end
19
+
20
+ protected
21
+
22
+ def prepare_snippet
23
+ @snippet = ""
24
+
25
+ return unless content = SnippetStoreService.send(snippet_key(@key))
26
+
27
+ snippets = content.split("#{SECTION_DELIMITER}")
28
+ @snippet = random_snippet(content)
29
+
30
+ if transform_class && transform_class.transforms?(key: @key)
31
+ @snippet = transform_class.new(content: @snippet, key: @key).transform
32
+ end
33
+ end
34
+
35
+ def snippet_class_list
36
+ [
37
+ "snippet",
38
+ @key.to_s,
39
+ *@classes
40
+ ].reject(&:blank?).join(" ").html_safe
41
+ end
42
+
43
+ def render
44
+ # If snippet is empty we avoid wrapping it in the div.
45
+ if @snippet.blank?
46
+ ""
47
+ else
48
+ @view.content_tag(:div, @snippet.html_safe, class: snippet_class_list)
49
+ end
50
+ end
51
+
52
+ def transform_class
53
+ @klass ||=
54
+ if RedisSnippets::Engine.config.redis_snippets[:transform].is_a?(Proc)
55
+ klass = RedisSnippets::Engine.config.redis_snippets[:transform].call and klass.constantize
56
+ else
57
+ RedisSnippets::Engine.config.redis_snippets[:transform] and RedisSnippets::Engine.config.redis_snippets[:transform].constantize
58
+ end
59
+ end
60
+
61
+ class << self
62
+ def random_snippet(content)
63
+ snippets = content.split("#{SECTION_DELIMITER}").map { |section| section.gsub(/^\n/, "") }
64
+ snippets[rand(snippets.length)]
65
+ end
66
+ end
67
+ end
@@ -1,10 +1,12 @@
1
- class RedisSnippets::Snippets
1
+ class SnippetStoreService
2
2
  class << self
3
3
  def update(key, content)
4
+ ensure_key_is_defined!(key)
4
5
  RedisSnippets::Redis.set("snippets:#{key}", content)
5
6
  end
6
7
 
7
8
  def del(key)
9
+ ensure_key_is_defined!(key)
8
10
  RedisSnippets::Redis.del("snippets:#{key}")
9
11
  end
10
12
 
@@ -12,5 +14,11 @@ class RedisSnippets::Snippets
12
14
  def method_missing(method, *args)
13
15
  RedisSnippets::Redis.get("snippets:#{method}")
14
16
  end
17
+
18
+ protected
19
+
20
+ def ensure_key_is_defined!(key)
21
+ raise UndefinedSnippetsKey.new("#{key} not in the specified keys.") unless RedisSnippets::Engine.config.redis_snippets[:keys].include?(key.to_sym)
22
+ end
15
23
  end
16
24
  end
@@ -1,23 +1,19 @@
1
- <div class="redis_snippets">
2
- <h1>Snippets</h1>
1
+ <div class="redis-snippets">
2
+ <h1 class="h1">Snippets</h1>
3
3
 
4
- <%= form_tag '', method: :put, class: "form-redis_snippets" do |f| %>
5
- <fieldset class="form-redis_snippets-inputs">
6
- <ol>
4
+ <%= form_tag "", method: :put, class: "redis-snippets__form" do |f| %>
5
+ <fieldset class="redis-snippets__fieldset">
6
+ <ol class="redis-snippets__list">
7
7
  <% RedisSnippets::Engine.config.redis_snippets[:keys].each do |key| %>
8
- <li class="form-redis_snippets-inputs-text form-redis_snippets-inputs-input form-redis_snippets-inputs-optional">
9
- <%= label_tag key.to_s, key.to_s, class: "form-redis_snippets-label" %>
10
- <%= text_area_tag "snippets[#{key}]", RedisSnippets::Snippets.send(snippet_key(key)), cols: 120, rows: 10 %>
8
+ <li class="redis-snippets__snippet">
9
+ <%= label_tag key.to_s, key.to_s, class: "redis-snippets__snippet-label" %>
10
+ <%= text_area_tag "snippets[#{key}]", SnippetStoreService.send(snippet_key(key)), cols: 120, rows: 10 %>
11
11
  </li>
12
12
  <% end -%>
13
13
  </ol>
14
14
  </fieldset>
15
- <fieldset class="form-redis_snippets-inputs-actions">
16
- <ol>
17
- <li class="form-redis_snippets-inputs-action form-redis_snippets-inputs-button_action">
18
- <%= button_tag 'Submit' %>
19
- </li>
20
- </ol>
21
- </field>
15
+ <fieldset class="redis-snippets__actions">
16
+ <%= button_tag "Submit", class: "redis-snippets__submit" %>
17
+ </fieldset>
22
18
  <% end -%>
23
19
  </div>
data/config/routes.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  RedisSnippets::Engine.routes.draw do
2
- resource :snippets, controller: 'snippets', only: [:show, :update]
2
+ resource :snippets, controller: 'redis_snippets/snippets', only: [:show, :update]
3
3
  end
@@ -1,5 +1,7 @@
1
1
  module RedisSnippets
2
2
  class Engine < ::Rails::Engine
3
- isolate_namespace RedisSnippets
3
+ config.generators do |g|
4
+ g.test_framework :rspec
5
+ end
4
6
  end
5
7
  end
@@ -1,17 +1,22 @@
1
1
  module RedisSnippets
2
2
  class Redis
3
3
  class << self
4
- # Can't do method_missing on get/set as they're defined somewhere by Ruby.
5
4
  def get(key)
6
- RedisSnippets::Engine.config.redis_snippets[:connection].get(key)
5
+ connection.get(key)
7
6
  end
8
7
 
9
8
  def set(key, value)
10
- RedisSnippets::Engine.config.redis_snippets[:connection].set(key, value)
9
+ connection.set(key, value)
11
10
  end
12
11
 
13
- def method_missing(method, *args)
14
- RedisSnippets::Engine.config.redis_snippets[:connection].send(method, *args)
12
+ def del(key)
13
+ connection.del(key)
14
+ end
15
+
16
+ protected
17
+
18
+ def connection
19
+ RedisSnippets::Engine.config.redis_snippets[:connection]
15
20
  end
16
21
  end
17
22
  end
@@ -1,6 +1,6 @@
1
1
  module RedisSnippets
2
- module Help
3
- # If multi_site => true the symbol returned will have the key returned with a prefix.
2
+ module Util
3
+ # If multi_site is true the symbol returned will have the key returned with a prefix.
4
4
  # This prefix is defined in your application using the redis_snippet_site_key method.
5
5
  # redis_snippet_site_key should simply return a unique string per site. For instance
6
6
  # it could be the domain of the site.