serve 0.9.10 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/{History.txt → CHANGELOG.rdoc} +9 -0
  2. data/{License.txt → LICENSE} +1 -1
  3. data/{Quickstart.textile → QUICKSTART.rdoc} +61 -80
  4. data/{README.txt → README.rdoc} +10 -13
  5. data/Rakefile +11 -13
  6. data/VERSION +1 -0
  7. data/bin/serve +6 -0
  8. data/lib/serve.rb +2 -8
  9. data/lib/serve/application.rb +13 -6
  10. data/lib/serve/file_resolver.rb +48 -0
  11. data/lib/serve/handlers/dynamic_handler.rb +31 -21
  12. data/lib/serve/handlers/file_type_handler.rb +23 -32
  13. data/lib/serve/handlers/markdown_handler.rb +1 -1
  14. data/lib/serve/handlers/redirect_handler.rb +6 -5
  15. data/lib/serve/handlers/sass_handler.rb +4 -3
  16. data/lib/serve/rack.rb +57 -0
  17. data/lib/serve/rails.rb +4 -0
  18. data/lib/serve/rails/configuration.rb +69 -0
  19. data/lib/serve/rails/mount.rb +38 -0
  20. data/lib/serve/rails/routing.rb +25 -0
  21. data/lib/serve/rails/serve_controller.rb +52 -0
  22. data/lib/serve/response_cache.rb +170 -0
  23. data/lib/serve/version.rb +4 -9
  24. data/lib/serve/webrick/extensions.rb +80 -15
  25. data/lib/serve/webrick/server.rb +17 -0
  26. data/lib/serve/webrick/servlet.rb +19 -0
  27. data/rails/init.rb +6 -0
  28. data/spec/{serve_application_spec.rb → application_spec.rb} +5 -4
  29. data/spec/response_cache_spec.rb +248 -0
  30. data/spec/serve_spec.rb +1 -0
  31. data/spec/spec_helper.rb +10 -9
  32. metadata +51 -69
  33. data.tar.gz.sig +0 -0
  34. data/Manifest.txt +0 -44
  35. data/config/hoe.rb +0 -70
  36. data/config/requirements.rb +0 -17
  37. data/log/debug.log +0 -0
  38. data/script/destroy +0 -14
  39. data/script/generate +0 -14
  40. data/script/txt2html +0 -74
  41. data/setup.rb +0 -1585
  42. data/tasks/deployment.rake +0 -27
  43. data/tasks/environment.rake +0 -7
  44. data/tasks/rspec.rake +0 -21
  45. data/tasks/undefine.rake +0 -5
  46. data/tasks/website.rake +0 -17
  47. data/test_project/_layout.haml +0 -12
  48. data/test_project/erb/_footer.html.erb +0 -2
  49. data/test_project/erb/_layout.html.erb +0 -28
  50. data/test_project/erb/index.html.erb +0 -10
  51. data/test_project/haml/_footer.haml +0 -2
  52. data/test_project/haml/_layout.haml +0 -20
  53. data/test_project/haml/index.haml +0 -9
  54. data/test_project/test.haml +0 -3
  55. data/test_project/test.html.erb +0 -3
  56. data/test_project/view_helpers.rb +0 -5
  57. metadata.gz.sig +0 -0
@@ -1,7 +1,16 @@
1
+ == 0.10.0
2
+
3
+ * Added additional view helper methods and harmonized the API a bit [aiwilliams]
4
+ * Added support for using Serve as a Rails plugin [aiwilliams]
5
+ * Added support for rack [ntalbott]
6
+ * Dropped Hoe and Newgem in favor of Jeweler
7
+
1
8
  == 0.9.10 (October 25, 2008)
9
+
2
10
  * Updated to work with Haml 2.0.3. [jlong]
3
11
 
4
12
  == 0.9.9 (September 19, 2008)
13
+
5
14
  * Fixed ERB partial support. [jlong]
6
15
  * Added support for content_for blocks in ERB. [jlong]
7
16
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 John W. Long
1
+ Copyright (c) 2007-2009 John W. Long and Adam I. Williams
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,104 +1,91 @@
1
- h1. Getting Started with Serve
1
+ = Getting Started with Serve
2
2
 
3
3
 
4
+ <b>This is tutorial is incomplete. Help us finish it!</b>
5
+
4
6
  Serve is a rapid prototyping framework for Rails applications. It is designed to compliment Rails development and enforce a strict separation of concerns between designer and developer. Using Serve with Rails allows the designer to happily work in his own space creating an HTML prototype of the application, while the developer works on the Rails application and copies over HTML from the prototype as needed. This allows the designer to focus on presentation and flow while the developer can focus on the implementation.
5
7
 
6
8
  Let's have a look at how it all works.
7
9
 
8
10
 
9
- h3. Installation
11
+ == Installation
10
12
 
11
13
  To get started we need to download and install the Ruby gem for Serve:
12
14
 
13
- <pre>
14
- % sudo gem install serve
15
- </pre>
15
+ $ sudo gem install serve
16
16
 
17
17
  After we've done that it's probably a good idea to install a couple of additional gems so that Serve will play nicely with HAML, Markdown, and Textile:
18
18
 
19
- <pre>
20
- % sudo gem install haml Bluecloth Redcloth
21
- </pre>
19
+ $ sudo gem install haml Bluecloth Redcloth
22
20
 
23
21
 
24
- h3. Project Directory Structure
22
+ == Project Directory Structure
25
23
 
26
24
  Once we have everything installed the next thing to do is setup the project directory. I like to setup my projects with the following directory structure:
27
25
 
28
- <pre>
29
- artwork # Logos and other identity design files go here
30
- mockups # Fireworks or Photoshop web app mockups go here
31
- prototype # The HTML prototype for the web app goes here
32
- application # The actual Rails application is here
33
- </pre>
26
+ artwork :: Logos and other identity design files go here
27
+ mockups :: Fireworks or Photoshop web app mockups go here
28
+ prototype :: The HTML prototype for the web app goes here
29
+ application :: The actual Rails application is here
34
30
 
35
31
  Let's go ahead and create the directory for the prototype:
36
32
 
37
- % mkdir prototype
33
+ $ mkdir prototype
38
34
 
39
35
  Rails apps generally store images, javascripts, and stylesheets in the top level directories by the same name. Let's go ahead and mirror those directories for our prototype:
40
36
 
41
- <pre>
42
- % cd prototype
43
- % mkdir images
44
- % mkdir javascripts
45
- % mkdir stylesheets
46
- </pre>
47
-
37
+ $ cd prototype
38
+ $ mkdir images
39
+ $ mkdir javascripts
40
+ $ mkdir stylesheets
48
41
 
49
- h3. Creating Our First Screen
42
+ == Creating Our First Screen
50
43
 
51
44
  Now that we have the prototype directory set up, let's create our first page so that you can get a feel for how Serve works. This will be a simple HTML login page for our application.
52
45
 
53
46
  Insert the following HTML into an file named "login.html.erb":
54
47
 
55
- <pre><code>
56
- <form action="/dashboard/" method="put">
57
- <p>
58
- <label for="username">Username</label>
59
- <input type="text" name="username" id="username" />
60
- </p>
61
- <p>
62
- <label for="password">Password</label>
63
- <input type="password" name="password" id="password" />
64
- </p>
65
- <p>
66
- <input type="submit" value="Login" />
67
- </p>
68
- </form>
69
- </code></pre>
70
-
71
-
72
- h3. Starting Serve
48
+ <form action="/dashboard/" method="put">
49
+ <p>
50
+ <label for="username">Username</label>
51
+ <input type="text" name="username" id="username" />
52
+ </p>
53
+ <p>
54
+ <label for="password">Password</label>
55
+ <input type="password" name="password" id="password" />
56
+ </p>
57
+ <p>
58
+ <input type="submit" value="Login" />
59
+ </p>
60
+ </form>
61
+
62
+
63
+ == Starting Serve
73
64
 
74
65
  To view our login page in a Web browser, we need to start up Serve in the directory where we are building the prototype:
75
66
 
76
- <pre>
77
- % cd prototype
78
- % serve
79
- [2008-02-23 15:19:05] INFO WEBrick 1.3.1
80
- [2008-02-23 15:19:05] INFO ruby 1.8.6 (2007-09-24) [universal-darwin9.0]
81
- [2008-02-23 15:19:05] INFO Serve::Server#start: pid=5087 port=4000
82
- ...
83
- </pre>
67
+ % cd prototype
68
+ % serve
69
+ [2008-02-23 15:19:05] INFO WEBrick 1.3.1
70
+ [2008-02-23 15:19:05] INFO ruby 1.8.6 (2007-09-24) [universal-darwin9.0]
71
+ [2008-02-23 15:19:05] INFO Serve::Server#start: pid=5087 port=4000
72
+ ...
84
73
 
85
74
  Once you execute the `serve` command it will launch a mini Web server for the prototype and will output a noisy log of any activity. (To stop the command at any point simply switch back to the command line and press Ctrl+C.)
86
75
 
87
76
  By default the `serve` command automatically serves files from the directory that it is started in over port 4000 on your local machine. To access the the prototype in your Web browser go to:
88
77
 
89
- http://localhost:4000
78
+ http://localhost:4000
90
79
 
91
80
  You should see a simple directory listing. It will look similar to this:
92
81
 
93
- <pre>
94
- Name Last modified Size
95
- ----------------------------------------------------------
96
- Parent Directory 2008/02/23 15:35 -
97
- images/ 2008/02/23 15:35 -
98
- javascripts/ 2008/02/23 15:35 -
99
- login.html.erb 2008/02/23 15:36 346
100
- stylesheets/ 2008/02/23 15:35 -
101
- </pre>
82
+ Name Last modified Size
83
+ ----------------------------------------------------------
84
+ Parent Directory 2008/02/23 15:35 -
85
+ images/ 2008/02/23 15:35 -
86
+ javascripts/ 2008/02/23 15:35 -
87
+ login.html.erb 2008/02/23 15:36 346
88
+ stylesheets/ 2008/02/23 15:35 -
102
89
 
103
90
  Now navigate to the following URL:
104
91
 
@@ -107,23 +94,21 @@ Now navigate to the following URL:
107
94
  You should see the contents of the login page. Note that Serve allows you to refer to pages without their extension. This allows you to use URLs in your documents that correspond well to the URLs that Rails uses by default.
108
95
 
109
96
 
110
- h3. Layouts
97
+ == Layouts
111
98
 
112
99
  One thing to note about the source that I gave you for the login page. I intentionally left out the <html>, <head>, and <body> tags because they belong a layout---not the source file. Let's go ahead and create that layout now.
113
100
 
114
101
  Insert the following HTML into a file named "_layout.html.erb" in the root directory of your prototype:
115
102
 
116
- <pre><code>
117
- <html>
118
- <head>
119
- <title><%= @title %></title>
120
- </head>
121
- <body>
122
- <h1><%= @title %>/h1>
123
- <%= yield %>
124
- </body>
125
- </html>
126
- </code></pre>
103
+ <html>
104
+ <head>
105
+ <title><%= @title %></title>
106
+ </head>
107
+ <body>
108
+ <h1><%= @title %>/h1>
109
+ <%= yield %>
110
+ </body>
111
+ </html>
127
112
 
128
113
  This layout includes a small amount of ERB(Embedded Ruby) to indicate the title of the web page and to insert the content of the page at the appropriate point.
129
114
 
@@ -131,18 +116,14 @@ Embedded Ruby is delineated with the opening and closing sequence <% and %> resp
131
116
 
132
117
  We need to make one small change to our login page before continuing. Insert the following line at the top of login.html.erb file:
133
118
 
134
- <pre>
135
- <% @title = "Login" %>
136
- </pre>
119
+ <% @title = "Login" %>
137
120
 
138
121
  This will set the @title variable for the login page. Now, switch back to your Web browser and navigate to:
139
122
 
140
- <pre>
141
- http://localhost:4000/login/
142
- </pre>
123
+ http://localhost:4000/login/
143
124
 
144
125
  The page should now have a title and heading that both read "Login".
145
126
 
146
- h3. Content For
127
+ == Content For
147
128
 
148
- h3. Partials
129
+ == Partials
@@ -1,9 +1,9 @@
1
1
  == Serve
2
2
 
3
- Serve is a small Ruby script that makes it easy to start up a WEBrick server
4
- in any directory. Serve is ideal for HTML prototyping and simple file sharing.
5
- If the haml, redcloth, and bluecloth gems are installed serve can handle Haml,
6
- Sass, Textile, and Markdown (in addition to HTML and ERB).
3
+ Serve is a small web server (based on WEBrick) that makes it easy to serve ERB
4
+ or HAML from any directory. Serve is an ideal tool for building HTML
5
+ prototypes of Rails applications. Serve can also handle SASS, Textile, and
6
+ Markdown if the appropriate gems are installed.
7
7
 
8
8
 
9
9
  === Usage
@@ -61,7 +61,9 @@ redirect :: Redirects to the URL contained in the document
61
61
 
62
62
  == View Helpers
63
63
 
64
- If you drop a file called view_helpers.rb in the root of a project, you can define custom helpers for your Haml and ERB views. Just declare the ViewHelpers module and begin declaring your helpers:
64
+ If you drop a file called view_helpers.rb in the root of a project, you can
65
+ define custom helpers for your Haml and ERB views. Just declare the
66
+ ViewHelpers module and begin declaring your helpers:
65
67
 
66
68
  module ViewHelpers
67
69
  def custom_method
@@ -95,11 +97,6 @@ All development now takes place on GitHub:
95
97
 
96
98
  === License
97
99
 
98
- Serve is released under the MIT license and is copyright (c) 2006-2008
99
- John W. Long. A copy of the MIT license can be found in the License.txt file.
100
-
101
-
102
- Enjoy!
103
-
104
- --
105
- John Long :: http://wiseheartdesign.com
100
+ Serve is released under the MIT license and is copyright (c) 2007-2009
101
+ John W. Long and Adam I. Williams. A copy of the MIT license can be found in
102
+ the LICENSE file.
data/Rakefile CHANGED
@@ -1,13 +1,11 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
5
-
6
- undefine_task %w(
7
- default
8
- test
9
- test_deps
10
- config_hoe
11
- )
12
-
13
- task :default => :spec
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ load 'tasks/jeweler.rake'
5
+ load 'tasks/rdoc.rake'
6
+ load 'tasks/rspec.rake'
7
+ load 'tasks/undefine.rake'
8
+
9
+ #Dir['tasks/**/*.rake'].each { |rake| load rake }
10
+
11
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.10.0
data/bin/serve CHANGED
@@ -1,10 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
  lib = File.dirname(__FILE__) + '/../lib'
3
3
  require 'rubygems'
4
+
5
+ gem 'activesupport'
6
+ require 'active_support'
7
+
4
8
  if File.file?(lib + '/serve/version.rb')
5
9
  $LOAD_PATH << lib
6
10
  else
7
11
  gem 'serve'
8
12
  end
9
13
  require 'serve'
14
+ require 'serve/application'
15
+
10
16
  Serve::Application.run
@@ -1,7 +1,5 @@
1
- require 'webrick'
2
1
  require 'serve/version'
3
- require 'serve/application'
4
- require 'serve/webrick/extensions'
2
+ require 'serve/file_resolver'
5
3
  require 'serve/handlers/file_type_handler'
6
4
  require 'serve/handlers/textile_handler'
7
5
  require 'serve/handlers/markdown_handler'
@@ -9,8 +7,4 @@ require 'serve/handlers/dynamic_handler'
9
7
  require 'serve/handlers/sass_handler'
10
8
  require 'serve/handlers/email_handler'
11
9
  require 'serve/handlers/redirect_handler'
12
-
13
- module Serve #:nodoc:
14
- class Server < ::WEBrick::HTTPServer #:nodoc:
15
- end
16
- end
10
+ require 'serve/response_cache'
@@ -1,3 +1,9 @@
1
+ require 'webrick'
2
+ require 'active_support'
3
+ require 'serve/webrick/extensions'
4
+ require 'serve/webrick/servlet'
5
+ require 'serve/webrick/server'
6
+
1
7
  module Serve
2
8
  class Application
3
9
  class InvalidArgumentsError < StandardError; end
@@ -53,8 +59,9 @@ module Serve
53
59
  program = File.basename($0)
54
60
  [
55
61
  "Usage:",
56
- " #{program} [port] [environment] [port]",
57
- " #{program} [address:port] [environment] [port]",
62
+ " #{program} [port] [environment] [directory]",
63
+ " #{program} [address:port] [environment] [directory]",
64
+ " #{program} [address] [port] [environment] [directory]",
58
65
  " #{program} [options]",
59
66
  " ",
60
67
  "Description:",
@@ -101,7 +108,7 @@ module Serve
101
108
  end
102
109
 
103
110
  def extract_port(args)
104
- args.delete(args.find {|a| /^\d\d\d+$/.match(a) }) || (rails_app? ? 3000 : 4000)
111
+ (args.delete(args.find {|a| /^\d\d\d*$/.match(a) }) || (rails_app? ? 3000 : 4000)).to_i
105
112
  end
106
113
 
107
114
  def extract_address(args)
@@ -131,12 +138,12 @@ module Serve
131
138
  end
132
139
 
133
140
  def run_server
134
- server = Serve::Server.new(
141
+ extensions = Serve::WEBrick::Server.register_handlers
142
+ server = Serve::WEBrick::Server.new(
135
143
  :Port => options[:port],
136
144
  :BindAddress => options[:address],
137
145
  :DocumentRoot => options[:root],
138
- :DirectoryIndex => %w(index.html index.erb index.html.erb index.rhtml index.haml index.html.haml index.txt index.text index.textile index.markdown index.email index.redirect),
139
- :AppendExtensions => %w(html txt text haml erb rhtml html.erb html.haml textile markdown email redirect)
146
+ :DirectoryIndex => %w(index.html index.rhtml index.txt index.text) + extensions.collect {|ext| "index.#{ext}"}
140
147
  )
141
148
  trap("INT") { server.shutdown }
142
149
  server.start
@@ -0,0 +1,48 @@
1
+ require 'active_support'
2
+
3
+ module Serve
4
+ mattr_accessor :file_resolver
5
+
6
+ class FileResolver
7
+ cattr_accessor :alternate_extensions
8
+ self.alternate_extensions = %w(html txt text haml erb rhtml html.erb html.haml textile markdown email redirect)
9
+
10
+ def resolve(root, path)
11
+ return nil if path.nil?
12
+ path = File.join(path) # path may be array
13
+ return nil if path =~ /\.\./
14
+ path = path.sub(%r{/\Z}, '')
15
+ if path =~ /\.css\Z/ && !File.file?(File.join(root, path))
16
+ sass_path = path.sub(/\.css\Z/, '.sass')
17
+ sass_path if File.file?(File.join(root, sass_path))
18
+ elsif File.directory?(File.join(root, path))
19
+ resolve(root, File.join(path, 'index'))
20
+ else
21
+ resolve_with_extension(root, path)
22
+ end
23
+ end
24
+
25
+ def resolve_with_extension(root, path)
26
+ full_path = File.join(root, path)
27
+ if File.file?(full_path)
28
+ path
29
+ else
30
+ if extension = find_extension(alternate_extensions, full_path)
31
+ "#{path}.#{extension}"
32
+ end
33
+ end
34
+ end
35
+
36
+ def find_extension(extensions_to_try, full_path)
37
+ extensions_to_try.find do |ext|
38
+ File.file?("#{full_path}.#{ext}")
39
+ end
40
+ end
41
+ end
42
+
43
+ self.file_resolver = FileResolver.new
44
+
45
+ def self.resolve_file(root, path)
46
+ file_resolver.resolve(root, path)
47
+ end
48
+ end
@@ -1,24 +1,15 @@
1
1
  module Serve #:nodoc:
2
- class Handler < FileTypeHandler #:nodoc:
2
+ class DynamicHandler < FileTypeHandler #:nodoc:
3
3
  extension 'erb', 'html.erb', 'rhtml', 'haml', 'html.haml'
4
4
 
5
- def process(req, res)
6
- class << req
7
- alias headers header
8
- end
9
- res['content-type'] = content_type
10
- res.body = parse(req, res)
5
+ def process(request, response)
6
+ response.headers['content-type'] = content_type
7
+ response.body = parse(request, response)
11
8
  end
12
9
 
13
- def parse(req, res)
14
- context = Context.new(req, res)
15
- view_helpers_file_path = Dir.pwd + '/view_helpers.rb'
16
- if File.file?(view_helpers_file_path)
17
- (class << context; self end).module_eval(File.read(view_helpers_file_path))
18
- class << context
19
- include ViewHelpers
20
- end
21
- end
10
+ def parse(request, response)
11
+ context = Context.new(@root_path, request, response)
12
+ install_view_helpers(context)
22
13
  parser = Parser.new(context)
23
14
  context.content << parser.parse_file(@script_filename)
24
15
  layout = find_layout_for(@script_filename)
@@ -30,7 +21,7 @@ module Serve #:nodoc:
30
21
  end
31
22
 
32
23
  def find_layout_for(filename)
33
- root = Dir.pwd
24
+ root = @root_path
34
25
  path = filename[root.size..-1]
35
26
  layout = nil
36
27
  until layout or path == "/"
@@ -44,6 +35,13 @@ module Serve #:nodoc:
44
35
  layout
45
36
  end
46
37
 
38
+ def install_view_helpers(context)
39
+ view_helpers_file_path = @root_path + '/view_helpers.rb'
40
+ if File.file?(view_helpers_file_path)
41
+ context.metaclass.module_eval(File.read(view_helpers_file_path) + "\ninclude ViewHelpers", view_helpers_file_path)
42
+ end
43
+ end
44
+
47
45
  module ERB #:nodoc:
48
46
  class Engine #:nodoc:
49
47
  def initialize(string, options = {})
@@ -98,8 +96,8 @@ module Serve #:nodoc:
98
96
  attr_accessor :content, :parser
99
97
  attr_reader :request, :response
100
98
 
101
- def initialize(req, res)
102
- @request, @response = req, res
99
+ def initialize(root_path, request, response)
100
+ @root_path, @request, @response = root_path, request, response
103
101
  @content = ''
104
102
  end
105
103
 
@@ -143,11 +141,23 @@ module Serve #:nodoc:
143
141
  instance_variable_get("@content_for_#{symbol}")
144
142
  end
145
143
  end
146
-
144
+
145
+ # View helper methods
146
+
147
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
148
+ def html_escape(s)
149
+ s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
150
+ end
151
+ alias h html_escape
152
+
147
153
  def set_content_for(symbol, value)
148
154
  instance_variable_set("@content_for_#{symbol}", value)
149
155
  end
150
156
 
157
+ def params
158
+ request.params
159
+ end
160
+
151
161
  # Render methods
152
162
 
153
163
  def render(options)
@@ -171,7 +181,7 @@ module Serve #:nodoc:
171
181
  path = File.dirname(parser.script_filename)
172
182
  if template =~ %r{^/}
173
183
  template = template[1..-1]
174
- path = Dir.pwd
184
+ path = @root_path
175
185
  end
176
186
  filename = template_filename(File.join(path, template), :partial => options.delete(:partial))
177
187
  if File.file?(filename)