xhive 1.4.0.pre → 1.5.0.pre
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.
data/README.md
CHANGED
|
@@ -268,6 +268,26 @@ end
|
|
|
268
268
|
|
|
269
269
|
Using this feature you can let the designers implement the HTML/CSS to display the posts in your site without your intervention.
|
|
270
270
|
|
|
271
|
+
## Policy based mapping
|
|
272
|
+
|
|
273
|
+
If you need more customization in the page mapping process, you can pass a policy class name as the last attribute.
|
|
274
|
+
|
|
275
|
+
```ruby
|
|
276
|
+
class MyPolicyClass
|
|
277
|
+
def call(opts={})
|
|
278
|
+
opts[:user].country == 'US' && opts[:user].age > 18
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
mapper = Xhive::Mapper.map_resource(site, posts_page, 'posts', 'index', post.id, 'MyPolicyClass')
|
|
283
|
+
|
|
284
|
+
# It will only use the page if the user is an adult from the US
|
|
285
|
+
render_page_with @post.id, :post => @post, :user => @user
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Note: the mailer instance variables will be passed along to the policy class. This allows you to customize the email templates
|
|
289
|
+
depending on the user properties. See below for ActionMailer integration.
|
|
290
|
+
|
|
271
291
|
## ActionMailer integration
|
|
272
292
|
|
|
273
293
|
Using xhive you can extend the CMS capabilities to your system generated emails.
|
|
@@ -316,6 +336,9 @@ mapper.page = email_for_spanish_users
|
|
|
316
336
|
mapper.save
|
|
317
337
|
```
|
|
318
338
|
|
|
339
|
+
Note: the page title will be used as the email subject. You can also make use of the instance variables
|
|
340
|
+
inside the page title as is treated as a Liquid template string.
|
|
341
|
+
|
|
319
342
|
### Inline stylesheets for your emails
|
|
320
343
|
|
|
321
344
|
If you add the inline widget to your cell routes you can use inline stylesheets within your email pages:
|
|
@@ -346,14 +369,17 @@ Then you can add your inline page into your email page using the corresponding t
|
|
|
346
369
|
|
|
347
370
|
`{% inline_page id:email_header %}`
|
|
348
371
|
|
|
349
|
-
TODO
|
|
350
|
-
====
|
|
372
|
+
## TODO
|
|
351
373
|
|
|
352
374
|
* Remove as many dependencies as possible
|
|
353
375
|
* Improve test coverage
|
|
354
376
|
|
|
355
|
-
Disclaimer
|
|
356
|
-
|
|
377
|
+
## Disclaimer
|
|
378
|
+
|
|
357
379
|
This is a work in progress and still a proof of concept. Use at your own risk.
|
|
358
380
|
|
|
359
381
|
Please let me know of any problems, ideas, improvements, etc.
|
|
382
|
+
|
|
383
|
+
## Special Thanks
|
|
384
|
+
|
|
385
|
+
* Thanks to [Daniel Cadenas](https://github.com/dcadenas) for the Policy class inspiration.
|
|
@@ -17,7 +17,7 @@ module Xhive
|
|
|
17
17
|
# Returns: the rendered page.
|
|
18
18
|
#
|
|
19
19
|
def render_page_with(key = nil, options={}, &block)
|
|
20
|
-
page = Xhive::Mapper.page_for(current_site, controller_path, action_name, key)
|
|
20
|
+
page = Xhive::Mapper.page_for(current_site, controller_path, action_name, key, options)
|
|
21
21
|
if page.present?
|
|
22
22
|
render :inline => page.present_content(options), :layout => true
|
|
23
23
|
else
|
data/app/models/xhive/mapper.rb
CHANGED
|
@@ -2,7 +2,7 @@ module Xhive
|
|
|
2
2
|
# Maps resources to pages.
|
|
3
3
|
#
|
|
4
4
|
class Mapper < ActiveRecord::Base
|
|
5
|
-
attr_accessible :action, :page_id, :site_id, :resource, :key
|
|
5
|
+
attr_accessible :action, :page_id, :site_id, :resource, :key, :policy
|
|
6
6
|
|
|
7
7
|
belongs_to :site
|
|
8
8
|
belongs_to :page
|
|
@@ -18,11 +18,12 @@ module Xhive
|
|
|
18
18
|
# resource - The String containing the resource name filter.
|
|
19
19
|
# action - The String containing the action name filter.
|
|
20
20
|
# key - The String containing the key filter.
|
|
21
|
+
# opts - The Hash containing extra values for policy-based filters.
|
|
21
22
|
#
|
|
22
23
|
# Returns: the mapped page or nil if not found.
|
|
23
24
|
#
|
|
24
|
-
def self.page_for(site, resource, action, key = nil)
|
|
25
|
-
mapper = find_map(site, resource, action, key)
|
|
25
|
+
def self.page_for(site, resource, action, key = nil, opts = {})
|
|
26
|
+
mapper = find_map(site, resource, action, key, opts)
|
|
26
27
|
page = mapper.try(:page)
|
|
27
28
|
end
|
|
28
29
|
|
|
@@ -33,13 +34,17 @@ module Xhive
|
|
|
33
34
|
# resource - The String containing the associated resource name.
|
|
34
35
|
# action - The String containing the associated action name.
|
|
35
36
|
# key - The String containing the associated key.
|
|
37
|
+
# policy - The String containing the policy class.
|
|
36
38
|
#
|
|
37
39
|
# Returns: true if created. False otherwise.
|
|
38
40
|
#
|
|
39
|
-
def self.map_resource(site, page, resource, action, key = nil)
|
|
40
|
-
|
|
41
|
+
def self.map_resource(site, page, resource, action, key = nil, policy = nil)
|
|
42
|
+
check_policy_class(policy) if policy.present?
|
|
43
|
+
|
|
44
|
+
mapper = find_exact_map(site, resource, action, key, policy)
|
|
41
45
|
mapper = new(:site_id => site.id, :resource => resource,
|
|
42
|
-
:action => action, :
|
|
46
|
+
:action => action, :policy => policy,
|
|
47
|
+
:key => key.present? ? key : nil) unless mapper.present?
|
|
43
48
|
mapper.page = page
|
|
44
49
|
mapper.save
|
|
45
50
|
end
|
|
@@ -55,6 +60,16 @@ module Xhive
|
|
|
55
60
|
where(:site_id => site.id).where(:resource => resource)
|
|
56
61
|
end
|
|
57
62
|
|
|
63
|
+
class InvalidPolicyError < StandardError
|
|
64
|
+
def initialize(name)
|
|
65
|
+
@name = name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def message
|
|
69
|
+
"#{@name} must implement a ::call method"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
58
73
|
private
|
|
59
74
|
|
|
60
75
|
# Private: looks for a mapper object.
|
|
@@ -63,15 +78,75 @@ module Xhive
|
|
|
63
78
|
# resource - The String containing the resource name filter.
|
|
64
79
|
# action - The String containing the action name filter.
|
|
65
80
|
# key - The String containing the key filter.
|
|
81
|
+
# opts - The Hash containing extra values for policy-based filters.
|
|
82
|
+
#
|
|
83
|
+
# Returns:
|
|
84
|
+
#
|
|
85
|
+
# - The mapper object if it finds a key.
|
|
86
|
+
# - The default mapper if it does not find a key.
|
|
87
|
+
# - Nil if there is no default mapper.
|
|
88
|
+
#
|
|
89
|
+
def self.find_map(site, resource, action, key, opts)
|
|
90
|
+
# Create filtering scopes
|
|
91
|
+
scope = where(:site_id => site.id)
|
|
92
|
+
scope = scope.where(:resource => resource)
|
|
93
|
+
scope = scope.where(:action => action)
|
|
94
|
+
|
|
95
|
+
# Fetch mappers
|
|
96
|
+
mappers = scope.where(:key => key.present? ? key : nil)
|
|
97
|
+
mappers = scope.where(:key => nil) if mappers.empty?
|
|
98
|
+
|
|
99
|
+
# Check policies and select the first that passes
|
|
100
|
+
select_by_policy(mappers, opts)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Private: looks for an exact mapper object.
|
|
104
|
+
#
|
|
105
|
+
# site - The Site to look into.
|
|
106
|
+
# resource - The String containing the resource name filter.
|
|
107
|
+
# action - The String containing the action name filter.
|
|
108
|
+
# key - The String containing the key filter.
|
|
109
|
+
# policy - The String containing the policy class.
|
|
66
110
|
#
|
|
67
111
|
# Returns: the mapper object or nil if not found.
|
|
68
112
|
#
|
|
69
|
-
def self.
|
|
113
|
+
def self.find_exact_map(site, resource, action, key, policy)
|
|
70
114
|
mapper = where(:site_id => site.id)
|
|
71
115
|
mapper = mapper.where(:resource => resource)
|
|
72
116
|
mapper = mapper.where(:action => action)
|
|
73
117
|
mapper = mapper.where(:key => key.present? ? key : nil)
|
|
118
|
+
mapper = mapper.where(:policy => policy.present? ? policy : nil)
|
|
74
119
|
mapper.first
|
|
75
120
|
end
|
|
121
|
+
|
|
122
|
+
# Private: selects the first mapper that fulfills the policy
|
|
123
|
+
#
|
|
124
|
+
# mappers - The Array containing the mapper objects.
|
|
125
|
+
# opts - The Hash containing the policy filter data.
|
|
126
|
+
#
|
|
127
|
+
# Returns: the first matching mapper or nil if no one matches
|
|
128
|
+
#
|
|
129
|
+
def self.select_by_policy(mappers, opts)
|
|
130
|
+
mappers.sort_by {|m| m.policy.to_s }.reverse.select {|m| m.send(:verify_policy, opts) }.first
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Private: checks the mapper policy against its class
|
|
134
|
+
#
|
|
135
|
+
# opts - The Hash containing the policy filter data.
|
|
136
|
+
#
|
|
137
|
+
# Return: true if it fulfills the policy and false if it does not.
|
|
138
|
+
#
|
|
139
|
+
def verify_policy(opts)
|
|
140
|
+
result = policy.constantize.call(opts)
|
|
141
|
+
rescue NameError
|
|
142
|
+
result = true
|
|
143
|
+
ensure
|
|
144
|
+
return result
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.check_policy_class(policy)
|
|
148
|
+
klass = policy.constantize
|
|
149
|
+
fail InvalidPolicyError.new(policy) unless klass.respond_to?(:call)
|
|
150
|
+
end
|
|
76
151
|
end
|
|
77
152
|
end
|
data/lib/xhive/mailer.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Xhive
|
|
2
2
|
class Mailer
|
|
3
|
-
attr :site, :resource, :action, :key, :mailer, :content, :page
|
|
3
|
+
attr :site, :resource, :action, :key, :mailer, :content, :page, :vars
|
|
4
4
|
|
|
5
5
|
def initialize(site, mailer, key = nil)
|
|
6
6
|
@site = site
|
|
@@ -8,7 +8,8 @@ module Xhive
|
|
|
8
8
|
@mailer = mailer
|
|
9
9
|
@action = mailer.action_name
|
|
10
10
|
@key = key
|
|
11
|
-
@
|
|
11
|
+
@vars = mailer_instance_variables(mailer)
|
|
12
|
+
@page = Xhive::Mapper.page_for(@site, @resource, @action, @key, @vars)
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
# Public: sends the email to the specified recipients.
|
|
@@ -38,7 +39,7 @@ module Xhive
|
|
|
38
39
|
#
|
|
39
40
|
def content
|
|
40
41
|
return @content if @content.present?
|
|
41
|
-
@content = page.present? ? page.present_content(
|
|
42
|
+
@content = page.present? ? page.present_content(vars) : mailer.render
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Public: returns the email subject.
|
|
@@ -46,7 +47,7 @@ module Xhive
|
|
|
46
47
|
# Returns: the rendered template or the mapped page content body.
|
|
47
48
|
#
|
|
48
49
|
def subject
|
|
49
|
-
@subject = page.present? ? page.present_title(
|
|
50
|
+
@subject = page.present? ? page.present_title(vars) : nil
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
private
|
data/lib/xhive/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xhive
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0.pre
|
|
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: 2012-11-
|
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rails
|
|
@@ -187,22 +187,6 @@ dependencies:
|
|
|
187
187
|
- - ! '>='
|
|
188
188
|
- !ruby/object:Gem::Version
|
|
189
189
|
version: '0'
|
|
190
|
-
- !ruby/object:Gem::Dependency
|
|
191
|
-
name: debugger
|
|
192
|
-
requirement: !ruby/object:Gem::Requirement
|
|
193
|
-
none: false
|
|
194
|
-
requirements:
|
|
195
|
-
- - ! '>='
|
|
196
|
-
- !ruby/object:Gem::Version
|
|
197
|
-
version: '0'
|
|
198
|
-
type: :development
|
|
199
|
-
prerelease: false
|
|
200
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
201
|
-
none: false
|
|
202
|
-
requirements:
|
|
203
|
-
- - ! '>='
|
|
204
|
-
- !ruby/object:Gem::Version
|
|
205
|
-
version: '0'
|
|
206
190
|
- !ruby/object:Gem::Dependency
|
|
207
191
|
name: mocha
|
|
208
192
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -264,6 +248,7 @@ files:
|
|
|
264
248
|
- db/migrate/20121019185702_create_xhive_mappers.rb
|
|
265
249
|
- db/migrate/20121031192552_add_key_to_xhive_mappers.rb
|
|
266
250
|
- db/migrate/20121101124925_create_xhive_images.rb
|
|
251
|
+
- db/migrate/20121127230527_add_policy_to_xhive_mappers.rb
|
|
267
252
|
- lib/tasks/xhive_tasks.rake
|
|
268
253
|
- lib/xhive/base_tag.rb
|
|
269
254
|
- lib/xhive/controller.rb
|
|
@@ -298,7 +283,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
298
283
|
version: '0'
|
|
299
284
|
segments:
|
|
300
285
|
- 0
|
|
301
|
-
hash:
|
|
286
|
+
hash: -2539444549338109190
|
|
302
287
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
303
288
|
none: false
|
|
304
289
|
requirements:
|