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,46 @@
1
+ class Ruhoh
2
+ class Cache
3
+ def initialize(ruhoh)
4
+ @__cache = {}
5
+ end
6
+
7
+ def __cache
8
+ @__cache
9
+ end
10
+
11
+ def set(key, data)
12
+ key = tokenize(key)
13
+ return nil unless key
14
+
15
+ @__cache[key] = data
16
+ end
17
+
18
+ def get(key)
19
+ key = tokenize(key)
20
+ return nil unless key
21
+
22
+ if @__cache[key]
23
+ @__cache[key]
24
+ end
25
+ end
26
+
27
+ def delete(key)
28
+ @__cache.delete(tokenize(key))
29
+ end
30
+
31
+ private
32
+
33
+ def tokenize(key)
34
+ new_key = case key
35
+ when Hash
36
+ key.to_a.sort.to_s.strip
37
+ when Array
38
+ key.sort.to_s.strip
39
+ else
40
+ key.to_s.strip
41
+ end
42
+
43
+ new_key.empty? ? nil : new_key
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,162 @@
1
+ require 'ruhoh/programs/compile'
2
+ require 'ruhoh/console_methods'
3
+ require 'irb'
4
+ require 'benchmark'
5
+
6
+ class Ruhoh
7
+
8
+ class Client
9
+ DefaultBlogScaffold = 'git://github.com/ruhoh/blog.git'
10
+ Help = [
11
+ {
12
+ "command" => "new <directory_path>",
13
+ "desc" => "Create a new blog directory based on the Ruhoh specification."
14
+ },
15
+ {
16
+ "command" => "compile",
17
+ "desc" => "Compile to static website."
18
+ },
19
+ {
20
+ "command" => "help",
21
+ "desc" => "Show this menu."
22
+ }
23
+ ]
24
+ def initialize(data)
25
+ @args = data[:args]
26
+ @options = data[:options]
27
+ @opt_parser = data[:opt_parser]
28
+ @ruhoh = Ruhoh.new
29
+ cmd = (@args[0] == 'new') ? 'blog' : (@args[0] || 'help')
30
+
31
+ @ruhoh.setup
32
+ @ruhoh.setup_paths
33
+
34
+ return __send__(cmd) if respond_to?(cmd)
35
+
36
+ Ruhoh::Friend.say {
37
+ yellow "-> Autoloading '#{cmd}' as pages collection"
38
+ } unless @ruhoh.collections.exists?(cmd)
39
+
40
+ collection = @ruhoh.collection(cmd)
41
+ client = collection.load_client(data)
42
+
43
+ Ruhoh::Friend.say {
44
+ red "method '#{data[:args][1]}' not found for #{client.class}"
45
+ exit
46
+ } unless @args[1] && client.respond_to?(@args[1])
47
+
48
+ client.__send__(@args[1])
49
+ end
50
+
51
+ # Thanks rails! https://github.com/rails/rails/blob/master/railties/lib/rails/commands/console.rb
52
+ def console
53
+ require 'pp'
54
+ Ruhoh::ConsoleMethods.env = @args[1]
55
+ IRB::ExtendCommandBundle.send :include, Ruhoh::ConsoleMethods
56
+
57
+ ARGV.clear # IRB throws an error otherwise.
58
+ IRB.start
59
+ end
60
+ alias_method :c, :console
61
+
62
+ # Show Client Utility help documentation.
63
+ def help
64
+ options = @opt_parser.help
65
+ resources = [{"methods" => Help}]
66
+ resources += @ruhoh.collections.all.map {|name|
67
+ collection = @ruhoh.collection(name)
68
+ next unless collection.client?
69
+ next unless collection.client.const_defined?(:Help)
70
+ {
71
+ "name" => name,
72
+ "methods" => collection.client.const_get(:Help)
73
+ }
74
+ }.compact
75
+
76
+ Ruhoh::Friend.say {
77
+ plain "Ruhoh is a nifty, modular static blog generator."
78
+ plain "It is the Universal Static Blog API."
79
+ plain "Visit http://www.ruhoh.com for complete usage and documentation."
80
+ plain ''
81
+ plain options
82
+ plain ''
83
+ plain 'Commands:'
84
+ plain ''
85
+ resources.each do |resource|
86
+ resource["methods"].each do |method|
87
+ if resource["name"]
88
+ green(" " + "#{resource["name"]} #{method["command"]}")
89
+ else
90
+ green(" " + method["command"])
91
+ end
92
+ plain(" "+ method["desc"])
93
+ end
94
+ end
95
+ }
96
+ end
97
+
98
+ # Public: Compile to static website.
99
+ def compile
100
+ puts Benchmark.measure {
101
+ Ruhoh::Program.compile(@args[1])
102
+ }
103
+ end
104
+
105
+ # Public: Create a new blog at the directory provided.
106
+ def blog
107
+ name = @args[1]
108
+ scaffold = @args.length > 2 ? @args[2] : DefaultBlogScaffold
109
+ useHg = @options.hg
110
+ Ruhoh::Friend.say {
111
+ red "Please specify a directory path."
112
+ plain " ex: ruhoh new the-blogist"
113
+ exit
114
+ } if name.nil?
115
+
116
+ target_directory = File.join(Dir.pwd, name)
117
+
118
+ Ruhoh::Friend.say {
119
+ red "#{target_directory} already exists."
120
+ plain " Specify another directory or `rm -rf` this directory first."
121
+ exit
122
+ } if File.exist?(target_directory)
123
+
124
+ Ruhoh::Friend.say {
125
+ plain "Trying this command:"
126
+
127
+ if useHg
128
+ cyan " hg clone #{scaffold} #{target_directory}"
129
+ success = system('hg', 'clone', scaffold, target_directory)
130
+ else
131
+ cyan " git clone #{scaffold} #{target_directory}"
132
+ success = system('git', 'clone', scaffold, target_directory)
133
+ end
134
+
135
+ if success
136
+ green "Success! Now do..."
137
+ cyan " cd #{target_directory}"
138
+ cyan " rackup -p9292"
139
+ cyan " http://localhost:9292"
140
+ else
141
+ red "Could not git clone blog scaffold. Please try it manually:"
142
+ cyan " git clone git://github.com/ruhoh/blog.git #{target_directory}"
143
+ end
144
+ }
145
+ end
146
+
147
+ def ask(message, valid_options)
148
+ if valid_options
149
+ answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
150
+ else
151
+ answer = get_stdin(message)
152
+ end
153
+ answer
154
+ end
155
+
156
+ def get_stdin(message)
157
+ print message
158
+ STDIN.gets.chomp
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,172 @@
1
+ module Ruhoh::Resources ; end
2
+ # Require all the resources
3
+ FileUtils.cd(File.join(File.dirname(__FILE__), 'base')) do
4
+ (Dir['*.rb'] + Dir[File.join('*', '*.rb')]).each do |f|
5
+ require File.join(File.dirname(__FILE__), 'base', f)
6
+ end
7
+ end
8
+ FileUtils.cd(File.join(File.dirname(__FILE__), 'resources')) do
9
+ Dir[File.join('**', '*.rb')].each do |f|
10
+ require File.join(File.dirname(__FILE__), 'resources', f)
11
+ end
12
+ end
13
+
14
+ class Ruhoh
15
+ class Collections
16
+ def initialize(ruhoh)
17
+ @ruhoh = ruhoh
18
+ @collections = {}
19
+ end
20
+
21
+ def collection(resource)
22
+ get_module_namespace_for(resource).const_get(:Collection)
23
+ end
24
+
25
+ def collection?(resource)
26
+ get_module_namespace_for(resource).const_defined?(:Collection)
27
+ end
28
+
29
+ # Load and cache a given resource collection.
30
+ # This allows you to work with single object instance and perform
31
+ # persistant mutations on it if necessary.
32
+ # Note the collection is always wrapped in its view.
33
+ # @returns[Class Instance] of the resource and class_name given.
34
+ def load(resource)
35
+ return @collections[resource] if @collections[resource]
36
+ instance = collection?(resource) ?
37
+ collection(resource).new(@ruhoh) :
38
+ Ruhoh::Base::Collection.new(@ruhoh)
39
+ instance.resource_name = resource
40
+ @collections[resource] = instance.load_collection_view
41
+ end
42
+
43
+ # Load the CollectionView class for this resource.
44
+ # Used primarily to as the plugin interface to include modules for mustache.
45
+ def self.load(resource)
46
+ get_module_namespace_for(resource).const_get(:CollectionView)
47
+ end
48
+
49
+ def all
50
+ (discover + registered).uniq
51
+ end
52
+
53
+ def base
54
+ Ruhoh::Base.constants.select{ |a|
55
+ Ruhoh::Base.const_get(a).class == Module
56
+ }.map{ |a|
57
+ a.to_s.downcase
58
+ }
59
+ end
60
+
61
+ def registered
62
+ self.class.registered
63
+ end
64
+
65
+ def self.registered
66
+ Ruhoh::Resources.constants.map{ |a| a.to_s.downcase }.delete_if{ |a| a == "pages" }
67
+ end
68
+
69
+ # discover all the resource mappings
70
+ def discover
71
+ FileUtils.cd(@ruhoh.base) {
72
+ return Dir['*'].select { |x|
73
+ File.directory?(x) && !["plugins", 'compiled'].include?(x)
74
+ }
75
+ }
76
+ end
77
+
78
+ def acting_as_pages
79
+ pool = discover
80
+ theme = @ruhoh.config['theme']['name'] rescue nil
81
+ pool.delete(theme)
82
+
83
+ pool.keep_if { |resource|
84
+ config = @ruhoh.config[resource]
85
+ if (config && config["use"])
86
+ config["use"] == "pages"
87
+ else
88
+ if resource == "pages"
89
+ true
90
+ else
91
+ !registered.include?(resource)
92
+ end
93
+ end
94
+ }
95
+ end
96
+
97
+ def exists?(name)
98
+ all.include?(name)
99
+ end
100
+ alias_method :exist?, :exists?
101
+
102
+ def paginator_urls
103
+ data = {}
104
+ all.each do |name|
105
+ paginator = load(name).config['paginator']['url'] rescue nil
106
+ next if paginator.nil? || paginator.empty?
107
+
108
+ data[name] = @ruhoh.to_url(paginator)
109
+ end
110
+
111
+ data
112
+ end
113
+
114
+ def url_endpoints
115
+ urls = {}
116
+ urls["base_path"] = @ruhoh.base_path
117
+
118
+ all.each do |name|
119
+ collection = load(name)
120
+ next unless collection.respond_to?(:url_endpoint)
121
+ urls[name] = @ruhoh.to_url(collection.url_endpoint)
122
+ end
123
+
124
+ urls
125
+ end
126
+
127
+ def url_endpoints_sorted
128
+ sorted_urls = url_endpoints.each.map {|k, v| {"name" => k, "url" => v} }
129
+ sorted_urls.sort { |a, b| b["url"].length <=> a["url"].length }
130
+ end
131
+
132
+ protected
133
+
134
+ # Load the registered resource else default to Pages if not configured.
135
+ # @returns[Constant] the resource's module namespace
136
+ def get_module_namespace_for(resource)
137
+ type = @ruhoh.config[resource]["use"] rescue nil
138
+
139
+ self.class.get_module_namespace_for(resource, type)
140
+ end
141
+
142
+ def self.get_module_namespace_for(resource, type=nil)
143
+ if type
144
+ if registered.include?(type)
145
+ Ruhoh::Resources.const_get(camelize(type))
146
+ elsif base.include?(type)
147
+ Ruhoh::Base.const_get(camelize(type))
148
+ else
149
+ klass = camelize(type)
150
+ Friend.say {
151
+ red "#{resource} resource set to use:'#{type}' in config.yml but Ruhoh::Resources::#{klass} does not exist."
152
+ }
153
+ abort
154
+ end
155
+ else
156
+ if registered.include?(resource)
157
+ Ruhoh::Resources.const_get(camelize(resource))
158
+ else
159
+ Ruhoh::Resources.const_get(:Pages)
160
+ end
161
+ end
162
+ end
163
+
164
+ def camelize(name)
165
+ self.class.camelize(name)
166
+ end
167
+
168
+ def self.camelize(name)
169
+ name.to_s.split('_').map {|a| a.capitalize}.join
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,21 @@
1
+ class Ruhoh
2
+ module ConsoleMethods
3
+ class << self
4
+ attr_accessor :env
5
+ end
6
+
7
+ def ruhoh
8
+ return @ruhoh if @ruhoh
9
+ @ruhoh = Ruhoh.new
10
+ @ruhoh.setup
11
+ @ruhoh.env = ConsoleMethods.env || 'development'
12
+ @ruhoh.setup_paths
13
+ @ruhoh
14
+ end
15
+
16
+ def reload!
17
+ @ruhoh = nil
18
+ self.ruhoh
19
+ end
20
+ end
21
+ end
@@ -1,4 +1,7 @@
1
- require 'ruhoh/converters/markdown'
1
+ # Require all the converters
2
+ Dir[File.join(File.dirname(__FILE__), 'converters', '*.rb')].each { |f|
3
+ require f
4
+ }
2
5
 
3
6
  class Ruhoh
4
7
  module Converter
@@ -0,0 +1,22 @@
1
+ class Ruhoh
2
+ module Program
3
+ # Public: A program for compiling to a static website.
4
+ # The compile environment should always be 'production' in order
5
+ # to properly omit drafts and other development-only settings.
6
+ def self.compile(target)
7
+ ruhoh = Ruhoh.new
8
+ ruhoh.setup
9
+ ruhoh.env = 'production'
10
+ ruhoh.setup_paths
11
+ ruhoh.setup_plugins
12
+
13
+ if target
14
+ ruhoh.paths.compiled = File.expand_path(target)
15
+ elsif ruhoh.config["compiled"]
16
+ ruhoh.paths.compiled = ruhoh.config["compiled"]
17
+ end
18
+
19
+ ruhoh.compile
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ require 'ruhoh/programs/watch'
2
+ class Ruhoh
3
+ module Program
4
+ # Public: A program for running ruhoh as a rack application
5
+ # which renders singular pages via their URL.
6
+ #
7
+ # Examples
8
+ #
9
+ # In config.ru:
10
+ #
11
+ # require 'ruhoh'
12
+ # run Ruhoh::Program.preview
13
+ #
14
+ # Returns: A new Rack builder object which should work inside config.ru
15
+ def self.preview(opts={})
16
+ opts[:watch] ||= true
17
+ opts[:env] ||= 'development'
18
+
19
+ ruhoh = Ruhoh.new
20
+ ruhoh.setup
21
+ ruhoh.env = opts[:env]
22
+ ruhoh.setup_paths
23
+ ruhoh.setup_plugins unless opts[:enable_plugins] == false
24
+
25
+ # initialize the routes dictionary for all page resources.
26
+ ruhoh.routes.all
27
+
28
+ Ruhoh::Program.watch(ruhoh) if opts[:watch]
29
+ Rack::Builder.new {
30
+ use Rack::Lint
31
+ use Rack::ShowExceptions
32
+
33
+ # Url endpoints as registered by the resources.
34
+ # The urls are mapped to the resource's individual rack-compatable Previewer class.
35
+ # Note page-like resources (posts, pages) don't render uniform url endpoints,
36
+ # since presumably they define customized permalinks per singular resource.
37
+ # Page-like resources are handled the root mapping below.
38
+ ruhoh.collections.url_endpoints_sorted.each do |h|
39
+ # Omit base_path and theme because they are special use-cases.
40
+ next if %w{base_path theme}.include?(h["name"])
41
+ map h["url"] do
42
+ collection = ruhoh.collection(h["name"])
43
+ if collection.previewer?
44
+ run collection.load_previewer
45
+ else
46
+ run Rack::Cascade.new(
47
+ collection.paths.reverse.map { |path|
48
+ Rack::File.new(path)
49
+ }
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ # The generic Page::Previewer is used to render any/all page-like resources,
56
+ # since they likely have arbitrary urls based on permalink settings.
57
+ map '/' do
58
+ run Ruhoh::Resources::Pages::Previewer.new(ruhoh)
59
+ end
60
+ }
61
+ end
62
+ end
63
+ end