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,73 @@
1
+ require 'ruhoh/views/helpers/categories'
2
+ require 'ruhoh/views/helpers/tags'
3
+ require 'ruhoh/views/helpers/paginator'
4
+ module Ruhoh::Resources::Pages
5
+
6
+ class CollectionView < SimpleDelegator
7
+ include Ruhoh::Views::Helpers::Tags
8
+ include Ruhoh::Views::Helpers::Categories
9
+ include Ruhoh::Views::Helpers::Paginator
10
+
11
+ def all
12
+ dictionary.each_value.find_all { |model|
13
+ File.basename(File.dirname(model.id)) != "drafts"
14
+ }.sort
15
+ end
16
+
17
+ def drafts
18
+ dictionary.each_value.find_all { |model|
19
+ File.basename(File.dirname(model.id)) == "drafts"
20
+ }.sort
21
+ end
22
+
23
+ def latest
24
+ latest = config['latest']
25
+ latest ||= 10
26
+ (latest.to_i > 0) ? all[0, latest.to_i] : all
27
+ end
28
+
29
+ # Internal: Create a collated pages data structure.
30
+ #
31
+ # pages - Required [Array]
32
+ # Must be sorted chronologically beforehand.
33
+ #
34
+ # @returns[Array] collated pages:
35
+ # [{ 'year': year,
36
+ # 'months' : [{ 'month' : month,
37
+ # 'pages': [{}, {}, ..] }, ..] }, ..]
38
+ def collated
39
+ collated = []
40
+ pages = all
41
+ pages.each_with_index do |page, i|
42
+ thisYear = Time.parse(page['date']).strftime('%Y')
43
+ thisMonth = Time.parse(page['date']).strftime('%B')
44
+ if (i-1 >= 0)
45
+ prevYear = Time.parse(pages[i-1]['date']).strftime('%Y')
46
+ prevMonth = Time.parse(pages[i-1]['date']).strftime('%B')
47
+ end
48
+
49
+ if(prevYear == thisYear)
50
+ if(prevMonth == thisMonth)
51
+ collated.last['months'].last[resource_name] << page['id'] # append to last year & month
52
+ else
53
+ collated.last['months'] << {
54
+ 'month' => thisMonth,
55
+ resource_name => [page['id']]
56
+ } # create new month
57
+ end
58
+ else
59
+ collated << {
60
+ 'year' => thisYear,
61
+ 'months' => [{
62
+ 'month' => thisMonth,
63
+ resource_name => [page['id']]
64
+ }]
65
+ } # create new year & month
66
+ end
67
+
68
+ end
69
+
70
+ collated
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,101 @@
1
+ require 'nokogiri'
2
+ module Ruhoh::Resources::Pages
3
+ class Compiler
4
+ include Ruhoh::Base::Compilable
5
+
6
+ def run
7
+ pages = @collection.all
8
+ resource_name = @collection.resource_name
9
+ Ruhoh::Friend.say { cyan "#{resource_name.capitalize}: (#{pages.count} #{resource_name})" }
10
+
11
+ FileUtils.cd(@ruhoh.paths.compiled) {
12
+ pages.each do |data|
13
+ view = @ruhoh.master_view(data['pointer'])
14
+
15
+ FileUtils.mkdir_p File.dirname(view.compiled_path)
16
+ File.open(view.compiled_path, 'w:UTF-8') { |p| p.puts view.render_full }
17
+
18
+ Ruhoh::Friend.say { green " > #{data['id']}" }
19
+ end
20
+ }
21
+
22
+ pagination
23
+ rss
24
+ end
25
+
26
+ def pagination
27
+ config = @collection.config["paginator"] || {}
28
+ resource_name = @collection.resource_name
29
+ if config["enable"] == false
30
+ Ruhoh::Friend.say { yellow "#{resource_name} paginator: disabled - skipping." }
31
+ return
32
+ end
33
+
34
+ pages_count = @collection.all.length
35
+ total_pages = (pages_count.to_f/config["per_page"]).ceil
36
+
37
+ Ruhoh::Friend.say { cyan "#{resource_name} paginator: (#{total_pages} pages)" }
38
+
39
+ FileUtils.cd(@ruhoh.paths.compiled) {
40
+ total_pages.times.map { |i|
41
+ # if a root page is defined we assume it's getting compiled elsewhere.
42
+ next if (i.zero? && config["root_page"])
43
+
44
+ url = "#{config["url"]}/#{i+1}"
45
+ view = @ruhoh.master_view({"resource" => resource_name})
46
+ view.page_data = {
47
+ "layout" => config["layout"],
48
+ "current_page" => (i+1),
49
+ "url" => @ruhoh.to_url(url)
50
+ }
51
+ FileUtils.mkdir_p File.dirname(view.compiled_path)
52
+ File.open(view.compiled_path, 'w:UTF-8') { |p| p.puts view.render_full }
53
+ Ruhoh::Friend.say { green " > #{view.page_data['url']}" }
54
+ }
55
+ }
56
+ end
57
+
58
+ def rss
59
+ config = @collection.config["rss"] || {}
60
+ resource_name = @collection.resource_name
61
+ if config["enable"] == false
62
+ Ruhoh::Friend.say { yellow "#{resource_name} RSS: disabled - skipping." }
63
+ return
64
+ end
65
+
66
+ limit = config["limit"] || 20
67
+ pages = @collection.all.first(limit)
68
+ Ruhoh::Friend.say { cyan "#{resource_name} RSS: (first #{limit} pages)" }
69
+ data = @ruhoh.collection("data").dictionary
70
+
71
+ feed = Nokogiri::XML::Builder.new do |xml|
72
+ xml.rss(:version => '2.0') {
73
+ xml.channel {
74
+ xml.title_ data['title']
75
+ xml.link_ @ruhoh.config['production_url']
76
+ xml.pubDate_ Time.now
77
+ pages.each do |page|
78
+ view = @ruhoh.master_view(page.pointer)
79
+ xml.item {
80
+ xml.title_ page.title
81
+ xml.link "#{@ruhoh.config['production_url']}#{page.url}"
82
+ xml.pubDate_ page.date if page.date
83
+ xml.description_ (page.try(:description) ? page.description : view.render_content)
84
+ }
85
+ end
86
+ }
87
+ }
88
+ end
89
+
90
+ FileUtils.cd(@ruhoh.paths.compiled) {
91
+ compiled_path = CGI.unescape(@ruhoh.to_url(config['url'], "rss.xml"))
92
+ compiled_path = compiled_path.gsub(/^\//, '')
93
+
94
+ FileUtils.mkdir_p File.dirname(compiled_path)
95
+ File.open(compiled_path, 'w'){ |p| p.puts feed.to_xml }
96
+
97
+ Ruhoh::Friend.say { green " > #{compiled_path}" }
98
+ }
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module Ruhoh::Resources::Pages
2
+ class Model
3
+ include Ruhoh::Base::PageLike
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Ruhoh::Resources::Pages
2
+ class ModelView < SimpleDelegator
3
+ include Ruhoh::Base::PageViewable
4
+ end
5
+ end
@@ -0,0 +1,72 @@
1
+ # Public: Rack application used to render singular pages via their URL.
2
+ module Ruhoh::Resources::Pages
3
+ class Previewer
4
+
5
+ def initialize(ruhoh)
6
+ @ruhoh = ruhoh
7
+ end
8
+
9
+ def call(env)
10
+ return favicon if env['PATH_INFO'] == '/favicon.ico'
11
+
12
+ # Always remove trailing slash if sent unless it's the root page.
13
+ env['PATH_INFO'].chomp!("/") unless env['PATH_INFO'] == "/"
14
+
15
+ pointer = @ruhoh.routes.find(env['PATH_INFO'])
16
+ view = pointer ? @ruhoh.master_view(pointer) : paginator_view(env)
17
+ if view
18
+ content = view.render_full
19
+ Ruhoh::Friend.say {
20
+ cyan "-> previewing page:"
21
+ plain " - #{pointer.inspect}"
22
+ plain " - sub-layout: #{ view.sub_layout }"
23
+ plain " - master-layout: #{ view.master_layout }"
24
+ plain " - meta-data: #{ view.page_data }"
25
+ }
26
+ [200, {'Content-Type' => 'text/html'}, [content]]
27
+ else
28
+ message = "No generated page URL matches '#{ env['PATH_INFO'] }'" +
29
+ " using file pointer: '#{ pointer.inspect }'."
30
+
31
+ if pointer.nil?
32
+ message += " Since the file pointer was nil" +
33
+ " we tried to load a pagination view but it didn't work;" +
34
+ "\n Expected the format to be: '<valid_resource_name>/page_number'"
35
+ end
36
+
37
+ raise message
38
+ end
39
+ end
40
+
41
+ # Try the paginator.
42
+ # search for the namespace and match it to a resource:
43
+ # need a way to register pagination namespaces then search the register.
44
+ def paginator_view(env)
45
+ path = env['PATH_INFO'].reverse.chomp("/").reverse
46
+ resource = @ruhoh.collections.paginator_urls.find do |a, b|
47
+ "/#{ path }" =~ %r{^#{ b }}
48
+ end
49
+ resource = resource[0] if resource
50
+ return false unless resource
51
+
52
+ page_number = path.match(/([1-9]+)$/)[0] rescue nil
53
+
54
+ return false unless @ruhoh.collections.exist?(resource)
55
+ return false if page_number.to_i.zero?
56
+
57
+ collection = @ruhoh.collection(resource)
58
+ config = collection.config["paginator"] || {}
59
+
60
+ view = @ruhoh.master_view({"resource" => resource})
61
+ view.page_data = {
62
+ "layout" => config["layout"],
63
+ "current_page" => page_number
64
+ }
65
+ view
66
+ end
67
+
68
+ def favicon
69
+ [200, {'Content-Type' => 'image/x-icon'}, ['']]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ module Ruhoh::Resources::Partials
2
+ class Model
3
+ include Ruhoh::Base::Modelable
4
+
5
+ def process
6
+ return File.open(@pointer['realpath'], 'r:UTF-8') { |f|
7
+ return f.read
8
+ }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Ruhoh::Resources::Stylesheets
2
+ class Collection
3
+ include Ruhoh::Base::Collectable
4
+
5
+ def url_endpoint
6
+ "assets/#{ resource_name }"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,45 @@
1
+ module Ruhoh::Resources::Stylesheets
2
+ class CollectionView < SimpleDelegator
3
+ attr_accessor :_cache
4
+
5
+ def initialize(collection)
6
+ super(collection)
7
+ @_cache = {}
8
+ end
9
+
10
+ # Load Stylesheets as defined within the given sub_context
11
+ #
12
+ # Example:
13
+ # {{# stylesheets.load }}
14
+ # global.css
15
+ # custom.css
16
+ # {{/ stylesheets.load }}
17
+ # (stylesheets are separated by newlines)
18
+ #
19
+ # This is a convenience method that will automatically create link tags
20
+ # with respect to ruhoh's internal URL generation mechanism; e.g. base_path
21
+ #
22
+ # @returns[String] HTML link tags for given stylesheets
23
+ def load(sub_context)
24
+ stylesheets = sub_context.split("\n").map{ |s| s.gsub(/\s/, '') }.delete_if(&:empty?)
25
+ stylesheets.map { |name|
26
+ "<link href='#{make_url(name)}' type='text/css' rel='stylesheet' media='all'>"
27
+ }.join("\n")
28
+ end
29
+
30
+ protected
31
+
32
+ def make_url(name)
33
+ return name if name =~ /^(http:|https:)?\/\//i
34
+
35
+ path = if @_cache[name]
36
+ @_cache[name]
37
+ else
38
+ @_cache[name] = name
39
+ "#{name}?#{rand()}"
40
+ end
41
+
42
+ ruhoh.to_url(url_endpoint, path)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ module Ruhoh::Resources::Stylesheets
2
+ class Compiler
3
+ include Ruhoh::Base::CompilableAsset
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ module Ruhoh::Resources::Theme
2
+ class Collection
3
+ include Ruhoh::Base::Collectable
4
+
5
+ def url_endpoint
6
+ "/assets"
7
+ end
8
+
9
+ # noop
10
+ def dictionary
11
+ {}
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,54 @@
1
+ module Ruhoh::Resources::Theme
2
+ class Compiler
3
+ include Ruhoh::Base::Compilable
4
+
5
+ def run
6
+ copy
7
+ end
8
+
9
+ # Copies all assets over to the compiled site.
10
+ # Note the compiled assets are namespaced at /assets/
11
+ def copy
12
+ collection = @collection
13
+ unless @collection.paths?
14
+ Ruhoh::Friend.say { yellow "#{collection.resource_name.capitalize}: directory not found - skipping." }
15
+ return
16
+ end
17
+
18
+ Ruhoh::Friend.say { cyan "Theme: ('#{collection.resource_name}' copying non-resource files)" }
19
+
20
+ theme = Ruhoh::Utils.url_to_path(@collection.url_endpoint, @ruhoh.paths.compiled)
21
+ FileUtils.mkdir_p theme
22
+
23
+ self.files.each do |file|
24
+ original_file = File.join(@ruhoh.paths.theme, file)
25
+ compiled_file = File.join(theme, file)
26
+ FileUtils.mkdir_p File.dirname(compiled_file)
27
+ FileUtils.cp_r original_file, compiled_file
28
+ Ruhoh::Friend.say { green " > #{file}" }
29
+ end
30
+ end
31
+
32
+ # Returns list of all files from the theme to be compiled.
33
+ # @returns[Array] relative filepaths
34
+ def files
35
+ FileUtils.cd(@ruhoh.paths.theme) {
36
+ return Dir["**/*"].select { |filepath|
37
+ is_valid_asset?(filepath)
38
+ }
39
+ }
40
+ end
41
+
42
+ # Checks a given asset filepath against any user-defined exclusion rules in theme.yml
43
+ # Omit layouts, stylesheets, javascripts, media as they are handled by their respective resources.
44
+ # @returns[Boolean]
45
+ def is_valid_asset?(filepath)
46
+ return false unless File.exist? filepath
47
+ return false if FileTest.directory?(filepath)
48
+ return false if filepath.start_with?('.', 'layouts', 'stylesheets', 'javascripts', 'media')
49
+ excludes = Array(@collection.config['exclude']).map { |node| Regexp.new(node) }
50
+ excludes.each { |regex| return false if filepath =~ regex }
51
+ true
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,26 @@
1
+ module Ruhoh::Resources::Widgets
2
+ class Collection
3
+ include Ruhoh::Base::Collectable
4
+
5
+ def initialize(ruhoh)
6
+ @ruhoh = ruhoh
7
+ @path = File.join(@ruhoh.paths.base, "widgets")
8
+ @system_path = File.join(@ruhoh.paths.system, "widgets")
9
+ end
10
+
11
+ def url_endpoint
12
+ "/assets/widgets"
13
+ end
14
+
15
+ # @returns[Array] registered widget names.
16
+ def widgets
17
+ names = []
18
+ paths.each do |path|
19
+ FileUtils.cd(path) {
20
+ names += Dir["*"]
21
+ }
22
+ end
23
+ names.uniq
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ module Ruhoh::Resources::Widgets
2
+ class CollectionView < SimpleDelegator
3
+
4
+ def widget(name)
5
+ page_config = (master.page_data["widgets"][name] || {}) rescue {}
6
+ widget_config = (config[name] || {}).merge(page_config)
7
+ return '' if widget_config['enable'].to_s == 'false'
8
+
9
+ model = find("#{ name }/#{ (widget_config['use'] || "default") }")
10
+ return '' unless model
11
+
12
+ view = ruhoh.master_view({})
13
+
14
+ # merge the config.yml data into the inline layout data.
15
+ # Note this is reversing the normal hierarchy
16
+ # in that inline should always override config level.
17
+ # However the inline in this case is set as implementation defaults
18
+ # and meant to be overridden by user specific data.
19
+ view.render(model.content, {
20
+ "this_config" => model.data.merge(widget_config),
21
+ "this_path" => ruhoh.to_url(url_endpoint, name)
22
+ })
23
+ end
24
+
25
+ def method_missing(name, *args, &block)
26
+ __getobj__.widgets.include?(name.to_s) ? widget(name.to_s) : super
27
+ end
28
+
29
+ def respond_to?(method)
30
+ __getobj__.widgets.include?(method.to_s) ? true : super
31
+ end
32
+
33
+ end
34
+ end