sharp 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f14fd10ff351041624cc62b49aff7992cebeaf97
4
+ data.tar.gz: 68c4c6646f5a5b7602b4e65e85714553bbf2e511
5
+ SHA512:
6
+ metadata.gz: 48f0fb545bbae6faee5fe3e3d0918e07870debc8a14c897757555c32902386e6c21194c014d946669d12c6389227a3e5b70449b3ec4f64678dbec04ce5801e26
7
+ data.tar.gz: f4390112607d781dc05580b604b70856515263d55b26766ba3bde1a4de7026419e423b537cad1e2382dc0ae5075de79afbb400af2d11473990add70290de98ed
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm 1.9.3@sharp --create
1
+ rvm 2.0.0@sharp --create
data/TUTORIAL.md CHANGED
@@ -111,6 +111,8 @@ end
111
111
 
112
112
  What this means is if the request is a `GET` and the path is just `/`, call the `RootAction` to generate the response. We'll go into routing in more detail later, but for now, let's take a look at what the `RootAction` does.
113
113
 
114
+ The Sharp router is a [Rack::Router][rack-router], so for more information on how the router works, take a look at the docs for [Rack::Router][rack-router].
115
+
114
116
  # Actions
115
117
 
116
118
  So as we've seen, the router determines what action should respond to a request, and it is the job of an action to generate the response. If we look at the `RootAction`, which is defined in `app/actions/root_action.rb`, we see this:
@@ -122,6 +124,8 @@ end
122
124
 
123
125
  Huh, not much going on there, is there? That's because the default behavior of an action is to render the template that matches the name of the action. In this case, the action is `app/actions/root_action.rb`, so the template will be `templates/root.erb`. We'll cover actions in more depth later, but let's take a look at the template next.
124
126
 
127
+ But in case you are curious now, Sharp actions are [Rack::Action][rack-action], so you can read up on the documentation for [Rack::Action][rack-action] to find out more about what you can do with actions.
128
+
125
129
  # Templates
126
130
 
127
131
  There is what the template that is used to generate our response, `templates/root.erb`, looks like:
@@ -156,7 +160,7 @@ If you make a request to your application now, you'll see this:
156
160
 
157
161
  As you can see, the Ruby code contained between the `<%= -%>` was evaluated and the result what the current year, which was included into the response.
158
162
 
159
- One thing to notice is that you didn't have to restart your application, the changes were picked up automatically. This is because we used `shotgun` to start the application, which handles automatically reloading the application between requests for us.
163
+ One thing to notice is that you didn't have to restart your application, the changes were picked up automatically. This is because we used [shotgun][shotgun] to start the application, which handles automatically reloading the application between requests for us.
160
164
 
161
165
  One question you may be asking is where did the `<html>`, `<head>` and `<body>` tags come from? `templates/root.erb` just contains the snippet that ends up in the `<body>`. The answer is layouts, which is the topic we'll introduce next.
162
166
 
@@ -178,10 +182,119 @@ In many web application, the same `<head>` and basic structure within the `<body
178
182
 
179
183
  The tag `<%= render main -%>` is used to specify where the main content for the view should go. In fact, `render` is a generic method that you can use render any template from within another. `main` is a local variable that has the name of the template for the current view, which is `"root"` in this case.
180
184
 
185
+ # Views
186
+
187
+ In your application, you will most likely want to prepare some data in the action and make it available for rendering in the template. Taking our previous example of dynamically generating the year in the template, let's move the "logic" of generating that into the action. Edit `app/actions/root_action.rb` to look like this:
188
+
189
+ ``` ruby
190
+ class RootAction < ApplicationAction
191
+ def respond
192
+ @now = Time.now
193
+ view[:current_year] = @now.year
194
+ super
195
+ end
196
+ end
197
+ ```
198
+
199
+ Now we can modify the template to refer to it like this:
200
+
201
+ ``` erb
202
+ <h1>Hello, World</h1>
203
+ <footer>
204
+ &copy; Copyright <%= current_year -%>
205
+ </footer>
206
+ ```
207
+
208
+ Instance variables of the action are not accessible in the template, so the following would not work:
209
+
210
+ ``` erb
211
+ <h1>Hello, World</h1>
212
+ <footer>
213
+ &copy; Copyright <%= @now.year -%>
214
+ </footer>
215
+ ```
216
+
217
+ If you have data that you want available in the template, you must assign to the view, as we did with `current_year` in this example.
218
+
219
+ # Filters
220
+
221
+ Sharp actions support before filters, which are methods that execute before the `response` method. Using before filters, we could write the previous example like this:
222
+
223
+ ``` ruby
224
+ class RootAction < ApplicationAction
225
+ before_filter :load_year
226
+
227
+ def load_year
228
+ view[:current_year] = Time.now.year
229
+ end
230
+ end
231
+ ```
232
+
233
+ More common usage of before filter is to check for some pre-existing conditions and possibly render a response if they are not met:
234
+
235
+ ``` ruby
236
+ class RootAction < ApplicationAction
237
+ before_filter :require_password
238
+
239
+ def require_password
240
+ unless params[:password] == 'secret'
241
+ redirect_to '/access_denied'
242
+ end
243
+ end
244
+ end
245
+ ```
246
+
247
+ In this example, unless there is a param password equal to "secret", a redirect response will be generate, which prevents the action from calling the respond method and instead returns the redirect response.
248
+
249
+ # Custom Views
250
+
251
+ Another way to make data available to the templates in Sharp is by creating a view object that corresponds to your action. Create a file at `app/views/root_view.rb` that looks like this:
252
+
253
+ ``` ruby
254
+ class RootView < ApplicationView
255
+ def current_year
256
+ Time.now.year
257
+ end
258
+ end
259
+ ```
260
+
261
+ You can now return the `RootAction` to it's original default state:
262
+
263
+ ``` ruby
264
+ class RootAction < ApplicationAction
265
+ end
266
+ ```
267
+
268
+ If you hit the root URL in your browser or with curl now, you will see the same result. It is a good practice to build up a hierarchy of view objects and use inheritance to share functionality between related views.
269
+
270
+ The functionality for the view layer in Sharp is provided by [Curtain][curtain]. If you are looking for more information on what you can do with views, take a look at the documentation for [Curtain][curtain].
271
+
272
+ # Console
273
+
274
+ You can get an IRB console with your sharp application loaded by running this command:
275
+
276
+ $ sharp console
277
+
278
+ From within the console, there are a few methods to help you work with your Sharp application. First, if you would like to see what action a request would route to, you can do this:
279
+
280
+ > Sharp.route :get, '/'
281
+ => RootAction
282
+
283
+ In this example, `:get` is the request method and `'/'` is the path you want to check. As you can see, it returns the rack app that the route matches. It returns nil if there is no match.
284
+
285
+ You can also call an action through the route and get the rack response that it generates:
286
+
287
+ > Sharp.get '/'
288
+ => [200, {"Content-Type"=>"text/html", "Content-Length"=>"171"}, #<Rack::BodyProxy...
289
+
181
290
  # More To Come
182
291
 
183
292
  Sharp is still in the early stages of development, so keep checking back for updates on how to do more advanced things with Sharp.
184
293
 
185
294
  [jquery]: http://jquery.com
186
295
  [bootstrap]: http://twitter.github.com/bootstrap
187
- [bundler]: http://gembundler.com
296
+ [bundler]: http://gembundler.com
297
+ [rack-router]: https://github.com/pjb3/rack-router#usage
298
+ [rack-action]: https://github.com/pjb3/rack-action#usage
299
+ [curtain]: https://github.com/pjb3/curtain#usage
300
+ [shotgun]: https://github.com/rtomayko/shotgun
data/lib/sharp.rb CHANGED
@@ -4,6 +4,7 @@ require 'logger'
4
4
  require 'pathname'
5
5
  require 'rack-action'
6
6
  require 'rack-router'
7
+ require 'stringio'
7
8
  require 'yaml'
8
9
  require 'sharp/action'
9
10
  require 'sharp/config'
@@ -12,7 +13,6 @@ require 'sharp/generator'
12
13
  require 'sharp/version'
13
14
 
14
15
  module Sharp
15
-
16
16
  class << self
17
17
  attr_reader :app
18
18
  delegate :logger, :boot, :root, :router, :env, :config, :route, :get, :post, :put, :delete, :head, :to => :app
@@ -32,6 +32,18 @@ module Sharp
32
32
  end
33
33
 
34
34
  class Application
35
+ DEFAULT_ENV = {
36
+ "SCRIPT_NAME" => "",
37
+ "SERVER_NAME" => "localhost",
38
+ "SERVER_PORT" => "80",
39
+ "HTTP_HOST" => "localhost",
40
+ "HTTP_ACCEPT" => "*/*",
41
+ "HTTP_USER_AGENT" => "Sharp #{VERSION}",
42
+ "rack.input" => StringIO.new,
43
+ "rack.errors" => StringIO.new,
44
+ "rack.url_scheme" => "http"
45
+ }.freeze
46
+
35
47
  attr_reader :root, :router
36
48
 
37
49
  def self.boot(root)
@@ -40,13 +52,6 @@ module Sharp
40
52
  app
41
53
  end
42
54
 
43
- # Generates a Rack env Hash
44
- def self.env(method, path, env={})
45
- env.merge(
46
- 'REQUEST_METHOD' => method.to_s.upcase,
47
- 'PATH_INFO' => path)
48
- end
49
-
50
55
  def initialize(root)
51
56
  @root = Pathname.new(root)
52
57
  end
@@ -57,9 +62,7 @@ module Sharp
57
62
  else
58
63
  pre_initialization
59
64
  load_i18n
60
- load_lib
61
- load_models
62
- load_actions
65
+ load_load_path
63
66
  load_routes
64
67
  post_initialization
65
68
  finish_boot
@@ -70,6 +73,15 @@ module Sharp
70
73
  @router ||= Rack::Router.new
71
74
  end
72
75
 
76
+ # Generates a Rack env Hash
77
+ def self.env(method, path, query={}, env={})
78
+ DEFAULT_ENV.merge(env || {}).merge(
79
+ 'REQUEST_METHOD' => method.to_s.upcase,
80
+ 'PATH_INFO' => path,
81
+ 'QUERY_STRING' => query.to_param,
82
+ 'rack.input' => StringIO.new)
83
+ end
84
+
73
85
  def route(method, path, env={})
74
86
  router.match(self.class.env(method, path, env={}))
75
87
  end
@@ -131,7 +143,12 @@ module Sharp
131
143
  @config ||= Sharp::Config.new(env, Dir[root.join("config/*.yml")])
132
144
  end
133
145
 
146
+ def load_path
147
+ @load_path ||= %w[app/lib app/models app/actions app/views]
148
+ end
149
+
134
150
  protected
151
+
135
152
  def pre_initialization
136
153
  Dir.glob(root.join("app/initializers/pre/*.rb")) {|file| load file }
137
154
  end
@@ -144,21 +161,11 @@ module Sharp
144
161
  end
145
162
  end
146
163
 
147
- # TODO: Make an Array of load paths that you can add to that these are just part of
148
- def load_lib
149
- $:.unshift(root.join("app/lib"))
150
- Dir.glob(root.join("app/lib/*.rb")) {|file| require file }
151
- end
152
-
153
- def load_models
154
- $:.unshift(root.join("app/models"))
155
- Dir.glob(root.join("app/models/*.rb")) {|file| require file }
156
- end
157
-
158
- def load_actions
159
- Rack::Action.logger = logger
160
- $:.unshift(root.join("app/actions"))
161
- Dir.glob(root.join("app/actions/*.rb")) {|file| require file }
164
+ def load_load_path
165
+ load_path.each do |path|
166
+ $:.unshift(root.join(path))
167
+ Dir.glob(root.join("#{path}/*.rb")) {|file| require file }
168
+ end
162
169
  end
163
170
 
164
171
  def load_routes
@@ -172,6 +179,5 @@ module Sharp
172
179
  def finish_boot
173
180
  @booted = true
174
181
  end
175
-
176
182
  end
177
183
  end
data/lib/sharp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sharp
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
data/sharp.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "sharp"
5
- gem.version = "0.3.1"
5
+ gem.version = "0.3.2"
6
6
  gem.authors = ["Paul Barry"]
7
7
  gem.email = ["mail@paulbarry.com"]
8
8
  gem.description = %q{A Ruby and Rack-based web framework}
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sharp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Paul Barry
@@ -14,65 +13,57 @@ dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: curtain
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rack-router
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rack-action
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  description: A Ruby and Rack-based web framework
@@ -124,27 +115,26 @@ files:
124
115
  - template/vendor/assets/stylesheets/.gitkeep
125
116
  homepage: http://github.com/pjb3/sharp
126
117
  licenses: []
118
+ metadata: {}
127
119
  post_install_message:
128
120
  rdoc_options: []
129
121
  require_paths:
130
122
  - lib
131
123
  required_ruby_version: !ruby/object:Gem::Requirement
132
- none: false
133
124
  requirements:
134
- - - ! '>='
125
+ - - '>='
135
126
  - !ruby/object:Gem::Version
136
127
  version: '0'
137
128
  required_rubygems_version: !ruby/object:Gem::Requirement
138
- none: false
139
129
  requirements:
140
- - - ! '>='
130
+ - - '>='
141
131
  - !ruby/object:Gem::Version
142
132
  version: '0'
143
133
  requirements: []
144
134
  rubyforge_project:
145
- rubygems_version: 1.8.25
135
+ rubygems_version: 2.0.0
146
136
  signing_key:
147
- specification_version: 3
137
+ specification_version: 4
148
138
  summary: A Ruby and Rack-based web framework
149
139
  test_files: []
150
140
  has_rdoc: