locomotive_plugins 1.0.0.beta6 → 1.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -5,6 +5,7 @@
5
5
  * Removed content type scoping (use liquid tags instead)
6
6
  * Removed DBModels (just use Mongoid and LocomotiveCMS will isolate the models)
7
7
  * Added class tracking (used by Locomotive)
8
+ * Added ability to supply a rack app for handling requests
8
9
 
9
10
  ## v0.2.1
10
11
 
data/README.md CHANGED
@@ -279,3 +279,14 @@ comes in to site A which causes a Mongoid Document to be saved to the database,
279
279
  this document will not be accessible to the plugin when a request comes in to
280
280
  site B. Thus plugin database models should be developed in the context of a
281
281
  single site, since each site will have its own database.
282
+
283
+ ### Rack App
284
+
285
+ Plugins can supply a Rack Application to be used for request handling. Do so by
286
+ overriding the `rack_app` class method on the plugin class. The plugin object
287
+ can also build URLs and paths for that Rack App without knowledge of where it
288
+ is mounted. This is important because Locomotive will mount the rack
289
+ application on a path based on the plugin's `plugin_id`. Given a string `path`
290
+ which is a path relative to the root of the rack app,
291
+ `plugin_object.full_path(path)` will give the full absolute path and
292
+ `plugin_object.full_url(path)` will give the full URL.
@@ -13,6 +13,7 @@ module Locomotive
13
13
  include ClassTracker
14
14
  include ConfigUI
15
15
  include Liquid
16
+ include RackAppHelpers
16
17
 
17
18
  # @private
18
19
  #
@@ -21,7 +22,8 @@ module Locomotive
21
22
  #
22
23
  # @param base the plugin class
23
24
  def self.included(base)
24
- self.add_liquid_tag_methods(base)
25
+ self.add_liquid_class_methods(base)
26
+ self.add_rack_app_helper_methods(base)
25
27
 
26
28
  base.class_eval do
27
29
  extend ActiveModel::Callbacks
@@ -74,6 +76,14 @@ module Locomotive
74
76
  def liquid_tags
75
77
  {}
76
78
  end
79
+
80
+ # Override this method to supply a rack app to be used for handling
81
+ # requests. Locomotive CMS will mount this app on a path dependent on the
82
+ # `plugin_id`. See `RackAppHelpers` for some helper methods.
83
+ def rack_app
84
+ nil
85
+ end
86
+
77
87
  end
78
88
 
79
89
  # This variable is set by LocomotiveCMS. It contains the controller which
@@ -0,0 +1,9 @@
1
+
2
+ module Locomotive
3
+ module Plugin
4
+
5
+ # General Locomotive::Plugin exception
6
+ class Error < StandardError; end
7
+
8
+ end
9
+ end
@@ -18,7 +18,7 @@ module Locomotive
18
18
  # Adds methods from LiquidClassMethods module.
19
19
  #
20
20
  # @param base the plugin class to extend LiquidClassMethods
21
- def add_liquid_tag_methods(base)
21
+ def add_liquid_class_methods(base)
22
22
  base.extend(LiquidClassMethods)
23
23
  end
24
24
  end
@@ -0,0 +1,92 @@
1
+
2
+ module Locomotive
3
+ module Plugin
4
+ # This module adds helpers for handling the Rack app supplied by the
5
+ # `rack_app` method.
6
+ module RackAppHelpers
7
+
8
+ # @private
9
+ #
10
+ # Add class methods.
11
+ #
12
+ # @param base the class which includes this module
13
+ def self.included(base)
14
+ base.extend(ClassMethods)
15
+ end
16
+
17
+ # @api internal
18
+ module ClassMethods
19
+ # Adds methods from RackAppHelpersClassMethods module.
20
+ #
21
+ # @param base the plugin class to extend LiquidClassMethods
22
+ def add_rack_app_helper_methods(base)
23
+ base.extend(RackAppHelpersClassMethods)
24
+ end
25
+ end
26
+
27
+ # This module adds class methods for managing the mount point for the
28
+ # Rack App. The mount point must be set in order to properly generate
29
+ # paths and URLs.
30
+ module RackAppHelpersClassMethods
31
+ # Set the full URL mountpoint for the Rack app. This will be set by
32
+ # Locomotive CMS. The URL must be an HTTP or HTTPS url with no query
33
+ # parameters or hash fragments.
34
+ #
35
+ # @param url [String] the full URL that the Rack app is mounted on
36
+ def set_mountpoint(url)
37
+ error = lambda do |msg|
38
+ raise Error, "Invalid mountpoint: #{msg}"
39
+ end
40
+
41
+ uri = URI(url)
42
+ unless uri.scheme =~ /^https?$/
43
+ error.call('only http or https allowed')
44
+ end
45
+ if uri.fragment
46
+ error.call('no hash fragment allowed')
47
+ end
48
+ if uri.query
49
+ error.call('no query string allowed')
50
+ end
51
+
52
+ @mountpoint = uri
53
+ end
54
+
55
+ # Get the mountpoint for this plugin class's Rack app.
56
+ #
57
+ # @return the mountpoint
58
+ def mountpoint
59
+ @mountpoint
60
+ end
61
+ end
62
+
63
+ # Generate the full absolute path for the given path based on the
64
+ # mountpoint of this plugin's rack app.
65
+ #
66
+ # @param path [String] the path relative to the mountpoint of the rack
67
+ # app
68
+ # @return the absolute path
69
+ def full_path(path)
70
+ [ mountpoint.path.sub(%r{/+$}, ''), path.sub(%r{^/+}, '') ].join('/')
71
+ end
72
+
73
+ # Generate the full URL for the given path based on the mountpoint of
74
+ # this plugin's rack app.
75
+ #
76
+ # @param path [String] the path relative to the mountpoint of the rack
77
+ # app
78
+ # @return the URL
79
+ def full_url(path)
80
+ [ mountpoint.to_s.sub(%r{/+$}, ''), path.sub(%r{^/+}, '') ].join('/')
81
+ end
82
+
83
+ # Get the mountpoint for this plugin's Rack app.
84
+ #
85
+ # @return the mountpoint
86
+ def mountpoint
87
+ self.class.mountpoint
88
+ end
89
+
90
+ end
91
+ end
92
+ end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LocomotivePlugins
2
- VERSION = '1.0.0.beta6'
2
+ VERSION = '1.0.0.beta7'
3
3
  end
@@ -0,0 +1,66 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ module Locomotive
5
+ module Plugin
6
+ describe RackAppHelpers do
7
+
8
+ before(:all) do
9
+ PluginWithRackApp.set_mountpoint('http://www.example.com/my/path')
10
+ end
11
+
12
+ before(:each) do
13
+ @config = {}
14
+ @plugin = PluginWithRackApp.new(@config)
15
+ end
16
+
17
+ it 'should supply an absolute path based on where it is mounted' do
18
+ @plugin.full_path('/plugin/path').should == '/my/path/plugin/path'
19
+ @plugin.full_path('another//path').should == '/my/path/another//path'
20
+ end
21
+
22
+ it 'should supply a full URL based on where it is mounted' do
23
+ @plugin.full_url('/plugin/path').should ==
24
+ 'http://www.example.com/my/path/plugin/path'
25
+ @plugin.full_url('another//path').should ==
26
+ 'http://www.example.com/my/path/another//path'
27
+ end
28
+
29
+ it 'should only allow URLs with proper format' do
30
+ old_mountpoint = PluginWithRackApp.mountpoint
31
+
32
+ bad_mountpoints = [
33
+ 'my/path',
34
+ 'my.server.com/my/path',
35
+ 'ftp://my.server.com',
36
+ 'http://my.server.com/my/path?q=value',
37
+ 'http://my.server.com/my/path#fragment',
38
+ 'https://my.server.com/my/path?q=value',
39
+ 'https://my.server.com/my/path#fragment'
40
+ ]
41
+
42
+ good_mountpoints = [
43
+ 'http://my.server.com/my/path',
44
+ 'http://my.server.com:3000/my/path',
45
+ 'https://my.server.com/my/path',
46
+ 'https://my.server.com:3000/my/path'
47
+ ]
48
+
49
+ bad_mountpoints.each do |mountpoint|
50
+ lambda do
51
+ PluginWithRackApp.set_mountpoint(mountpoint)
52
+ end.should raise_exception(Locomotive::Plugin::Error)
53
+ PluginWithRackApp.mountpoint.should == old_mountpoint
54
+ end
55
+
56
+ good_mountpoints.each do |mountpoint|
57
+ lambda do
58
+ PluginWithRackApp.set_mountpoint(mountpoint)
59
+ end.should_not raise_exception
60
+ PluginWithRackApp.mountpoint.to_s.should == mountpoint
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -47,5 +47,10 @@ module Locomotive
47
47
  }
48
48
  end
49
49
 
50
+ it 'should optionally supply a Rack application' do
51
+ UselessPlugin.rack_app.should be_nil
52
+ PluginWithRackApp.rack_app.should_not be_nil
53
+ end
54
+
50
55
  end
51
56
  end
@@ -0,0 +1,10 @@
1
+
2
+ class PluginWithRackApp
3
+ include Locomotive::Plugin
4
+
5
+ def self.rack_app
6
+ Proc.new do
7
+ [200, {'Content-Type' => 'text/html'}, []]
8
+ end
9
+ end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locomotive_plugins
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta6
4
+ version: 1.0.0.beta7
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-17 00:00:00.000000000 Z
12
+ date: 2013-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: locomotive_liquid
@@ -117,10 +117,12 @@ files:
117
117
  - Rakefile
118
118
  - lib/locomotive/plugin/liquid.rb
119
119
  - lib/locomotive/plugin/class_tracker.rb
120
+ - lib/locomotive/plugin/exceptions.rb
120
121
  - lib/locomotive/plugin/liquid/prefixed_filter_module.rb
121
122
  - lib/locomotive/plugin/liquid/drop_extension.rb
122
123
  - lib/locomotive/plugin/liquid/tag_subclass_methods.rb
123
124
  - lib/locomotive/plugin/liquid/context_helpers.rb
125
+ - lib/locomotive/plugin/rack_app_helpers.rb
124
126
  - lib/locomotive/plugin/config_ui.rb
125
127
  - lib/locomotive/plugin.rb
126
128
  - lib/version.rb
@@ -133,10 +135,12 @@ files:
133
135
  - spec/support/plugins/plugin_with_filter.rb
134
136
  - spec/support/plugins/plugin_with_many_filter_modules.rb
135
137
  - spec/support/plugins/my_plugin.rb
138
+ - spec/support/plugins/plugin_with_rack_app.rb
136
139
  - spec/support/factories.rb
137
140
  - spec/fixtures/config_template.haml
138
141
  - spec/fixtures/config_template.html
139
142
  - spec/lib/locomotive/plugin/class_tracker_spec.rb
143
+ - spec/lib/locomotive/plugin/rack_app_helpers_spec.rb
140
144
  - spec/lib/locomotive/plugin/liquid/context_helpers_spec.rb
141
145
  - spec/lib/locomotive/plugin/liquid_spec.rb
142
146
  - spec/lib/locomotive/plugin/config_ui_spec.rb