padrino-core 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -34,7 +34,7 @@ Reloading:: Automatically reloads server code during development.
34
34
  Localization:: Full support of I18n language localization and can auto-set user’s locale.
35
35
 
36
36
  Keep in mind, the user will be able to pull in these components
37
- {seperately into existing Sinatra applications}[http://wiki.github.com/padrino/padrino-framework/standalone-usage-in-sinatra]
37
+ {seperately into existing Sinatra applications}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra]
38
38
  or use them altogether for a comprehensive upgrade to Sinatra (a full-stack Padrino application).
39
39
 
40
40
  == Installation
@@ -47,7 +47,7 @@ This will install the necessary padrino gems to get you started.
47
47
  Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications.
48
48
 
49
49
  For a more detailed look at Padrino installation,
50
- check out the {Installation Guide}[http://wiki.github.com/padrino/padrino-framework/installation].
50
+ check out the {Installation Guide}[http://www.padrinorb.com/guides/installation].
51
51
 
52
52
  == Usage
53
53
 
@@ -57,20 +57,20 @@ on the enhancements to the core Sinatra functionality. To use Padrino, one shoul
57
57
  usage of Sinatra itself.
58
58
 
59
59
  Please check out the
60
- {Understanding Sinatra}[http://wiki.github.com/padrino/padrino-framework/underlying-sinatra-overview] guide
60
+ {Understanding Sinatra}[http://www.padrinorb.com/guides/underlying-sinatra-overview] guide
61
61
  to learn more about these fundamentals.
62
62
 
63
63
  For information on how to use a specific gem in isolation within an existing Sinatra project, checkout the guide for
64
- {Using Padrino in Sinatra}[http://wiki.github.com/padrino/padrino-framework/standalone-usage-in-sinatra].
64
+ {Using Padrino in Sinatra}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra].
65
65
 
66
66
  == Getting Started
67
67
 
68
68
  Once a developer understands Sinatra, Padrino is quite easy to get comfortable with since Padrino is simply a superset
69
69
  of existing Sinatra Functionality! Best way to get started with building Padrino applications is to read following resources:
70
70
 
71
- * {Blog Tutorial}[http://wiki.github.com/padrino/padrino-framework/blog-tutorial] - Step-by-step guide to building a blog application with Padrino.
72
- * {Quick Overview}[http://wiki.github.com/padrino/padrino-framework/basic-projects] - Outlines basic generation commands.
73
- * {Padrino Examples}[http://wiki.github.com/padrino/padrino-framework/examples] - List of known Padrino applications which can serve as examples.
71
+ * {Blog Tutorial}[http://www.padrinorb.com/guides/blog-tutorial] - Step-by-step guide to building a blog application with Padrino.
72
+ * {Quick Overview}[http://www.padrinorb.com/guides/basic-projects] - Outlines basic generation commands.
73
+ * {Padrino Examples}[http://www.padrinorb.com/guides/examples] - List of known Padrino applications which can serve as examples.
74
74
 
75
75
  == Enhanced Base Application (padrino-core)
76
76
 
@@ -107,7 +107,7 @@ Let us first take a look at the simplest possible Padrino application:
107
107
  === Enhanced Route Definitions and Controllers
108
108
 
109
109
  For a complete overview of the Padrino routing and controller system,
110
- check out the {Routing and Controller guide}[http://wiki.github.com/padrino/padrino-framework/controllers].
110
+ check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
111
111
 
112
112
  Suppose we wanted to add additional routes to our Padrino application, and we want to organize the routes
113
113
  within a more structured layout. Simply add a <tt>controllers</tt> or <tt>app/controllers</tt> folder and create a file as such:
@@ -175,7 +175,7 @@ When you visit :+show+ and your I18n.locale == :ru Padrino try to look for "admi
175
175
  they try "admin/show.ru.*" then "admin/show.js.*" if none match return "admin/show.erb" (or other engine i.e. haml)
176
176
 
177
177
  For a complete overview of the routing and controller system, check out the
178
- {Routing and Controller guide}[http://wiki.github.com/padrino/padrino-framework/controllers].
178
+ {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
179
179
 
180
180
  === Rendering
181
181
 
@@ -191,7 +191,7 @@ The existing render function works as well if an engine type should be specified
191
191
  render :haml, 'account/index'
192
192
 
193
193
  For a complete overview of the Padrino rendering system, check out the
194
- {Routing and Controller guide}[http://wiki.github.com/padrino/padrino-framework/controllers].
194
+ {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
195
195
 
196
196
  === Layout
197
197
 
@@ -206,7 +206,7 @@ With Padrino you can (like rails do) use for your custom layout, disable it
206
206
  layout :custom
207
207
 
208
208
  For a complete overview of the layout functionality,
209
- check out the {Routing and Controller guide}[http://wiki.github.com/padrino/padrino-framework/controllers].
209
+ check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
210
210
 
211
211
  === Mounting Applications
212
212
 
@@ -221,7 +221,7 @@ Padrino stores application mounting information by default within <tt>config/app
221
221
  to keep all information regarding what applications are mounted to which uri's.
222
222
 
223
223
  For a complete look at mounting applications within a Padrino project,
224
- check out the guide on {Mounting Applications}[http://wiki.github.com/padrino/padrino-framework/mounting-applications].
224
+ check out the guide on {Mounting Applications}[http://www.padrinorb.com/guides/mounting-applications].
225
225
 
226
226
  === Auto Load Paths
227
227
 
@@ -231,7 +231,7 @@ as a convention for establishing database connection. Also, any files within the
231
231
  automatically by Padrino.
232
232
 
233
233
  For a complete overview of auto-loaded paths within Padrino,
234
- check out the {Padrino Development Guide}[http://wiki.github.com/padrino/padrino-framework/development-and-terminal-commands].
234
+ check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
235
235
 
236
236
  === Application Logging
237
237
 
@@ -248,7 +248,7 @@ within your app and any controller or views:
248
248
  end
249
249
 
250
250
  For a complete overview of Padrino logger functionality, check out the
251
- {Padrino Development Guide}[http://wiki.github.com/padrino/padrino-framework/development-and-terminal-commands].
251
+ {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
252
252
 
253
253
  === Development Reloader
254
254
 
@@ -260,7 +260,7 @@ This makes rapid development much easier and provides a better alternative to 's
260
260
  which requires the application server to be restarted which makes requests take much longer to complete.
261
261
 
262
262
  For a complete overview of code reloading in development,
263
- check out the {Padrino Development Guide}[http://wiki.github.com/padrino/padrino-framework/development-and-terminal-commands].
263
+ check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
264
264
 
265
265
  === Terminal Commands
266
266
 
@@ -287,7 +287,7 @@ You can also create custom rake tasks as well. Using these commands can simplify
287
287
  making development that much smoother.
288
288
 
289
289
  For a complete overview of Padrino terminal commands, check out the
290
- {Padrino Commands Guide}[http://wiki.github.com/padrino/padrino-framework/development-and-terminal-commands].
290
+ {Padrino Commands Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
291
291
 
292
292
  == Copyright
293
293
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require File.expand_path("../lib/padrino-core/version.rb", __FILE__)
3
4
 
4
5
  begin
5
6
  require 'jeweler'
@@ -12,6 +13,7 @@ begin
12
13
  gem.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
13
14
  gem.executables = ["padrino"]
14
15
  gem.rubyforge_project = 'padrino-core'
16
+ gem.version = Padrino.version
15
17
  gem.add_runtime_dependency "sinatra", ">= 1.0.0"
16
18
  gem.add_runtime_dependency "i18n", ">= 0.3.2"
17
19
  gem.add_runtime_dependency "usher", ">= 0.6.2"
@@ -52,16 +54,4 @@ rescue LoadError
52
54
  end
53
55
  end
54
56
 
55
- task :test => :check_dependencies
56
-
57
- task :default => :test
58
-
59
- require 'rake/rdoctask'
60
- Rake::RDocTask.new do |rdoc|
61
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
62
-
63
- rdoc.rdoc_dir = 'rdoc'
64
- rdoc.title = "padrino-core #{version}"
65
- rdoc.rdoc_files.include('README*')
66
- rdoc.rdoc_files.include('lib/**/*.rb')
67
- end
57
+ task :default => :test
data/bin/padrino CHANGED
@@ -4,14 +4,21 @@ require 'rubygems'
4
4
  padrino_core_path = File.expand_path('../../lib', __FILE__)
5
5
  $:.unshift(padrino_core_path) if File.directory?(padrino_core_path) && !$:.include?(padrino_core_path)
6
6
 
7
+ padrino_local_path = Dir.pwd
8
+ $:.unshift(padrino_local_path) if File.directory?(padrino_local_path) && !$:.include?(padrino_local_path)
9
+
7
10
  require 'padrino-core/cli/base'
11
+ require 'padrino-core/support_lite'
8
12
 
9
13
  if %w(g gen).include?(ARGV[0])
10
14
  ARGV.shift
11
- padrino_gen = File.join(padrino_core_path, "/../../padrino-gen/bin/padrino-gen")
12
- if File.exist?(padrino_gen)
13
- system "#{padrino_gen} #{ARGV.join(" ")}"
14
- else
15
+ begin
16
+ # We try to load the vendored padrino-gen if exist
17
+ padrino_gen_path = File.expand_path('../../../padrino-gen/lib', __FILE__)
18
+ $:.unshift(padrino_gen_path) if File.directory?(padrino_gen_path) && !$:.include?(padrino_gen_path)
19
+ require 'padrino-gen'
20
+ Padrino.bin_gen(ARGV)
21
+ rescue
15
22
  puts "<= You need padrino-gen! Run: gem install padrino-gen"
16
23
  end
17
24
  exit(0)
@@ -9,14 +9,15 @@ module Padrino
9
9
  # Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
10
10
  #
11
11
  class Mounter
12
- attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj
12
+ attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host
13
13
 
14
14
  def initialize(name, options={})
15
- @name = name.downcase
15
+ @name = name.underscore
16
16
  @app_class = options[:app_class] || name.classify
17
17
  @app_file = options[:app_file] || locate_app_file
18
18
  @app_root = options[:app_root] || File.dirname(@app_file)
19
19
  @app_obj = self.app_object
20
+ @uri_root = "/"
20
21
  end
21
22
 
22
23
  ##
@@ -33,21 +34,36 @@ module Padrino
33
34
  end
34
35
 
35
36
  ##
36
- # Maps Padrino application onto a Rack::Builder
37
+ # Registers the mounted application onto Padrino for the given host
38
+ #
39
+ # ==== Examples
40
+ #
41
+ # Mounter.new("blog_app").to("/blog").host("blog.padrino.org")
42
+ # Mounter.new("blog_app").host("blog.padrino.org")
43
+ # Mounter.new("catch_all").host(/.*\.padrino.org/)
44
+ #
45
+ def host(mount_host)
46
+ @app_host = mount_host
47
+ Padrino.insert_mounted_app(self)
48
+ self
49
+ end
50
+
51
+ ##
52
+ # Maps Padrino application onto a Padrino::Router
37
53
  # For use in constructing a Rack application
38
54
  #
39
- # @app.map_onto(@builder)
55
+ # @app.map_onto(router)
40
56
  #
41
- def map_onto(builder)
57
+ def map_onto(router)
42
58
  app_data, app_obj = self, @app_obj
43
- builder.map self.uri_root do
44
- app_obj.set :uri_root, app_data.uri_root
45
- app_obj.set :app_name, app_data.name
46
- app_obj.set :app_file, app_data.app_file unless ::File.exist?(app_obj.app_file)
47
- app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
48
- app_obj.setup_application! # We need to initialize here the app.
49
- run app_obj
50
- end
59
+ app_obj.set :uri_root, app_data.uri_root
60
+ app_obj.set :app_name, app_data.name
61
+ app_obj.set :app_file, app_data.app_file unless ::File.exist?(app_obj.app_file)
62
+ app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
63
+ app_obj.set :public, Padrino.root('public', app_data.uri_root)
64
+ app_obj.set :static, File.exist?(app_obj.public)
65
+ app_obj.setup_application! # We need to initialize here the app.
66
+ router.map(:path => app_data.uri_root, :to => app_obj, :host => app_data.app_host)
51
67
  end
52
68
 
53
69
  ##
@@ -37,7 +37,36 @@ module Padrino
37
37
  #
38
38
  def layout(name=:layout, &block)
39
39
  return super(name, &block) if block_given?
40
- @_layout = name
40
+ @layout = name
41
+ end
42
+
43
+ ##
44
+ # Returns the cached template file to render for a given url, content_type and locale.
45
+ #
46
+ # render_options = [template_path, content_type, locale]
47
+ #
48
+ def fetch_template_file(render_options)
49
+ (@_cached_templates ||= {})[render_options]
50
+ end
51
+
52
+ ###
53
+ # Caches the template file for the given rendering options
54
+ #
55
+ # render_options = [template_path, content_type, locale]
56
+ #
57
+ def cache_template_file!(template_file, render_options)
58
+ (@_cached_templates ||= {})[render_options] = template_file || []
59
+ end
60
+
61
+ def fetch_layout_path
62
+ layout_name = @layout || :application
63
+ @_cached_layout ||= {}
64
+ cached_layout_path = @_cached_layout[layout_name]
65
+ return cached_layout_path if cached_layout_path
66
+ has_layout_at_root = Dir["#{views}/#{layout_name}.*"].any?
67
+ layout_path = has_layout_at_root ? layout_name.to_sym : File.join('layouts', layout_name.to_s).to_sym
68
+ @_cached_layout[layout_name] = layout_path unless reload_templates?
69
+ layout_path
41
70
  end
42
71
  end
43
72
 
@@ -64,16 +93,16 @@ module Padrino
64
93
  data, engine = *resolve_template(engine, options) if data.nil?
65
94
 
66
95
  # Sinatra 1.0 requires an outvar for erb and erubis templates
67
- options[:outvar] ||= '@_out_buf' if [:erb, :erubis].include?(engine)
96
+ options[:outvar] ||= '@_out_buf' if [:erb, :erubis] & [engine]
68
97
 
69
98
  # Resolve layouts similar to in Rails
70
99
  if (options[:layout].nil? || options[:layout] == true) && !self.class.templates.has_key?(:layout)
71
- options[:layout] = resolved_layout
72
- logger.debug "Resolving layout #{options[:layout]}" if defined?(logger) && options[:layout]
100
+ options[:layout] = resolved_layout || false # We need to force layout false so sinatra don't try to render it
101
+ logger.debug "Resolving layout #{options[:layout]}" if defined?(logger) && options[:layout].present?
73
102
  end
74
103
 
75
104
  # Pass arguments to Sinatra render method
76
- super(engine, data, options, locals, &block)
105
+ super(engine, data, options.dup, locals, &block)
77
106
  end
78
107
 
79
108
  ##
@@ -85,10 +114,8 @@ module Padrino
85
114
  # => "/layouts/custom"
86
115
  #
87
116
  def resolved_layout
88
- layout_var = self.class.instance_variable_get(:@_layout) || :application
89
- has_layout_at_root = Dir["#{self.settings.views}/#{layout_var}.*"].any?
90
- layout_path = has_layout_at_root ? layout_var.to_sym : File.join('layouts', layout_var.to_s).to_sym
91
- resolve_template(layout_path, :strict_format => true)[0] rescue nil
117
+ located_layout = resolve_template(self.class.fetch_layout_path, :strict_format => true, :raise_exceptions => false)
118
+ located_layout ? located_layout[0] : false
92
119
  end
93
120
 
94
121
  ##
@@ -97,6 +124,7 @@ module Padrino
97
124
  # === Options
98
125
  #
99
126
  # :strict_format:: The resolved template must match the content_type of the request (defaults to false)
127
+ # :raise_exceptions:: Raises a +TemplateNotFound+ exception if the template cannot be located.
100
128
  #
101
129
  # ==== Example
102
130
  #
@@ -105,28 +133,44 @@ module Padrino
105
133
  # # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
106
134
  #
107
135
  def resolve_template(template_path, options={})
108
- options.reverse_merge!(:strict_format => false)
136
+ # Fetch cached template for rendering options
137
+ template_path = "/#{template_path}" unless template_path.to_s[0] == ?/
138
+ rendering_options = [template_path, content_type, locale]
139
+ cached_template = self.class.fetch_template_file(rendering_options)
140
+ return cached_template if cached_template
141
+
142
+ # Resolve view path and options
143
+ options.reverse_merge!(:strict_format => false, :raise_exceptions => true)
109
144
  view_path = options.delete(:views) || self.options.views || self.class.views || "./views"
110
- template_path = "/#{template_path}" unless template_path.to_s =~ /^\//
111
145
  target_extension = File.extname(template_path)[1..-1] || "none" # retrieves explicit template extension
112
146
  template_path = template_path.chomp(".#{target_extension}")
113
147
 
148
+ # Generate potential template candidates
114
149
  templates = Dir[File.join(view_path, template_path) + ".*"].map do |file|
115
150
  template_engine = File.extname(file)[1..-1].to_sym # retrieves engine extension
116
- template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
151
+ template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
117
152
  [template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern }
118
153
  end
119
154
 
155
+ # Resolve final template to render
120
156
  located_template =
121
- templates.find { |file, e| defined?(I18n) && file.to_s == "#{template_path}.#{I18n.locale}.#{content_type}" } ||
122
- templates.find { |file, e| defined?(I18n) && file.to_s == "#{template_path}.#{I18n.locale}" && content_type == :html } ||
157
+ templates.find { |file, e| file.to_s == "#{template_path}.#{locale}.#{content_type}" } ||
158
+ templates.find { |file, e| file.to_s == "#{template_path}.#{locale}" && content_type == :html } ||
123
159
  templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } ||
124
160
  templates.find { |file, e| file.to_s == "#{template_path}.#{content_type}" } ||
125
161
  templates.find { |file, e| file.to_s == "#{template_path}" && content_type == :html } ||
126
162
  templates.any? && !options[:strict_format] && templates.first # If not strict, fall back to the first located template
127
163
 
128
- raise TemplateNotFound.new("Template path '#{template_path}' could not be located!") unless located_template
164
+ self.class.cache_template_file!(located_template, rendering_options) unless settings.reload_templates?
165
+ raise TemplateNotFound.new("Template path '#{template_path}' could not be located!") if !located_template && options[:raise_exceptions]
129
166
  located_template
130
167
  end
168
+
169
+ ##
170
+ # Return the I18n.locale if I18n is defined
171
+ #
172
+ def locale
173
+ I18n.locale if defined?(I18n)
174
+ end
131
175
  end # Rendering
132
- end # Padrino
176
+ end # Padrino