ruhoh 1.1 → 2.1

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.
Files changed (121) hide show
  1. data/Gemfile +3 -3
  2. data/README.md +3 -2
  3. data/Rakefile +1 -22
  4. data/bin/ruhoh +1 -5
  5. data/history.json +16 -0
  6. data/lib/ruhoh.rb +229 -84
  7. data/lib/ruhoh/base/collection.rb +280 -0
  8. data/lib/ruhoh/base/compiler.rb +55 -0
  9. data/lib/ruhoh/base/model.rb +220 -0
  10. data/lib/ruhoh/base/model_view.rb +152 -0
  11. data/lib/ruhoh/base/watcher.rb +25 -0
  12. data/lib/ruhoh/cache.rb +46 -0
  13. data/lib/ruhoh/client.rb +162 -0
  14. data/lib/ruhoh/collections.rb +172 -0
  15. data/lib/ruhoh/console_methods.rb +21 -0
  16. data/lib/ruhoh/{converters/converter.rb → converter.rb} +4 -1
  17. data/lib/ruhoh/programs/compile.rb +22 -0
  18. data/lib/ruhoh/programs/preview.rb +63 -0
  19. data/lib/ruhoh/programs/watch.rb +45 -0
  20. data/lib/ruhoh/resources/dash/collection.rb +10 -0
  21. data/lib/ruhoh/resources/dash/model.rb +5 -0
  22. data/lib/ruhoh/resources/dash/model_view.rb +5 -0
  23. data/lib/ruhoh/resources/dash/previewer.rb +13 -0
  24. data/lib/ruhoh/resources/data/collection.rb +9 -0
  25. data/lib/ruhoh/resources/data/collection_view.rb +23 -0
  26. data/lib/ruhoh/resources/javascripts/collection.rb +9 -0
  27. data/lib/ruhoh/resources/javascripts/collection_view.rb +46 -0
  28. data/lib/ruhoh/resources/javascripts/compiler.rb +5 -0
  29. data/lib/ruhoh/resources/layouts/client.rb +45 -0
  30. data/lib/ruhoh/resources/layouts/model.rb +16 -0
  31. data/lib/ruhoh/resources/media/collection.rb +9 -0
  32. data/lib/ruhoh/resources/media/compiler.rb +27 -0
  33. data/lib/ruhoh/resources/pages/client.rb +124 -0
  34. data/lib/ruhoh/resources/pages/collection.rb +86 -0
  35. data/lib/ruhoh/resources/pages/collection_view.rb +73 -0
  36. data/lib/ruhoh/resources/pages/compiler.rb +101 -0
  37. data/lib/ruhoh/resources/pages/model.rb +5 -0
  38. data/lib/ruhoh/resources/pages/model_view.rb +5 -0
  39. data/lib/ruhoh/resources/pages/previewer.rb +72 -0
  40. data/lib/ruhoh/resources/partials/model.rb +11 -0
  41. data/lib/ruhoh/resources/stylesheets/collection.rb +9 -0
  42. data/lib/ruhoh/resources/stylesheets/collection_view.rb +45 -0
  43. data/lib/ruhoh/resources/stylesheets/compiler.rb +5 -0
  44. data/lib/ruhoh/resources/theme/collection.rb +14 -0
  45. data/lib/ruhoh/resources/theme/compiler.rb +54 -0
  46. data/lib/ruhoh/resources/widgets/collection.rb +26 -0
  47. data/lib/ruhoh/resources/widgets/collection_view.rb +34 -0
  48. data/lib/ruhoh/resources/widgets/compiler.rb +27 -0
  49. data/lib/ruhoh/resources/widgets/model.rb +16 -0
  50. data/lib/ruhoh/routes.rb +29 -0
  51. data/lib/ruhoh/utils.rb +32 -49
  52. data/lib/ruhoh/version.rb +2 -2
  53. data/lib/ruhoh/views/helpers/categories.rb +38 -0
  54. data/lib/ruhoh/views/helpers/paginator.rb +39 -0
  55. data/lib/ruhoh/views/helpers/tags.rb +37 -0
  56. data/lib/ruhoh/views/master_view.rb +183 -0
  57. data/lib/ruhoh/views/rmustache.rb +24 -0
  58. data/ruhoh.gemspec +6 -82
  59. data/spec/spec_helper.rb +1 -1
  60. data/spec/support/shared_contexts.rb +6 -5
  61. data/system/{scaffolds/post.html → _scaffold.html} +1 -1
  62. data/system/{dash.html → dash/index.html} +37 -51
  63. data/system/{scaffolds/layout.html → layouts/_scaffold.html} +0 -0
  64. data/system/layouts/paginator.html +28 -0
  65. data/system/plugins/sprockets/javascripts/compiler.rb +25 -0
  66. data/system/plugins/sprockets/javascripts/previewer.rb +17 -0
  67. data/system/plugins/sprockets/stylesheets/compiler.rb +26 -0
  68. data/system/plugins/sprockets/stylesheets/previewer.rb +17 -0
  69. data/system/widgets/analytics/{layouts/getclicky.html → getclicky.html} +6 -2
  70. data/system/widgets/analytics/{layouts/google.html → google.html} +5 -1
  71. data/system/widgets/comments/{layouts/disqus.html → disqus.html} +6 -2
  72. data/system/widgets/comments/{layouts/facebook.html → facebook.html} +9 -2
  73. data/system/widgets/comments/{layouts/intensedebate.html → intensedebate.html} +5 -1
  74. data/system/widgets/comments/{layouts/livefyre.html → livefyre.html} +5 -1
  75. data/system/widgets/google_prettify/{layouts/google_prettify.html → default.html} +6 -2
  76. metadata +69 -66
  77. data/lib/ruhoh/client/client.rb +0 -306
  78. data/lib/ruhoh/client/console_methods.rb +0 -9
  79. data/lib/ruhoh/client/help.yml +0 -56
  80. data/lib/ruhoh/compiler.rb +0 -72
  81. data/lib/ruhoh/compilers/rss.rb +0 -39
  82. data/lib/ruhoh/compilers/theme.rb +0 -46
  83. data/lib/ruhoh/config.rb +0 -62
  84. data/lib/ruhoh/db.rb +0 -50
  85. data/lib/ruhoh/deployers/s3.rb +0 -71
  86. data/lib/ruhoh/page.rb +0 -106
  87. data/lib/ruhoh/parsers/javascripts.rb +0 -55
  88. data/lib/ruhoh/parsers/layouts.rb +0 -32
  89. data/lib/ruhoh/parsers/pages.rb +0 -79
  90. data/lib/ruhoh/parsers/partials.rb +0 -42
  91. data/lib/ruhoh/parsers/payload.rb +0 -49
  92. data/lib/ruhoh/parsers/posts.rb +0 -259
  93. data/lib/ruhoh/parsers/routes.rb +0 -20
  94. data/lib/ruhoh/parsers/scaffolds.rb +0 -35
  95. data/lib/ruhoh/parsers/site.rb +0 -19
  96. data/lib/ruhoh/parsers/stylesheets.rb +0 -63
  97. data/lib/ruhoh/parsers/theme_config.rb +0 -30
  98. data/lib/ruhoh/parsers/widgets.rb +0 -104
  99. data/lib/ruhoh/paths.rb +0 -83
  100. data/lib/ruhoh/previewer.rb +0 -48
  101. data/lib/ruhoh/program.rb +0 -68
  102. data/lib/ruhoh/templaters/asset_helpers.rb +0 -66
  103. data/lib/ruhoh/templaters/base_helpers.rb +0 -147
  104. data/lib/ruhoh/templaters/helpers.rb +0 -8
  105. data/lib/ruhoh/templaters/rmustache.rb +0 -70
  106. data/lib/ruhoh/urls.rb +0 -50
  107. data/lib/ruhoh/watch.rb +0 -78
  108. data/spec/config_spec.rb +0 -50
  109. data/spec/db_spec.rb +0 -91
  110. data/spec/page_spec.rb +0 -164
  111. data/spec/parsers/layouts_spec.rb +0 -41
  112. data/spec/parsers/pages_spec.rb +0 -120
  113. data/spec/parsers/posts_spec.rb +0 -309
  114. data/spec/parsers/routes_spec.rb +0 -39
  115. data/spec/parsers/site_spec.rb +0 -28
  116. data/spec/setup_spec.rb +0 -12
  117. data/system/scaffolds/draft.html +0 -9
  118. data/system/scaffolds/page.html +0 -4
  119. data/system/widgets/analytics/config.yml +0 -5
  120. data/system/widgets/comments/config.yml +0 -13
  121. data/system/widgets/google_prettify/config.yml +0 -1
@@ -0,0 +1,27 @@
1
+ module Ruhoh::Resources::Widgets
2
+ class Compiler
3
+ include Ruhoh::Base::Compilable
4
+
5
+ def run
6
+ collection = @collection
7
+ unless @collection.paths?
8
+ Ruhoh::Friend.say { yellow "#{collection.resource_name.capitalize}: directory not found - skipping." }
9
+ return
10
+ end
11
+ Ruhoh::Friend.say { cyan "#{collection.resource_name.capitalize}: (copying valid files)" }
12
+
13
+ compiled_path = Ruhoh::Utils.url_to_path(@ruhoh.to_url(@collection.url_endpoint), @ruhoh.paths.compiled)
14
+ FileUtils.mkdir_p compiled_path
15
+
16
+ files = @collection.files.values
17
+ # Don't copy over the layouts.
18
+ files.delete_if { |p| p['id'].end_with?('.html') }
19
+ files.each do |pointer|
20
+ compiled_file = File.join(compiled_path, pointer['id'])
21
+ FileUtils.mkdir_p File.dirname(compiled_file)
22
+ FileUtils.cp_r pointer['realpath'], compiled_file
23
+ Ruhoh::Friend.say { green " > #{pointer['id']}" }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module Ruhoh::Resources::Widgets
2
+ class Model
3
+ include Ruhoh::Base::PageLike
4
+
5
+ def process
6
+ parsed = parse_page_file
7
+ @data = parsed['data']
8
+ @content = parsed['content']
9
+
10
+ changed
11
+ notify_observers(parsed)
12
+
13
+ parsed
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ class Ruhoh
2
+ class Routes
3
+ def initialize(ruhoh)
4
+ @ruhoh = ruhoh
5
+ end
6
+
7
+ def find(route)
8
+ @ruhoh.collections.acting_as_pages.each do |r|
9
+ next unless @ruhoh.collection(r).routes[route]
10
+ return @ruhoh.collection(r).routes[route]
11
+ break
12
+ end
13
+
14
+ nil
15
+ end
16
+
17
+ # All available routes from pages.
18
+ # This is not cached because the page collections should manage
19
+ # their own cache invalidation strategy
20
+ # @returns[Hash map]
21
+ def all
22
+ routes = {}
23
+ @ruhoh.collections.acting_as_pages.each do |r|
24
+ routes.merge!(@ruhoh.collection(r).routes)
25
+ end
26
+ routes
27
+ end
28
+ end
29
+ end
data/lib/ruhoh/utils.rb CHANGED
@@ -15,60 +15,24 @@ class Ruhoh
15
15
  nil
16
16
  end
17
17
 
18
- def self.parse_page_file(*args)
19
- path = File.__send__(:join, args)
20
- raise "File not found: #{path}" unless File.exist?(path)
21
-
22
- page = File.open(path, 'r:UTF-8') {|f| f.read }
23
-
24
- front_matter = page.match(FMregex)
25
- if front_matter
26
- data = YAML.load(front_matter[0].gsub(/---\n/, "")) || {}
27
- data['categories'] = Array(data['categories'])
28
- data['tags'] = Array(data['tags'])
29
- else
30
- data = {}
31
- end
32
-
33
- {
34
- "data" => data,
35
- "content" => page.gsub(FMregex, '')
36
- }
37
- rescue Psych::SyntaxError => e
38
- Ruhoh.log.error("ERROR in #{path}: #{e.message}")
39
- nil
40
- end
41
-
42
- def self.parse_layout_file(*args)
43
- path = File.__send__(:join, args)
44
- raise "Layout file not found: #{path}" unless File.exist?(path)
45
- data = {}
46
- page = File.open(path, 'r:UTF-8') {|f| f.read }
47
-
48
- front_matter = page.match(FMregex)
49
- if front_matter
50
- data = YAML.load(front_matter[0].gsub(/---\n/, "")) || {}
51
- end
52
-
53
- {
54
- "data" => data,
55
- "content" => page.gsub(FMregex, '')
56
- }
57
- rescue Psych::SyntaxError => e
58
- Ruhoh.log.error("ERROR in #{path}: #{e.message}")
59
- nil
60
- end
61
-
62
- def self.relative_path(filename)
63
- filename.gsub(Regexp.new("^#{Ruhoh.paths.base}/"), '')
64
- end
65
-
66
18
  def self.url_to_path(url, base=nil)
19
+ url = url.gsub(/^\//, '')
67
20
  parts = url.split('/')
68
21
  parts = parts.unshift(base) if base
69
22
  File.__send__(:join, parts)
70
23
  end
71
-
24
+
25
+ def self.to_url_slug(title)
26
+ CGI::escape self.to_slug(title)
27
+ end
28
+
29
+ # My Post Title ===> my-post-title
30
+ def self.to_slug(title)
31
+ title = title.to_s.downcase.strip.gsub(/[^\p{Word}+]/u, '-')
32
+ title.gsub(/^\-+/, '').gsub(/\-+$/, '').gsub(/\-+/, '-')
33
+ end
34
+
35
+
72
36
  def self.report(name, collection, invalid)
73
37
  output = "#{collection.count}/#{collection.count + invalid.count} #{name} processed."
74
38
  if collection.empty? && invalid.empty?
@@ -102,5 +66,24 @@ class Ruhoh
102
66
  target
103
67
  end
104
68
 
69
+ def self.constantize(class_name)
70
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ class_name
71
+ raise NameError, "#{class_name.inspect} is not a valid constant name!"
72
+ end
73
+
74
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
75
+ end
76
+
77
+ # Thanks ActiveSupport: http://stackoverflow.com/a/1509939/101940
78
+ def self.underscore(string)
79
+ string.
80
+ to_s.
81
+ gsub(/::/, '/').
82
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
83
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
84
+ tr("-", "_").
85
+ downcase
86
+ end
87
+
105
88
  end
106
89
  end #Ruhoh
data/lib/ruhoh/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  class Ruhoh
2
- Version = VERSION = '1.1'
3
- RuhohSpec = '1.0'
2
+ Version = VERSION = '2.1'
3
+ RuhohSpec = '2.1'
4
4
  end
@@ -0,0 +1,38 @@
1
+ module Ruhoh::Views::Helpers
2
+ module Categories
3
+ # Category dictionary
4
+ def categories
5
+ categories_url = nil
6
+ [ruhoh.to_url("categories"), ruhoh.to_url("categories.html")].each { |url|
7
+ categories_url = url and break if ruhoh.routes.find(url)
8
+ }
9
+ dict = {}
10
+ dictionary.each_value do |model|
11
+ Array(model.data['categories']).each do |cat|
12
+ cat = Array(cat).join('/')
13
+ if dict[cat]
14
+ dict[cat]['count'] += 1
15
+ else
16
+ dict[cat] = {
17
+ 'count' => 1,
18
+ 'name' => cat,
19
+ resource_name => [],
20
+ 'url' => "#{categories_url}##{cat}-ref"
21
+ }
22
+ end
23
+
24
+ dict[cat][resource_name] << model.id
25
+ end
26
+ end
27
+ dict["all"] = dict.each_value.map { |cat| cat }
28
+ dict
29
+ end
30
+
31
+ # Convert single or Array of category ids (names) to category hash(es).
32
+ def to_categories(sub_context)
33
+ Array(sub_context).map { |id|
34
+ categories[id]
35
+ }.compact
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ module Ruhoh::Views::Helpers
2
+ module Paginator
3
+ # current_page is set via a compiler or previewer
4
+ # in which it can discern what current_page to serve
5
+ def paginator
6
+ per_page = config["paginator"]["per_page"] rescue 5
7
+ current_page = master.page_data['current_page'].to_i
8
+ current_page = current_page.zero? ? 1 : current_page
9
+ offset = (current_page-1)*per_page
10
+
11
+ page_batch = all[offset, per_page]
12
+ raise "Page does not exist" unless page_batch
13
+ page_batch
14
+ end
15
+
16
+ def paginator_navigation
17
+ paginator_config = config["paginator"] || {}
18
+ page_count = all.length
19
+ total_pages = (page_count.to_f/paginator_config["per_page"]).ceil
20
+ current_page = master.page_data['current_page'].to_i
21
+ current_page = current_page.zero? ? 1 : current_page
22
+
23
+ pages = total_pages.times.map { |i|
24
+ url = if i.zero? && paginator_config["root_page"]
25
+ paginator_config["root_page"]
26
+ else
27
+ "#{paginator_config["url"]}/#{i+1}"
28
+ end
29
+
30
+ {
31
+ "url" => ruhoh.to_url(url),
32
+ "name" => "#{i+1}",
33
+ "is_active_page" => (i+1 == current_page)
34
+ }
35
+ }
36
+ pages
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ module Ruhoh::Views::Helpers
2
+ module Tags
3
+ # Generate the tags dictionary
4
+ def tags
5
+ tags_url = nil
6
+ [ruhoh.to_url("tags"), ruhoh.to_url("tags.html")].each { |url|
7
+ tags_url = url and break if ruhoh.routes.find(url)
8
+ }
9
+ dict = {}
10
+ dictionary.each_value do |model|
11
+ Array(model.data['tags']).each do |tag|
12
+ if dict[tag]
13
+ dict[tag]['count'] += 1
14
+ else
15
+ dict[tag] = {
16
+ 'count' => 1,
17
+ 'name' => tag,
18
+ resource_name => [],
19
+ 'url' => "#{tags_url}##{tag}-ref"
20
+ }
21
+ end
22
+
23
+ dict[tag][resource_name] << model.id
24
+ end
25
+ end
26
+ dict["all"] = dict.each_value.map { |tag| tag }
27
+ dict
28
+ end
29
+
30
+ # Convert single or Array of tag ids (names) to tag hash(es).
31
+ def to_tags(sub_context)
32
+ Array(sub_context).map { |id|
33
+ tags[id]
34
+ }.compact
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,183 @@
1
+ require 'ruhoh/views/rmustache'
2
+
3
+ module Ruhoh::Views
4
+ module Helpers ; end
5
+ class MasterView < RMustache
6
+ attr_reader :sub_layout, :master_layout
7
+ attr_accessor :page_data
8
+
9
+ def initialize(ruhoh, pointer_or_data)
10
+ @ruhoh = ruhoh
11
+ define_resource_collection_namespaces(ruhoh)
12
+
13
+ if pointer_or_data['id']
14
+ @pointer = pointer_or_data
15
+ @page = collection.find(pointer_or_data)
16
+ unless @page
17
+ raise "Could not find the page with pointer: #{ pointer_or_data }" +
18
+ "Finding this page is required because an 'id' key is being passed."
19
+ end
20
+
21
+ @page_data = @page.data.dup # legacy...working on removing this..
22
+ else
23
+ @content = pointer_or_data['content']
24
+ @page_data = pointer_or_data
25
+ @pointer = pointer_or_data
26
+ end
27
+ end
28
+
29
+ def render_full
30
+ process_layouts
31
+ render(expand_layouts)
32
+ end
33
+
34
+ def render_content
35
+ render('{{{page.content}}}')
36
+ end
37
+
38
+ # Delegate #page to the kind of resource this view is modeling.
39
+ def page
40
+ collection ? collection.find(@pointer) : nil
41
+ end
42
+
43
+ def collection
44
+ @pointer["resource"] ? __send__(@pointer["resource"]) : nil
45
+ end
46
+
47
+ def urls
48
+ @ruhoh.collections.url_endpoints
49
+ end
50
+
51
+ def content
52
+ render(@content || page.content)
53
+ end
54
+
55
+ # NOTE: newline ensures proper markdown rendering.
56
+ def partial(name)
57
+ partial = partials.find(name.to_s)
58
+ partial ?
59
+ partial.process.to_s + "\n" :
60
+ Ruhoh::Friend.say { yellow "partial not found: '#{name}'" }
61
+ end
62
+
63
+ def page_collections
64
+ @ruhoh.collections.acting_as_pages.map do |a|
65
+ @ruhoh.collection(a)
66
+ end
67
+ end
68
+
69
+ def to_json(sub_context)
70
+ sub_context.to_json
71
+ end
72
+
73
+ def to_pretty_json(sub_context)
74
+ JSON.pretty_generate(sub_context)
75
+ end
76
+
77
+ def debug(sub_context)
78
+ Ruhoh::Friend.say {
79
+ yellow "?debug:"
80
+ magenta sub_context.class
81
+ cyan sub_context.inspect
82
+ }
83
+
84
+ "<pre>#{sub_context.class}\n#{sub_context.pretty_inspect}</pre>"
85
+ end
86
+
87
+ def raw_code(sub_context)
88
+ code = sub_context.gsub('{', '&#123;').gsub('}', '&#125;').gsub('<', '&lt;').gsub('>', '&gt;').gsub('_', "&#95;")
89
+ "<pre><code>#{code}</code></pre>\n"
90
+ end
91
+
92
+ # My Post Title ===> my-post-title
93
+ # Handy for transforming ids into css-classes in your views.
94
+ # @returns[String]
95
+ def to_slug(sub_context)
96
+ Ruhoh::Utils.to_slug(sub_context)
97
+ end
98
+
99
+ # Public: Formats the path to the compiled file based on the URL.
100
+ #
101
+ # Returns: [String] The relative path to the compiled file for this page.
102
+ def compiled_path
103
+ path = CGI.unescape(@page_data['url']).gsub(/^\//, '') #strip leading slash.
104
+ path = "index.html" if path.empty?
105
+ path += '/index.html' unless path =~ /\.\w+$/
106
+ path
107
+ end
108
+
109
+ protected
110
+
111
+ def process_layouts
112
+ if @page_data['layout']
113
+ @sub_layout = layouts.find(@page_data['layout'], :all => true)
114
+ raise "Layout does not exist: #{@page_data['layout']}" unless @sub_layout
115
+ elsif @page_data['layout'] != false
116
+ # try default
117
+ @sub_layout = layouts.find(@pointer["resource"], :all => true)
118
+ end
119
+
120
+ if @sub_layout && @sub_layout.layout
121
+ @master_layout = layouts.find(@sub_layout.layout)
122
+ raise "Layout does not exist: #{ @sub_layout.layout }" unless @master_layout
123
+ end
124
+ end
125
+
126
+ # Expand the layout(s).
127
+ # Pages may have a single master_layout, a master_layout + sub_layout, or no layout.
128
+ def expand_layouts
129
+ if @sub_layout
130
+ layout = @sub_layout.content
131
+
132
+ # If a master_layout is found we need to process the sub_layout
133
+ # into the master_layout using mustache.
134
+ if @master_layout && @master_layout.content
135
+ layout = render(@master_layout.content, {"content" => layout})
136
+ end
137
+ else
138
+ # Minimum layout if no layout defined.
139
+ layout = page ? '{{{ page.content }}}' : '{{{ content }}}'
140
+ end
141
+
142
+ layout
143
+ end
144
+
145
+ private
146
+
147
+ # Dynamically add method proxies to resource collections
148
+ # This is how collections are accessed throughout mustache's global context.
149
+ # Also support calling ?to_<resource> contextual block helpers
150
+ def define_resource_collection_namespaces(ruhoh)
151
+ ruhoh.collections.all.each do |method_name|
152
+ (class << self; self; end).class_eval do
153
+ define_method(method_name) do
154
+ load_collection_view_for(method_name.to_s)
155
+ end
156
+
157
+ define_method("to_#{method_name}") do |*args|
158
+ resource_generator_for(method_name, *args)
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ # Load collection views dynamically when calling a resources name.
165
+ # Uses method_missing to catch calls to resource namespace.
166
+ # @returns[CollectionView] for the calling resource.
167
+ def load_collection_view_for(resource)
168
+ view = @ruhoh.collection(resource)
169
+ view.master = self
170
+ view
171
+ end
172
+
173
+ # Transforms an Array or String of resource ids into their corresponding resource objects.
174
+ # Uses method_missing to catch calls to 'to_<resource>` contextual helper.
175
+ # @returns[Array] the resource modelView objects or raw data hash.
176
+ def resource_generator_for(resource, sub_context)
177
+ collection_view = load_collection_view_for(resource)
178
+ Array(sub_context).map { |id|
179
+ collection_view.find(id)
180
+ }.compact
181
+ end
182
+ end
183
+ end