middleman-apps 0.1.0 → 0.2.0

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +2 -1
  4. data/Gemfile +4 -0
  5. data/{LICENSE.txt → LICENSE} +0 -0
  6. data/README.md +166 -40
  7. data/features/e_asset_hash.feature +17 -0
  8. data/features/{directory_indexes.feature → e_directory_indexes.feature} +14 -16
  9. data/features/e_relative_assets.feature +17 -0
  10. data/features/f_code_reloading.feature +134 -0
  11. data/features/f_metadata.feature +25 -0
  12. data/features/{not_found_rack.feature → f_not_found.feature} +12 -22
  13. data/features/f_options.feature +39 -0
  14. data/features/step_definitions/capybara_steps.rb +18 -0
  15. data/features/step_definitions/mechanize_steps.rb +19 -0
  16. data/features/step_definitions/rack_app_steps.rb +4 -2
  17. data/features/support/aruba.rb +22 -0
  18. data/features/support/env.rb +0 -14
  19. data/features/support/helpers.rb +11 -0
  20. data/features/support/mechanize.rb +32 -0
  21. data/features/support/poltegeist.rb +35 -0
  22. data/features/v_activating.feature +74 -0
  23. data/features/v_building.feature +31 -0
  24. data/features/v_inheriting_from.feature +38 -0
  25. data/fixtures/asset_hash/apps/ignored_app.rb +10 -0
  26. data/fixtures/asset_hash/apps/test_app.rb +11 -0
  27. data/fixtures/asset_hash/config.rb +2 -0
  28. data/fixtures/asset_hash/source/error.html.erb +2 -0
  29. data/fixtures/{complex-app → asset_hash}/source/index.html.erb +0 -0
  30. data/fixtures/asset_hash/source/layouts/layout.erb +12 -0
  31. data/fixtures/asset_hash/source/layouts/page.erb +6 -0
  32. data/fixtures/asset_hash/source/stylesheets/style.css.scss.erb +5 -0
  33. data/fixtures/dir_index/apps/ignored_app.rb +10 -0
  34. data/fixtures/dir_index/apps/test_app.rb +10 -0
  35. data/fixtures/dir_index/config.rb +2 -0
  36. data/fixtures/{simple-app → dir_index}/source/index.html.erb +0 -0
  37. data/fixtures/mount_path/apps/test_app.rb +10 -0
  38. data/fixtures/mount_path/config.rb +1 -0
  39. data/fixtures/{complex-app/build/index.html → mount_path/source/index.html.erb} +0 -0
  40. data/fixtures/real_world/apps/awesome_api.rb +40 -0
  41. data/fixtures/{complex-app → real_world}/apps/child_app.rb +15 -2
  42. data/fixtures/{complex-app/apps/test_app.rb → real_world/apps/ignored_app.rb} +2 -2
  43. data/fixtures/real_world/apps/no_namespace.rb +8 -0
  44. data/fixtures/real_world/apps/test_app.rb +16 -0
  45. data/fixtures/real_world/config.rb +13 -0
  46. data/fixtures/real_world/source/apps.html.erb +14 -0
  47. data/fixtures/real_world/source/custom.html.erb +1 -0
  48. data/fixtures/{simple-app/build/index.html → real_world/source/index.html.erb} +0 -0
  49. data/fixtures/real_world/source/layouts/_partial.erb +1 -0
  50. data/fixtures/real_world/source/layouts/layout.erb +11 -0
  51. data/fixtures/real_world/source/layouts/page.erb +6 -0
  52. data/fixtures/real_world/source/layouts/test.html.markdown.erb +3 -0
  53. data/fixtures/relative_assets/apps/ignored_app.rb +10 -0
  54. data/fixtures/relative_assets/apps/test_app.rb +11 -0
  55. data/fixtures/relative_assets/config.rb +2 -0
  56. data/fixtures/relative_assets/source/error.html.erb +2 -0
  57. data/fixtures/relative_assets/source/index.html.erb +2 -0
  58. data/fixtures/relative_assets/source/layouts/layout.erb +12 -0
  59. data/fixtures/relative_assets/source/layouts/page.erb +6 -0
  60. data/fixtures/relative_assets/source/stylesheets/style.css.scss.erb +5 -0
  61. data/fixtures/simple/apps/ignored_app.rb +10 -0
  62. data/fixtures/simple/apps/test_app.rb +10 -0
  63. data/fixtures/simple/config.rb +1 -0
  64. data/fixtures/simple/source/index.html.erb +2 -0
  65. data/lib/middleman/apps.rb +26 -7
  66. data/lib/middleman/apps/base.rb +71 -15
  67. data/lib/middleman/apps/extension.rb +34 -158
  68. data/lib/middleman/apps/version.rb +2 -1
  69. data/lib/middleman/sitemap/app_collection.rb +225 -0
  70. data/lib/middleman/sitemap/app_resource.rb +61 -0
  71. metadata +77 -31
  72. data/features/activation.feature +0 -53
  73. data/features/build.feature +0 -20
  74. data/features/child_app.feature +0 -18
  75. data/features/complex_app.feature +0 -66
  76. data/features/not_found_server.feature +0 -8
  77. data/features/verbose.feature +0 -23
  78. data/fixtures/complex-app/apps/awesome_api.rb +0 -11
  79. data/fixtures/complex-app/build/error.html +0 -1
  80. data/fixtures/complex-app/config.rb +0 -1
  81. data/fixtures/simple-app/apps/test_app.rb +0 -8
  82. data/fixtures/simple-app/build/error.html +0 -1
  83. data/fixtures/simple-app/config.rb +0 -1
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module OtherNamespace
4
+ # Test application fixture
5
+ class IgnoredApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'sinatra'
2
+
3
+ module AssetHash
4
+ # Test application fixture
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ str = params[:test] ? 'pass' : 'fail'
8
+ middleman_layout :page, locals: { str: str }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ activate :asset_hash
2
+ activate :apps, not_found: 'error.html', namespace: 'AssetHash'
@@ -0,0 +1,2 @@
1
+ <h1><%= 404 %> <span>Error</span> - Not Found!</h1>
2
+
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <%= stylesheet_link_tag "style" %>
6
+ <title><%= page_classes %></title>
7
+ </head>
8
+ <body>
9
+ <%= yield %>
10
+ <h3>via layout</h3>
11
+ </body>
12
+ </html>
@@ -0,0 +1,6 @@
1
+ <% wrap_layout :layout do %>
2
+ <h1><%= current_page.title %></h1>
3
+ <%= str %>
4
+ <%= partial 'layouts/partial' %>
5
+ <h3>via page</h3>
6
+ <% end %>
@@ -0,0 +1,5 @@
1
+ h1 {
2
+ span {
3
+ display: <%= :none %>;
4
+ }
5
+ }
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module OtherNamespace
4
+ # Test application fixture
5
+ class IgnoredApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module DirectoryIndex
4
+ # Test application fixture
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ activate :directory_indexes
2
+ activate :apps, not_found: 'error.html', namespace: 'DirectoryIndex'
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module MountPath
4
+ # Test application fixture
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ activate :apps, mount_path: '///a/b//c////d', namespace: 'MountPath'
@@ -0,0 +1,40 @@
1
+ require 'middleman/apps/base'
2
+
3
+ module OtherNamespace
4
+ # Child app that tests specifying a specific namespace/class
5
+ # for a single URL endpoint
6
+ class AwesomeAPI < Middleman::Apps::Base
7
+ post '/' do
8
+ status 201
9
+ '201 Created'
10
+ end
11
+
12
+ get '/ping' do
13
+ 'pong'
14
+ end
15
+
16
+ add_routes_to_metadata
17
+ set_metadata :arbitrary, 'defined'
18
+ set_metadata :title, 'Awesome API'
19
+ set_metadata :description, <<-MARKDOWN
20
+ ## Awesome API v3
21
+
22
+ A markdown formatted description for this `Awesome API` can be provided
23
+ here. It, also, serves as a simple documentation for anyone reading your
24
+ code later.
25
+
26
+ You can even set this method from outside this class like this:
27
+
28
+ description = File.read('long_docs_for_simple_api.md')
29
+ OtherNamespace::AwesomeAPI.set :page_description, description
30
+
31
+ Enough now!
32
+ MARKDOWN
33
+
34
+ get '/metadata' do
35
+ metadata.map do |key, val|
36
+ "#{key} => #{val}"
37
+ end.join("\n")
38
+ end
39
+ end
40
+ end
@@ -1,6 +1,6 @@
1
1
  require 'middleman/apps/base'
2
2
 
3
- module ComplexApp
3
+ module RealWorld
4
4
  # Child app that inherits from Middleman::Apps::BaseApp (which in turn
5
5
  # inherits from Sinatra::Base) for additional features, such as:
6
6
  # - error pages will be same as your main middleman static app
@@ -9,7 +9,20 @@ module ComplexApp
9
9
  #
10
10
  class ChildApp < ::Middleman::Apps::Base
11
11
  get '/' do
12
- 'hello'
12
+ "hello #{named} world"
13
+ end
14
+
15
+ get '/test' do
16
+ middleman_layout :test
17
+ end
18
+
19
+ get '/page/:str' do
20
+ str = params[:str] || 'testing..'
21
+ middleman_layout :page, locals: { str: str }
22
+ end
23
+
24
+ def named
25
+ 'my'
13
26
  end
14
27
  end
15
28
  end
@@ -1,9 +1,9 @@
1
1
  require 'sinatra'
2
2
 
3
- module ComplexApp
3
+ module RealWorld
4
4
  module SomeNamespace
5
5
  # Child app that is used by option: namespace
6
- class TestApp < Sinatra::Base
6
+ class IgnoredApp < Sinatra::Base
7
7
  get '/' do
8
8
  params[:test] ? 'pass' : 'fail'
9
9
  end
@@ -0,0 +1,8 @@
1
+ require 'sinatra'
2
+
3
+ # A child app without any namespace attached
4
+ class NoNamespaceApp < Sinatra::Base
5
+ get '/' do
6
+ 'pass'
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'middleman/apps/base'
2
+
3
+ module RealWorld
4
+ # Child app that is used by option: namespace
5
+ class TestApp < Middleman::Apps::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+
10
+ get '/metadata' do
11
+ metadata.map do |key, val|
12
+ "#{key} => #{val}"
13
+ end.join("\n")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ activate :apps, not_found: 'custom.html',
2
+ namespace: 'RealWorld',
3
+ map: {
4
+ test_app: 'test',
5
+ awesome_api: {
6
+ url: 'api',
7
+ class: 'OtherNamespace::AwesomeAPI'
8
+ },
9
+ no_namespace: {
10
+ url: '/no-name',
11
+ class: 'NoNamespaceApp'
12
+ }
13
+ }
@@ -0,0 +1,14 @@
1
+ <section class="articles index">
2
+ <h3 class="title">Available apps:</h3>
3
+ <ul>
4
+ <% apps_list.each_with_index do |app, i| %>
5
+ <article>
6
+ <h2 class="title">
7
+ <%= link_to app.title, app.url %>
8
+ </h2>
9
+ <p><%= app.description %></p>
10
+ </article>
11
+ <% end %>
12
+ </ul>
13
+ </section>
14
+
@@ -0,0 +1 @@
1
+ <h1><%= 404 %> Custom Not Found!</h1>
@@ -0,0 +1 @@
1
+ <h3>rendered partial</h3>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title><%= page_classes %></title>
6
+ </head>
7
+ <body>
8
+ <%= yield %>
9
+ <h3>via layout</h3>
10
+ </body>
11
+ </html>
@@ -0,0 +1,6 @@
1
+ <% wrap_layout :layout do %>
2
+ <h1><%= current_page.title %></h1>
3
+ <%= str %>
4
+ <%= partial 'layouts/partial' %>
5
+ <h3>via page</h3>
6
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= '<h1>Heading L1</h1>' %>
2
+
3
+ ## Heading L2
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module OtherNamespace
4
+ # Test application fixture
5
+ class IgnoredApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'sinatra'
2
+
3
+ module AssetHash
4
+ # Test application fixture
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ str = params[:test] ? 'pass' : 'fail'
8
+ middleman_layout :page, locals: { str: str }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ activate :relative_assets
2
+ activate :apps, not_found: 'error.html', namespace: 'RelativeAssets'
@@ -0,0 +1,2 @@
1
+ <h1><%= 404 %> <span>Error</span> - Not Found!</h1>
2
+
@@ -0,0 +1,2 @@
1
+ <h1>Middleman</h1>
2
+
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <%= stylesheet_link_tag "style" %>
6
+ <title><%= page_classes %></title>
7
+ </head>
8
+ <body>
9
+ <%= yield %>
10
+ <h3>via layout</h3>
11
+ </body>
12
+ </html>
@@ -0,0 +1,6 @@
1
+ <% wrap_layout :layout do %>
2
+ <h1><%= current_page.title %></h1>
3
+ <%= str %>
4
+ <%= partial 'layouts/partial' %>
5
+ <h3>via page</h3>
6
+ <% end %>
@@ -0,0 +1,5 @@
1
+ h1 {
2
+ span {
3
+ display: <%= :none %>;
4
+ }
5
+ }
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module OtherNamespace
4
+ # Test application fixture
5
+ class IgnoredApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'sinatra'
2
+
3
+ module Simple
4
+ # Test application fixture
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ params[:test] ? 'pass' : 'fail'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ activate :apps, namespace: 'Simple'
@@ -0,0 +1,2 @@
1
+ <h1>Middleman</h1>
2
+
@@ -6,6 +6,7 @@ require 'middleman/apps/extension'
6
6
  # Register this extension with the name of `apps`
7
7
  Middleman::Extensions.register :apps, Middleman::Apps::Extension
8
8
 
9
+ # Namespace for the Middleman project
9
10
  module Middleman
10
11
  # Base namespace for `middleman-apps` extension.
11
12
  #
@@ -23,12 +24,11 @@ module Middleman
23
24
 
24
25
  # Middleman app instance for reference to configuration, etc.
25
26
  #
26
- # @return [Middleman::Application] an instance of {Middleman::Application}
27
+ # @return [Middleman::Application] an instance of Middleman::Application
27
28
  # using configuration in {MIDDLEMAN_OPTIONS}
28
29
  #
29
30
  def self.middleman_app
30
31
  Middleman.setup_load_paths
31
-
32
32
  ::Middleman::Application.new do
33
33
  MIDDLEMAN_OPTIONS.each do |key, val|
34
34
  config[key] = val
@@ -43,10 +43,13 @@ module Middleman
43
43
  #
44
44
  # @see .rack_app `.rack_app` method which uses this internally
45
45
  #
46
- def self.within_extension(&block)
47
- app = middleman_app
46
+ def self.with_app_list(app = nil, &block)
47
+ app ||= middleman_app
48
48
  options = app.extensions[:apps].options.to_h
49
- Middleman::Apps::Extension.new(app, options).instance_eval(&block)
49
+ ex = Middleman::Apps::Extension.new(app, options)
50
+ app.sitemap.register_resource_list_manipulator(:child_apps, ex.collection)
51
+ app.sitemap.ensure_resource_list_updated!
52
+ block ? ex.collection.instance_eval(&block) : ex.collection
50
53
  end
51
54
 
52
55
  # Rack app comprising of the static (middleman) app with 404 pages, and
@@ -57,9 +60,25 @@ module Middleman
57
60
  #
58
61
  # @return [Rack::App] rack application configuration
59
62
  def self.rack_app
60
- within_extension do
61
- mount_child_apps(middleman_static_app)
63
+ with_app_list { mount_child_apps(middleman_static_app) }
64
+ end
65
+
66
+ # Find App Resource for the given class name
67
+ #
68
+ # @param [Class] klass - klass to search
69
+ # @return [Middleman::Sitemap::AppResource, nil] - found app resource if any
70
+ def self.find_app_resource_for(klass, app = nil)
71
+ Middleman::Sitemap::AppResource.find_by_klass(klass, app)
72
+ end
73
+
74
+ # Get content for the not found page as specified in options.
75
+ #
76
+ def self.not_found(rack_app = nil)
77
+ rack_app ||= middleman_app
78
+ path = with_app_list(rack_app) do
79
+ build_dir.join(find_resource(@options.not_found))
62
80
  end
81
+ path.exist? ? path.read : "Not found\n"
63
82
  end
64
83
  end
65
84
  end