rooftop-rails 0.0.1 → 0.0.2

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: 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