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.
- checksums.yaml +5 -5
- data/.gitignore +4 -2
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/Gemfile +12 -0
- data/README.md +84 -18
- data/Rakefile +5 -0
- data/app/controllers/redis_snippets/snippets_controller.rb +5 -6
- data/app/helpers/redis_snippets/snippets_helper.rb +5 -23
- data/app/presenters/snippet_presenter.rb +67 -0
- data/app/{models/redis_snippets/snippets.rb → services/snippet_store_service.rb} +9 -1
- data/app/views/redis_snippets/snippets/show.html.erb +11 -15
- data/config/routes.rb +1 -1
- data/lib/redis_snippets/engine.rb +3 -1
- data/lib/redis_snippets/redis.rb +10 -5
- data/lib/redis_snippets/{help.rb → util.rb} +2 -2
- data/lib/redis_snippets/version.rb +1 -1
- data/lib/redis_snippets.rb +4 -2
- data/redis_snippets.gemspec +5 -4
- data/spec/app/helpers/redis_snippets/snippets_helper_spec.rb +38 -0
- data/spec/app/presenters/snippet_presenter_spec.rb +53 -0
- data/spec/app/presenters/snippet_presenter_transform_spec.rb +45 -0
- data/spec/app/services/snippet_store_service_spec.rb +44 -0
- data/spec/dummy/.ruby-version +1 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config/application.rb +29 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +62 -0
- data/spec/dummy/config/environments/test.rb +48 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/tmp/.keep +0 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/rails_helper.rb +54 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/simplecov_setup.rb +5 -0
- metadata +105 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1157b175b0ce0c3c72be376383f9da2d522999f69304c093cd3ddbc22eb0d25d
|
4
|
+
data.tar.gz: 7673c2ffe8fd7b0134847e1de912dd94aadf900a267c937625e3ace993f106ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc847d478f9c40aef9fe2ecb067eee24c700d23b1053bcb09280db46c5025b09a94e6363ecdb2f0d70e567a606b75cb53d0771e16844b3a934b6eb815c4bb44f
|
7
|
+
data.tar.gz: fbfc1e84fc0c9794221880574abde61e7d3e2c11720c0c92062be5592c0f15d599f428b556abe777156fc2662790b4386c60cd553720d9567a3664337761602d
|
data/.gitignore
CHANGED
data/.rspec
ADDED
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
data/README.md
CHANGED
@@ -1,20 +1,48 @@
|
|
1
1
|
# Redis Snippets
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/redis_snippets)
|
4
|
+
[](https://travis-ci.org/wulffeld/redis_snippets)
|
5
|
+
[](https://codeclimate.com/github/wulffeld/redis_snippets)
|
6
|
+
[](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
|
-
##
|
32
|
+
## Usage
|
8
33
|
|
9
|
-
It's a Rails engine so add redis-snippets to your Gemfile and put this in an
|
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
|
-
|
13
|
-
:
|
14
|
-
:
|
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
|
-
[
|
59
|
+
[section]
|
32
60
|
```
|
33
61
|
|
34
|
-
The snippet helper will randomly select the snippet. This is convenient for ad
|
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
|
67
|
+
If you're using one app to serve multiple sites a little more configuration is
|
68
|
+
necessary.
|
39
69
|
|
40
70
|
``` ruby
|
41
|
-
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
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,7 +1,7 @@
|
|
1
1
|
class RedisSnippets::SnippetsController < ApplicationController
|
2
|
-
include RedisSnippets::
|
3
|
-
|
4
|
-
|
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
|
-
|
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::
|
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?(
|
11
|
-
!
|
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
|
27
|
-
|
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
|
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="
|
2
|
-
<h1>Snippets</h1>
|
1
|
+
<div class="redis-snippets">
|
2
|
+
<h1 class="h1">Snippets</h1>
|
3
3
|
|
4
|
-
<%= form_tag
|
5
|
-
<fieldset class="
|
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="
|
9
|
-
<%= label_tag key.to_s, key.to_s, class: "
|
10
|
-
<%= text_area_tag "snippets[#{key}]",
|
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="
|
16
|
-
|
17
|
-
|
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
data/lib/redis_snippets/redis.rb
CHANGED
@@ -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
|
-
|
5
|
+
connection.get(key)
|
7
6
|
end
|
8
7
|
|
9
8
|
def set(key, value)
|
10
|
-
|
9
|
+
connection.set(key, value)
|
11
10
|
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
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
|
3
|
-
# If multi_site
|
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.
|