xhive 1.4.0.pre → 1.5.0.pre
Sign up to get free protection for your applications and to get access to all the features.
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:
|