middleman-apps 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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