rooftop-rails 0.0.1 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b80eb9aa0ca54ecdd1b5e48e97317d57879ecf1f
4
- data.tar.gz: 0b3cc153eec7c9b28f2b6348d8f3a042a1e601e9
3
+ metadata.gz: 0ce7b53b614dba3b91d76917209fdd360b3074ee
4
+ data.tar.gz: 9b3034dca31a3d7011d635b46639e519ebb90a51
5
5
  SHA512:
6
- metadata.gz: 72ee68d6c0a743a63ad16e622cfa9340bb1f3be2c56830fd46ed2648ac91be5d4577c3b17a832d26772e19a3b353d5ee6dab764aa8843f6443b1203bb9f7b2c4
7
- data.tar.gz: 2be3d3a56377202414c237d640497a0c546c1111eda3c9068aaa4584cb0b1f90d7806b0683c7a59a092ddb513b1be5dab8dd5fb5f322432fb9dc1494584e3dc9
6
+ metadata.gz: 7420b709d0dd54f2e485a87240a50e319806df71870d730d022d71529bf4a09407d1674fee1a29c2eb68b8cdea539d9e24c6451848533096f8d68d9985624f8e
7
+ data.tar.gz: dc72a561f64cb5e2ab552771ca5bfe61cba476117d9a39be140090cf44fb29db9b2eac4794d5750c71f12e431e7644f33037f28769a4e09f5d22fcaa4416a8e4
@@ -0,0 +1,65 @@
1
+ module Rooftop
2
+ module Rails
3
+ # A controller mixin which can load a resource from a nested path. Useful mostly for pages.
4
+ # The mixin defines some dynamic instance methods on the controller, and a class method to define the name of the model you want to load.
5
+ module NestedResource
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ attr_reader :resource_name, :resource_class
12
+ # A class method defined on the controller which gives you an easy way to find a resource from a deeply-nested path, and optionally check that the path provided is correct.
13
+ # By adding a call to `nested_rooftop_resource` in your controller class, the following happens:
14
+ # - The resource model you identify has Rooftop::Rails::NestedModel mixed into it
15
+ # - Methods for finding a model object and validating that the path is correct are added
16
+ # For example:
17
+ # class PagesController
18
+ # include Rooftop::Rails::NestedResource
19
+ # nested_rooftop_resource :page
20
+ # before_action :find_and_validate_page, except: :index
21
+ # end
22
+ #
23
+ # Note that the methods on the controller are dynamically named according to the resource name - i.e. find_and_validate_page in this case.
24
+ # You need to set up your routes so that a single param called `nested_path` is passed to this controller for any methods you're calling `find_and_validate_page` on, for example:
25
+ # match "/*nested_path", via: [:get], to: "pages#show"
26
+ # This is a greedy route so you probably want it at the bottom.
27
+ def nested_rooftop_resource(resource)
28
+ @resource_name = resource
29
+ @resource_class = resource.to_s.classify.constantize
30
+ @resource_class.send(:include, Rooftop::Rails::NestedModel)
31
+
32
+ # Set up the dynamically-named find_[resource name]
33
+ define_method "find_#{@resource_name}" do
34
+ respond_to do |format|
35
+ format.html do
36
+ resource = self.class.resource_class.send(:find_by_nested_path, params[:nested_path])
37
+ instance_variable_set("@#{self.class.resource_name}",resource)
38
+ end
39
+ format.all do
40
+ raise ActionController::RoutingError, "Not found: #{request.original_fullpath}"
41
+ end
42
+ end
43
+
44
+ end
45
+ # Set up the dynamically-named validate_[resource name]
46
+ define_method "validate_#{@resource_name}" do
47
+ resource = instance_variable_get("@#{self.class.resource_name}")
48
+ if resource.nested_path != params[:nested_path]
49
+ raise Rooftop::Rails::AncestorMismatch, "The #{self.class.resource_name} you requested has a different path"
50
+ end
51
+ end
52
+ # Set up the dynamically-named find_and_validate_[resource name]
53
+ # (this is a utility method to call the two above)
54
+ define_method "find_and_validate_#{@resource_name}" do
55
+ send(:"find_#{self.class.resource_name}")
56
+ send(:"validate_#{self.class.resource_name}")
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
1
+ module Rooftop
2
+ module Rails
3
+ # A mixin helper to make it easier to deal with content coming out of Rooftop.
4
+ # For example, rendering relative links in the context of your application.
5
+ module ContentHelper
6
+
7
+ # Parse content and replace links from Rooftop with links to your resources.
8
+ # We introspect your routes using Rooftop::Rails::RouteResolver, which also gives you scope for
9
+ # manually overriding something, by setting Rooftop::Rails.configuration.resource_route_mapping.
10
+ # See the readme for more info.
11
+
12
+ # @param content [String] the content you want to parse, e.g. an html field from Rooftop.
13
+ # @return [String] the HTML, parsed to point to your URL structure.
14
+ def parse_links(content)
15
+ _fragment = Nokogiri::HTML.fragment(content, 'UTF-8')
16
+ _fragment.css("a[data-rooftop-link-type]").each do |a|
17
+ # build up the slug path for the resource we're linking to
18
+ if a['data-rooftop-link-ancestor-slugs'] #we have a nested resource, we need to build up the slug path
19
+ path = a['data-rooftop-link-ancestor-slugs'].split(",").push(a['data-rooftop-link-slug'])
20
+ resource_id = path.join("/")
21
+ else
22
+ resource_id = a['data-rooftop-link-slug']
23
+ end
24
+
25
+ a['href'] = Rooftop::Rails::RouteResolver.new(a['data-rooftop-link-type'], resource_id).resolve
26
+ end
27
+ _fragment.to_html
28
+ end
29
+
30
+ def parse_content(content)
31
+ parse_links(content).html_safe
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,52 @@
1
+ module Rooftop
2
+ module Rails
3
+
4
+ # This module adds methods for finding by a nested path of slugs, and generating a
5
+ # nested path of slugs
6
+ module NestedModel
7
+
8
+ def self.included(base)
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ # Get a model from a nested path. Assumes `slug` is the field you'll be finding by.
14
+ # Accepts options for the path delimiter and whether you want to unescape url strings
15
+
16
+ # @param path [String] the path - the last of which will be the thing we find
17
+ # @param opts [Hash] options - path delimiter and unescape
18
+ # @return object [Object] an instance of the class this is mixed into
19
+ def find_by_nested_path(path, opts = {})
20
+ options = {delimiter: '/', unescape: false}
21
+ options.merge!(opts)
22
+ path = CGI::unescape(path) if options[:unescape]
23
+ delimiter = options[:delimiter]
24
+ slug = "#{options[:prefix]}#{path}".gsub(/^\//, '').split(delimiter).last
25
+ entity = where(slug: slug).first
26
+ if entity.nil?
27
+ raise Rooftop::RecordNotFoundError, "Couldn't find #{self} with slug #{slug}"
28
+ else
29
+ return entity
30
+ end
31
+ end
32
+ end
33
+
34
+ # Given a field (and optional delimiter), return a path to the current object.
35
+ # e.g. you'd end up with /path/to/page (where this object is 'page')
36
+ # @param [Symbol] the field to use to create the path
37
+ # @param [String] the delimiter to use. Defaults to "/"
38
+ # @return [String] the path as a string
39
+ def nested_path(opts = {})
40
+ options = {delimiter: "/", prefix: ""}
41
+ options.merge!(opts)
42
+ delimiter = options[:delimiter]
43
+ prefix = options[:prefix].empty? ? "" : "#{options[:prefix]}#{delimiter}"
44
+ path = ([slug] + ancestors.collect(&:slug)).reverse.join(delimiter).gsub(prefix,"")
45
+ return path
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+
data/lib/rooftop/rails.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require 'rooftop'
2
-
3
- require "rooftop/rails/engine"
4
- require "rooftop/rails/development_constraint"
5
- require "rooftop/rails/preview"
2
+ require 'require_all'
3
+ require_rel '.'
6
4
 
7
5
  module Rooftop
8
6
  module Rails
@@ -25,15 +23,24 @@ module Rooftop
25
23
  :authenticate_webhooks,
26
24
  :webhooks_username,
27
25
  :webhooks_password,
28
- :perform_caching,
29
26
  :preview_username,
30
27
  :preview_password,
31
28
  :preview_domain,
32
- :enable_preview_domain
29
+ :enable_preview_domain,
30
+ :perform_caching,
31
+ :cache_store,
32
+ :cache_logger,
33
+ :ssl_options,
34
+ :proxy,
35
+ :resource_route_map
33
36
 
34
37
  def initialize
35
38
  @authenticate_webhooks = true
36
39
  @perform_caching = ::Rails.configuration.action_controller.perform_caching
40
+ @cache_store = ::Rails.cache
41
+ @cache_logger = ::Rails.logger
42
+ @ssl_options = {}
43
+ @resource_route_map = {}
37
44
  end
38
45
  end
39
46
  end
@@ -17,7 +17,12 @@ module Rooftop
17
17
  config.extra_headers = Rooftop::Rails.configuration.extra_headers
18
18
  config.advanced_options = Rooftop::Rails.configuration.advanced_options
19
19
  config.api_path = Rooftop::Rails.configuration.api_path
20
- config.url = Rooftop::Rails.configuration.url || "http://#{config.site_name}.rooftopcms.io"
20
+ config.url = Rooftop::Rails.configuration.url || "https://#{config.site_name}.rooftopcms.io"
21
+ config.perform_caching = Rooftop::Rails.configuration.perform_caching
22
+ config.cache_store = Rooftop::Rails.configuration.cache_store
23
+ config.cache_logger = Rooftop::Rails.configuration.cache_logger
24
+ config.ssl_options = Rooftop::Rails.configuration.ssl_options
25
+ config.proxy = Rooftop::Rails.configuration.proxy
21
26
  end
22
27
  end
23
28
 
@@ -26,6 +31,12 @@ module Rooftop
26
31
  include Rooftop::Rails::Preview
27
32
  end
28
33
  end
34
+
35
+ initializer "add_helpers" do
36
+ ActiveSupport.on_load(:action_view) do
37
+ include Rooftop::Rails::ContentHelper
38
+ end
39
+ end
29
40
  end
30
41
  end
31
42
  end
@@ -0,0 +1,5 @@
1
+ module Rooftop
2
+ module Rails
3
+ class AncestorMismatch < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,34 @@
1
+ module Rooftop
2
+ module Rails
3
+ # A class to generate a proper rails route for Rooftop resources.
4
+ #
5
+ # You can configure a custom route in Rooftop::Rails::Configuration.resource_route_map. If you don't,
6
+ # this class will introspect the Rails routes to try and guess. Otherwise it'll return nothing.
7
+ class RouteResolver
8
+ # Create the route resolver, with a type (post, page, whatever) and an optional ID
9
+ attr_accessor :type, :id
10
+ def initialize(type, id=nil)
11
+ @type = type.to_sym
12
+ @id = id
13
+ end
14
+
15
+ def resolve
16
+ route_config = Rooftop::Rails.configuration.resource_route_map
17
+ resource_key = @id.nil? ? @type.to_s.pluralize.to_sym : @type
18
+ if route_config[resource_key]
19
+ return route_config[resource_key].try(:call,@id)
20
+ else
21
+ begin
22
+ route_info = ::Rails.application.routes.named_routes[resource_key].defaults
23
+ route_info.reverse_merge!(id: @id) unless @id.nil?
24
+ ::Rails.application.routes.url_helpers.url_for(route_info.merge(only_path: true))
25
+ rescue
26
+ nil
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Rooftop
2
2
  module Rails
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rooftop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Error Studio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2015-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: require_all
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rails
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,20 +38,34 @@ dependencies:
24
38
  - - ~>
25
39
  - !ruby/object:Gem::Version
26
40
  version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: rooftop
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
- - - '>='
59
+ - - '='
32
60
  - !ruby/object:Gem::Version
33
- version: '0'
61
+ version: 0.0.5
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
- - - '>='
66
+ - - '='
39
67
  - !ruby/object:Gem::Version
40
- version: '0'
68
+ version: 0.0.5
41
69
  description: This gem provides utility methods and a mountable engine for Rails applications
42
70
  using the Rooftop gem
43
71
  email:
@@ -47,13 +75,18 @@ extensions: []
47
75
  extra_rdoc_files: []
48
76
  files:
49
77
  - Rakefile
78
+ - app/controllers/concerns/rooftop/rails/nested_resource.rb
50
79
  - app/controllers/rooftop_rails/webhooks_controller.rb
51
- - app/helpers/rooftop_rails/webhooks_helper.rb
80
+ - app/helpers/rooftop/rails/content_helper.rb
81
+ - app/helpers/rooftop/webhooks_helper.rb
82
+ - app/models/concerns/rooftop/rails/nested_model.rb
52
83
  - config/routes.rb
53
84
  - lib/rooftop/rails.rb
54
85
  - lib/rooftop/rails/development_constraint.rb
55
86
  - lib/rooftop/rails/engine.rb
87
+ - lib/rooftop/rails/errors.rb
56
88
  - lib/rooftop/rails/preview.rb
89
+ - lib/rooftop/rails/route_resolver.rb
57
90
  - lib/rooftop/rails/version.rb
58
91
  - test/controllers/rooftop_rails/webhooks_controller_test.rb
59
92
  - test/dummy/README.rdoc