contentful_rails 0.0.9 → 0.2.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 +4 -4
- data/app/controllers/contentful_rails/webhooks_controller.rb +5 -8
- data/app/helpers/contentful_rails/markdown_helper.rb +1 -0
- data/lib/contentful_rails.rb +18 -2
- data/lib/contentful_rails/caching/timestamps.rb +57 -0
- data/lib/contentful_rails/engine.rb +32 -10
- data/lib/contentful_rails/markdown_renderer.rb +1 -0
- data/lib/contentful_rails/nested_resource.rb +17 -8
- data/lib/contentful_rails/preview.rb +53 -0
- data/lib/contentful_rails/sluggable.rb +7 -9
- data/lib/contentful_rails/version.rb +1 -1
- metadata +6 -5
- data/lib/contentful_rails/cached_timestamps.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 020e69292f25bc884fa90c49bd9a1a8d7182e249
|
4
|
+
data.tar.gz: 45d6590bc12f515276302ac8400b3d3b4c4b80fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2aedf217e1096fcda85385e891706a39be4606bb5696ba3683af33aad0fb414b0f859316ad648fcc01d3dca246e1dac4efdf6847dfd2bc9c1daa644fc31e9955
|
7
|
+
data.tar.gz: dd9de11844ecb8075a8f3a995d272e9ab6678ba9cb1853f44556cb3a7a8ad24716dfc004131935a410efbbfefda945561109a93b18932d286c4f93d905d0f706
|
@@ -16,14 +16,11 @@ class ContentfulRails::WebhooksController < ActionController::Base
|
|
16
16
|
# We can then just use normal Rails russian doll caching without expensive API calls.
|
17
17
|
request.format = :json
|
18
18
|
update_type = request.headers['HTTP_X_CONTENTFUL_TOPIC']
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
if update_type =~ %r(Entry)
|
25
|
-
Rails.cache.delete(cache_key)
|
26
|
-
end
|
19
|
+
|
20
|
+
# All we do here is publish an ActiveSupport::Notification, which is subscribed to
|
21
|
+
# elsewhere. In this gem are subscription options for timestamp or object caching,
|
22
|
+
# implement your own and subscribe in an initializer.
|
23
|
+
ActiveSupport::Notifications.instrument("Contentful.#{update_type}", params)
|
27
24
|
|
28
25
|
#must return an ok
|
29
26
|
render nothing: true
|
@@ -6,6 +6,7 @@ module ContentfulRails
|
|
6
6
|
# @param renderer_options [Hash] of options from https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch
|
7
7
|
# @param markdown_options [Hash] of options from https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
|
8
8
|
def parse_markdown(markdown_string, renderer_options: {}, markdown_options: {}, image_options: {})
|
9
|
+
markdown_string ||= ""
|
9
10
|
markdown_opts = {
|
10
11
|
no_intr_emphasis: true,
|
11
12
|
tables: true,
|
data/lib/contentful_rails.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "contentful_rails/engine"
|
2
2
|
require "contentful_rails/development_constraint"
|
3
|
-
require
|
3
|
+
require 'contentful_rails/caching/timestamps'
|
4
4
|
require "contentful_rails/markdown_renderer"
|
5
5
|
require "contentful_rails/nested_resource"
|
6
6
|
require "contentful_rails/sluggable"
|
7
|
+
require "contentful_rails/preview"
|
7
8
|
require 'redcarpet'
|
8
9
|
|
9
10
|
module ContentfulRails
|
@@ -17,10 +18,25 @@ module ContentfulRails
|
|
17
18
|
end
|
18
19
|
|
19
20
|
class Configuration
|
20
|
-
attr_accessor :authenticate_webhooks,
|
21
|
+
attr_accessor :authenticate_webhooks,
|
22
|
+
:webhooks_username,
|
23
|
+
:webhooks_password,
|
24
|
+
:slug_delimiter,
|
25
|
+
:perform_caching,
|
26
|
+
:access_token,
|
27
|
+
:preview_access_token,
|
28
|
+
:space,
|
29
|
+
:contentful_options,
|
30
|
+
:preview_username,
|
31
|
+
:preview_password,
|
32
|
+
:preview_domain,
|
33
|
+
:enable_preview_domain
|
21
34
|
|
22
35
|
def initialize
|
23
36
|
@authenticate = true
|
37
|
+
@slug_delimiter = "-"
|
38
|
+
@perform_caching = Rails.configuration.action_controller.perform_caching
|
39
|
+
@contentful_options = {}
|
24
40
|
end
|
25
41
|
end
|
26
42
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ContentfulRails
|
2
|
+
module Caching
|
3
|
+
# A module to prepend into ContentfulModel::Base which will allow the model instance
|
4
|
+
# to check the cache for its timestamp before making an expensive API call.
|
5
|
+
# Also includes a module method to remove an existing timestamp.
|
6
|
+
module Timestamps
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
base.class_eval do
|
10
|
+
alias_method_chain :updated_at, :caching
|
11
|
+
alias_method_chain :cache_key, :preview
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# Clear an existing timestamp from the cache; called by the subscriber to the Entry notifications
|
17
|
+
# from the WebhooksController.
|
18
|
+
def clear_cache_for(item_id)
|
19
|
+
cache_key = timestamp_cache_key(item_id)
|
20
|
+
|
21
|
+
Rails.cache.delete(cache_key)
|
22
|
+
end
|
23
|
+
|
24
|
+
def timestamp_cache_key(item_id)
|
25
|
+
"contentful_timestamp/#{self.content_type_id}/#{item_id}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# A replacement method for updated_at(), called when this module is included in ContentfulModel::Base
|
31
|
+
def updated_at_with_caching
|
32
|
+
if ContentfulRails.configuration.perform_caching && !ContentfulModel.use_preview_api
|
33
|
+
Rails.cache.fetch(self.timestamp_cache_key) do
|
34
|
+
updated_at_without_caching
|
35
|
+
end
|
36
|
+
else
|
37
|
+
updated_at_without_caching
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def timestamp_cache_key
|
42
|
+
self.class.timestamp_cache_key(id)
|
43
|
+
end
|
44
|
+
|
45
|
+
def cache_key_with_preview
|
46
|
+
if ContentfulModel.use_preview_api
|
47
|
+
"preview/#{cache_key_without_preview}"
|
48
|
+
else
|
49
|
+
cache_key_without_preview
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -3,10 +3,25 @@ module ContentfulRails
|
|
3
3
|
|
4
4
|
isolate_namespace ContentfulRails
|
5
5
|
|
6
|
+
config.before_initialize do
|
7
|
+
if ContentfulRails.configuration.nil?
|
8
|
+
ContentfulRails.configure {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer "configure_contentful", before: :add_entry_mappings do
|
13
|
+
ContentfulModel.configure do |config|
|
14
|
+
config.access_token = ContentfulRails.configuration.access_token
|
15
|
+
config.preview_access_token = ContentfulRails.configuration.preview_access_token
|
16
|
+
config.space = ContentfulRails.configuration.space
|
17
|
+
config.options = ContentfulRails.configuration.contentful_options
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
6
21
|
#Iterate through all models which inherit from ContentfulModel::Base
|
7
22
|
#and add an entry mapping for them, so calls to the Contentful API return
|
8
|
-
#the appropriate classes
|
9
|
-
initializer "
|
23
|
+
#the appropriate classes
|
24
|
+
initializer "add_entry_mappings", after: :configure_contentful do
|
10
25
|
if defined?(ContentfulModel)
|
11
26
|
Rails.application.eager_load!
|
12
27
|
ContentfulModel::Base.descendents.each do |klass|
|
@@ -15,22 +30,29 @@ module ContentfulRails
|
|
15
30
|
end
|
16
31
|
end
|
17
32
|
|
33
|
+
initializer "subscribe_to_webhook_events", after: :add_entry_mappings do
|
34
|
+
ActiveSupport::Notifications.subscribe(/Contentful.*Entry.*/) do |name, start, finish, id, payload|
|
35
|
+
content_type_id = payload[:sys][:contentType][:sys][:id]
|
36
|
+
klass = ContentfulModel.configuration.entry_mapping[content_type_id]
|
37
|
+
klass.send(:clear_cache_for, payload[:sys][:id])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
18
41
|
initializer "add_contentful_mime_type" do
|
19
42
|
Mime::Type.register "application/json", :json, ["application/vnd.contentful.management.v1+json"]
|
20
43
|
end
|
21
44
|
|
22
|
-
|
23
|
-
|
24
|
-
|
45
|
+
initializer "add_preview_support" do
|
46
|
+
ActiveSupport.on_load(:action_controller) do
|
47
|
+
include ContentfulRails::Preview
|
25
48
|
end
|
26
49
|
end
|
27
50
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if ContentfulRails.configuration.nil?
|
32
|
-
ContentfulRails.configure {}
|
51
|
+
config.to_prepare do
|
52
|
+
if defined?(::ContentfulModel)
|
53
|
+
ContentfulModel::Base.send(:include, ContentfulRails::Caching::Timestamps)
|
33
54
|
end
|
34
55
|
end
|
56
|
+
|
35
57
|
end
|
36
58
|
end
|
@@ -5,6 +5,7 @@ require 'redcarpet'
|
|
5
5
|
# You can subclass this in your application, to add or manipulate specific markup to elements in the markdown.
|
6
6
|
class ContentfulRails::MarkdownRenderer < Redcarpet::Render::HTML
|
7
7
|
include ActionView::Helpers::TagHelper
|
8
|
+
include ActionView::Context
|
8
9
|
def initialize(opts)
|
9
10
|
@options = opts
|
10
11
|
@image_parameters = {
|
@@ -11,11 +11,15 @@ module ContentfulRails
|
|
11
11
|
# e.g. /grandparent/parent/child
|
12
12
|
# @param [Symbol] the field to search by - for example, :slug
|
13
13
|
# @param [String] the path as a forward-slash separated string
|
14
|
-
def get_nested_from_path_by(field, path, opts)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def get_nested_from_path_by(field, path, opts = {})
|
15
|
+
options = {delimiter: '/', unescape: false, prefix: ""}
|
16
|
+
options.merge!(opts)
|
17
|
+
|
18
|
+
path = CGI::unescape(path) if options[:unescape]
|
19
|
+
delimiter = options[:delimiter]
|
20
|
+
prefix = options[:prefix].empty? ? "" : "#{delimiter}#{options[:prefix]}#{delimiter}"
|
21
|
+
|
22
|
+
root, *children = "#{prefix}#{path}".gsub(/^\//, '').split(delimiter)
|
19
23
|
|
20
24
|
if field.to_sym == :id
|
21
25
|
#we need to call find() to get by ID
|
@@ -62,8 +66,13 @@ module ContentfulRails
|
|
62
66
|
# @param [Symbol] the field to use to create the path
|
63
67
|
# @param [String] the delimiter to use. Defaults to "/"
|
64
68
|
# @return [String] the path as a string
|
65
|
-
def nested_path_by(field,
|
66
|
-
|
69
|
+
def nested_path_by(field, opts = {})
|
70
|
+
options = {delimiter: "/", prefix: ""}
|
71
|
+
options.merge!(opts)
|
72
|
+
delimiter = options[:delimiter]
|
73
|
+
prefix = options[:prefix].empty? ? "" : "#{options[:prefix]}#{delimiter}"
|
74
|
+
path = ([self] + ancestors).reverse.collect {|a| a.send(field)}.join(delimiter).gsub(prefix,"")
|
75
|
+
return delimiter + path
|
67
76
|
end
|
68
77
|
end
|
69
|
-
end
|
78
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ContentfulRails
|
2
|
+
module Preview
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_action :check_preview_domain
|
7
|
+
after_action :remove_preview_cache
|
8
|
+
helper_method :preview?
|
9
|
+
end
|
10
|
+
# Check whether the subdomain being presented is the preview domain.
|
11
|
+
# If so, set ContentfulModel to use the preview API, and request a username / password
|
12
|
+
def check_preview_domain
|
13
|
+
# If enable_preview_domain is not enabled, explicitly set use_preview_api false and return
|
14
|
+
unless ContentfulRails.configuration.enable_preview_domain
|
15
|
+
ContentfulModel.use_preview_api = false
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
#check subdomain matches the configured one - we assume it's first sub.domain.in.the.array
|
20
|
+
if request.subdomains.first == ContentfulRails.configuration.preview_domain
|
21
|
+
authenticated = authenticate_with_http_basic do |u,p|
|
22
|
+
u == ContentfulRails.configuration.preview_username
|
23
|
+
p == ContentfulRails.configuration.preview_password
|
24
|
+
end
|
25
|
+
# If user is authenticated, we're good to switch to the preview api
|
26
|
+
if authenticated
|
27
|
+
ContentfulModel.use_preview_api = true
|
28
|
+
else
|
29
|
+
#otherwise ask for user / pass
|
30
|
+
request_http_basic_authentication
|
31
|
+
end
|
32
|
+
else
|
33
|
+
#if the subdomain doesn't match the configured one, explicitly set to false
|
34
|
+
ContentfulModel.use_preview_api = false
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# If we're in preview mode, we need to remove the preview view caches which were created.
|
41
|
+
# this is a bit of a hack but it's probably not feasible to turn off caching in preview mode.
|
42
|
+
def remove_preview_cache
|
43
|
+
# in preview mode, we alias_method_chain the cache_key method on ContentfulModel::Base to append 'preview/'
|
44
|
+
# to the front of the key.
|
45
|
+
return unless request.subdomain == ContentfulRails.configuration.preview_domain
|
46
|
+
expire_fragment(%r{.*/preview/.*})
|
47
|
+
end
|
48
|
+
|
49
|
+
def preview?
|
50
|
+
ContentfulModel.use_preview_api == true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
module ContentfulRails
|
2
2
|
module Sluggable
|
3
|
+
extend ActiveSupport::Concern
|
3
4
|
# A quick mixin to slugify a field other than 'slug'
|
4
5
|
# NOTE that if you include sluggable (and define a slug field) in a class which responds to
|
5
6
|
# slug() than you'll get a stack level too deep error.
|
6
|
-
module Sluggable
|
7
|
-
extend ActiveSupport::Concern
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
class_methods do
|
9
|
+
attr_accessor :slug_field
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
def slug
|
13
|
+
if self.class.slug_field.present?
|
14
|
+
self.send(self.class.slug_field).parameterize(ContentfulRails.configuration.slug_delimiter)
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contentful_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Error Creative Studio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: contentful_model
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.
|
19
|
+
version: 0.1.6
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.
|
26
|
+
version: 0.1.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,11 +65,12 @@ files:
|
|
65
65
|
- app/helpers/contentful_rails/markdown_helper.rb
|
66
66
|
- config/routes.rb
|
67
67
|
- lib/contentful_rails.rb
|
68
|
-
- lib/contentful_rails/
|
68
|
+
- lib/contentful_rails/caching/timestamps.rb
|
69
69
|
- lib/contentful_rails/development_constraint.rb
|
70
70
|
- lib/contentful_rails/engine.rb
|
71
71
|
- lib/contentful_rails/markdown_renderer.rb
|
72
72
|
- lib/contentful_rails/nested_resource.rb
|
73
|
+
- lib/contentful_rails/preview.rb
|
73
74
|
- lib/contentful_rails/sluggable.rb
|
74
75
|
- lib/contentful_rails/version.rb
|
75
76
|
- lib/tasks/contentful_rails_tasks.rake
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module ContentfulRails
|
2
|
-
#A module to prepend into ContentfulModel::Base which will allow the model instance
|
3
|
-
#to check the cache for its timestamp before making an expensive API call
|
4
|
-
module CachedTimestamps
|
5
|
-
def self.included(base)
|
6
|
-
base.class_eval do
|
7
|
-
alias_method_chain :updated_at, :caching
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def updated_at_with_caching
|
12
|
-
if Rails.configuration.action_controller.perform_caching
|
13
|
-
Rails.cache.fetch(self.timestamp_cache_key) do
|
14
|
-
updated_at_without_caching
|
15
|
-
end
|
16
|
-
else
|
17
|
-
updated_at_without_caching
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def timestamp_cache_key
|
22
|
-
"contentful_timestamp/#{self.class.content_type_id}/#{self.id}"
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|