padrino-core 0.10.7 → 0.11.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.
- checksums.yaml +7 -0
- data/lib/padrino-core.rb +58 -4
- data/lib/padrino-core/application.rb +38 -16
- data/lib/padrino-core/application/flash.rb +229 -0
- data/lib/padrino-core/application/rendering.rb +39 -11
- data/lib/padrino-core/application/rendering/extensions/erubis.rb +55 -0
- data/lib/padrino-core/application/rendering/extensions/haml.rb +26 -0
- data/lib/padrino-core/application/rendering/extensions/slim.rb +14 -0
- data/lib/padrino-core/application/routing.rb +106 -35
- data/lib/padrino-core/cli/base.rb +41 -38
- data/lib/padrino-core/cli/rake.rb +30 -9
- data/lib/padrino-core/cli/rake_tasks.rb +9 -14
- data/lib/padrino-core/loader.rb +23 -9
- data/lib/padrino-core/locale/fr.yml +1 -1
- data/lib/padrino-core/locale/ru.yml +1 -1
- data/lib/padrino-core/logger.rb +48 -32
- data/lib/padrino-core/module.rb +58 -0
- data/lib/padrino-core/mounter.rb +15 -5
- data/lib/padrino-core/reloader.rb +14 -12
- data/lib/padrino-core/server.rb +4 -4
- data/lib/padrino-core/support_lite.rb +43 -6
- data/lib/padrino-core/version.rb +1 -1
- data/padrino-core.gemspec +9 -4
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/mini_shoulda.rb +1 -1
- data/test/test_application.rb +38 -21
- data/test/test_csrf_protection.rb +80 -0
- data/test/test_filters.rb +70 -0
- data/test/test_flash.rb +168 -0
- data/test/test_logger.rb +27 -0
- data/test/test_mounter.rb +24 -2
- data/test/test_reloader_simple.rb +4 -4
- data/test/test_rendering.rb +75 -4
- data/test/test_routing.rb +164 -35
- data/test/test_support_lite.rb +56 -0
- metadata +52 -29
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9f915e954014b964f9d5afccd9999d80cd888c05
|
4
|
+
data.tar.gz: 0f64be604ae666519fdd77d32413f9bdf4c32986
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f5b45a55ece397aabf5c7e9d4c961a51edeaa882156962222a0b41d718e62c000fa301f954236fa1599d94e8f2e19109e538b775a2c651c94dfefabf6f187073
|
7
|
+
data.tar.gz: 7796c665daf7a323174e265e3fbc23d71cef98cc9ae1427cb0d5a3d18a3352fdd861fab8adb83308b01c6f4e2f7b1e3bd6ab372493b6032c43f41431dabbb15e
|
data/lib/padrino-core.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
require 'sinatra/base'
|
2
|
-
require 'padrino-core/
|
2
|
+
require 'padrino-core/version'
|
3
|
+
require 'padrino-core/support_lite'
|
4
|
+
require 'padrino-core/application'
|
5
|
+
|
6
|
+
require 'padrino-core/caller'
|
7
|
+
require 'padrino-core/command'
|
8
|
+
require 'padrino-core/loader'
|
9
|
+
require 'padrino-core/logger'
|
10
|
+
require 'padrino-core/mounter'
|
11
|
+
require 'padrino-core/reloader'
|
12
|
+
require 'padrino-core/router'
|
13
|
+
require 'padrino-core/server'
|
14
|
+
require 'padrino-core/tasks'
|
15
|
+
require 'padrino-core/module'
|
3
16
|
|
4
|
-
FileSet.glob_require('padrino-core/application/*.rb', __FILE__)
|
5
|
-
FileSet.glob_require('padrino-core/*.rb', __FILE__)
|
6
17
|
|
7
18
|
# The Padrino environment (falls back to the rack env or finally develop)
|
8
19
|
PADRINO_ENV = ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= "development" unless defined?(PADRINO_ENV)
|
@@ -80,7 +91,14 @@ module Padrino
|
|
80
91
|
# end
|
81
92
|
#
|
82
93
|
def configure_apps(&block)
|
83
|
-
|
94
|
+
return unless block_given?
|
95
|
+
@@_global_configurations ||= []
|
96
|
+
@@_global_configurations << block
|
97
|
+
@_global_configuration = lambda do |app|
|
98
|
+
@@_global_configurations.each do |configuration|
|
99
|
+
app.class_eval(&configuration)
|
100
|
+
end
|
101
|
+
end
|
84
102
|
end
|
85
103
|
|
86
104
|
##
|
@@ -148,5 +166,41 @@ module Padrino
|
|
148
166
|
def use(m, *args, &block)
|
149
167
|
middleware << [m, args, block]
|
150
168
|
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Registers a gem with padrino. This relieves the caller from setting up
|
172
|
+
# loadpaths by himself and enables Padrino to look up apps in gem folder.
|
173
|
+
#
|
174
|
+
# The name given has to be the proper gem name as given in the gemspec.
|
175
|
+
#
|
176
|
+
# @param [String] name
|
177
|
+
# The name of the gem being registered.
|
178
|
+
#
|
179
|
+
# @param [Module] main_module
|
180
|
+
# The main module of the gem.
|
181
|
+
#
|
182
|
+
# @returns The root path of the loaded gem
|
183
|
+
def gem(name, main_module)
|
184
|
+
_,spec = Gem.loaded_specs.find { |spec_name, spec| spec_name == name }
|
185
|
+
gems << spec
|
186
|
+
modules << main_module
|
187
|
+
spec.full_gem_path
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# Returns all currently known padrino gems.
|
192
|
+
#
|
193
|
+
# @returns [Gem::Specification]
|
194
|
+
def gems
|
195
|
+
@gems ||= []
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# All loaded Padrino modules.
|
200
|
+
#
|
201
|
+
# @returns [<Padrino::Module>]
|
202
|
+
def modules
|
203
|
+
@modules ||= []
|
204
|
+
end
|
151
205
|
end # self
|
152
206
|
end # Padrino
|
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'padrino-core/application/rendering'
|
2
|
+
require 'padrino-core/application/routing'
|
3
|
+
require 'padrino-core/application/flash'
|
4
|
+
require 'padrino-core/application/showexceptions'
|
5
|
+
|
1
6
|
module Padrino
|
2
7
|
class ApplicationSetupError < RuntimeError # @private
|
3
8
|
end
|
@@ -173,17 +178,21 @@ module Padrino
|
|
173
178
|
set :method_override, true
|
174
179
|
set :sessions, false
|
175
180
|
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
176
|
-
set :views, Proc.new { File.join(root,
|
177
|
-
set :images_path, Proc.new { File.join(
|
178
|
-
set :protection,
|
181
|
+
set :views, Proc.new { File.join(root, 'views') }
|
182
|
+
set :images_path, Proc.new { File.join(public_folder, 'images') }
|
183
|
+
set :protection, true
|
184
|
+
# Haml specific
|
185
|
+
set :haml, { :ugly => (Padrino.env == :production) } if defined?(Haml)
|
179
186
|
# Padrino specific
|
180
187
|
set :uri_root, '/'
|
181
188
|
set :app_name, settings.to_s.underscore.to_sym
|
182
189
|
set :default_builder, 'StandardFormBuilder'
|
183
|
-
set :flash, defined?(Sinatra::Flash) || defined?(Rack::Flash)
|
184
190
|
set :authentication, false
|
185
191
|
# Padrino locale
|
186
192
|
set :locale_path, Proc.new { Dir[File.join(settings.root, '/locale/**/*.{rb,yml}')] }
|
193
|
+
# Authenticity token
|
194
|
+
set :protect_from_csrf, false
|
195
|
+
set :allow_disabled_csrf, false
|
187
196
|
# Load the Global Configurations
|
188
197
|
class_eval(&Padrino.apps_configuration) if Padrino.apps_configuration
|
189
198
|
end
|
@@ -241,27 +250,40 @@ module Padrino
|
|
241
250
|
# Also initializes the application after setting up the middleware
|
242
251
|
def setup_default_middleware(builder)
|
243
252
|
setup_sessions builder
|
244
|
-
setup_flash builder
|
245
253
|
builder.use Padrino::ShowExceptions if show_exceptions?
|
246
254
|
builder.use Padrino::Logger::Rack, uri_root if Padrino.logger && logging?
|
247
255
|
builder.use Padrino::Reloader::Rack if reload?
|
248
256
|
builder.use Rack::MethodOverride if method_override?
|
249
257
|
builder.use Rack::Head
|
258
|
+
register Padrino::Flash
|
250
259
|
setup_protection builder
|
260
|
+
setup_csrf_protection builder
|
251
261
|
setup_application!
|
252
262
|
end
|
253
263
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
264
|
+
# sets up csrf protection for the app
|
265
|
+
def setup_csrf_protection(builder)
|
266
|
+
if protect_from_csrf? && !sessions?
|
267
|
+
raise(<<-ERROR)
|
268
|
+
`protect_from_csrf` is activated, but `sessions` are not. To enable csrf
|
269
|
+
protection, use:
|
270
|
+
|
271
|
+
enable :sessions
|
272
|
+
|
273
|
+
or deactivate protect_from_csrf:
|
274
|
+
|
275
|
+
disable :protect_from_csrf
|
276
|
+
ERROR
|
277
|
+
end
|
278
|
+
|
279
|
+
if protect_from_csrf?
|
280
|
+
if allow_disabled_csrf?
|
281
|
+
builder.use Rack::Protection::AuthenticityToken,
|
282
|
+
:reaction => :report,
|
283
|
+
:report_key => 'protection.csrf.failed'
|
284
|
+
else
|
285
|
+
builder.use Rack::Protection::AuthenticityToken
|
286
|
+
end
|
265
287
|
end
|
266
288
|
end
|
267
289
|
end # self
|
@@ -0,0 +1,229 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Flash
|
3
|
+
|
4
|
+
class << self
|
5
|
+
# @private
|
6
|
+
def registered(app)
|
7
|
+
app.helpers Helpers
|
8
|
+
app.after do
|
9
|
+
session[:_flash] = @_flash.next if @_flash
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end # self
|
13
|
+
|
14
|
+
class Storage
|
15
|
+
include Enumerable
|
16
|
+
|
17
|
+
# @private
|
18
|
+
def initialize(session=nil)
|
19
|
+
@_now = session || {}
|
20
|
+
@_next = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def now
|
24
|
+
@_now
|
25
|
+
end
|
26
|
+
|
27
|
+
def next
|
28
|
+
@_next
|
29
|
+
end
|
30
|
+
|
31
|
+
# @since 0.10.8
|
32
|
+
# @api public
|
33
|
+
def [](type)
|
34
|
+
@_now[type]
|
35
|
+
end
|
36
|
+
|
37
|
+
# @since 0.10.8
|
38
|
+
# @api public
|
39
|
+
def []=(type, message)
|
40
|
+
@_next[type] = message
|
41
|
+
end
|
42
|
+
|
43
|
+
# @since 0.10.8
|
44
|
+
# @api public
|
45
|
+
def delete(type)
|
46
|
+
@_now.delete(type)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# @since 0.10.8
|
51
|
+
# @api public
|
52
|
+
def keys
|
53
|
+
@_now.keys
|
54
|
+
end
|
55
|
+
|
56
|
+
# @since 0.10.8
|
57
|
+
# @api public
|
58
|
+
def key?(type)
|
59
|
+
@_now.key?(type)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @since 0.10.8
|
63
|
+
# @api public
|
64
|
+
def each(&block)
|
65
|
+
@_now.each(&block)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @since 0.10.8
|
69
|
+
# @api public
|
70
|
+
def replace(hash)
|
71
|
+
@_now.replace(hash)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# @since 0.10.8
|
76
|
+
# @api public
|
77
|
+
def update(hash)
|
78
|
+
@_now.update(hash)
|
79
|
+
self
|
80
|
+
end
|
81
|
+
alias_method :merge!, :update
|
82
|
+
|
83
|
+
# @since 0.10.8
|
84
|
+
# @api public
|
85
|
+
def sweep
|
86
|
+
@_now.replace(@_next)
|
87
|
+
@_next = {}
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
# @since 0.10.8
|
92
|
+
# @api public
|
93
|
+
def keep(key = nil)
|
94
|
+
if key
|
95
|
+
@_next[key] = @_now[key]
|
96
|
+
else
|
97
|
+
@_next.merge!(@_now)
|
98
|
+
end
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
# @since 0.10.8
|
103
|
+
# @api public
|
104
|
+
def discard(key = nil)
|
105
|
+
if key
|
106
|
+
@_next.delete(key)
|
107
|
+
else
|
108
|
+
@_next = {}
|
109
|
+
end
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
# @since 0.10.8
|
114
|
+
# @api public
|
115
|
+
def clear
|
116
|
+
@_now.clear
|
117
|
+
end
|
118
|
+
|
119
|
+
# @since 0.10.8
|
120
|
+
# @api public
|
121
|
+
def empty?
|
122
|
+
@_now.empty?
|
123
|
+
end
|
124
|
+
|
125
|
+
# @since 0.10.8
|
126
|
+
# @api public
|
127
|
+
def to_hash
|
128
|
+
@_now.dup
|
129
|
+
end
|
130
|
+
|
131
|
+
def length
|
132
|
+
@_now.length
|
133
|
+
end
|
134
|
+
alias_method :size, :length
|
135
|
+
|
136
|
+
# @since 0.10.8
|
137
|
+
# @api public
|
138
|
+
def to_s
|
139
|
+
@_now.to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
# @since 0.10.8
|
143
|
+
# @api public
|
144
|
+
def error=(message)
|
145
|
+
self[:error] = message
|
146
|
+
end
|
147
|
+
|
148
|
+
# @since 0.10.8
|
149
|
+
# @api public
|
150
|
+
def error
|
151
|
+
self[:error]
|
152
|
+
end
|
153
|
+
|
154
|
+
# @since 0.10.8
|
155
|
+
# @api public
|
156
|
+
def notice=(message)
|
157
|
+
self[:notice] = message
|
158
|
+
end
|
159
|
+
|
160
|
+
# @since 0.10.8
|
161
|
+
# @api public
|
162
|
+
def notice
|
163
|
+
self[:notice]
|
164
|
+
end
|
165
|
+
|
166
|
+
# @since 0.10.8
|
167
|
+
# @api public
|
168
|
+
def success=(message)
|
169
|
+
self[:success] = message
|
170
|
+
end
|
171
|
+
|
172
|
+
# @since 0.10.8
|
173
|
+
# @api public
|
174
|
+
def success
|
175
|
+
self[:success]
|
176
|
+
end
|
177
|
+
end # Storage
|
178
|
+
|
179
|
+
module Helpers
|
180
|
+
###
|
181
|
+
# Overloads the existing redirect helper in-order to provide support for flash messages
|
182
|
+
#
|
183
|
+
# @overload redirect(url)
|
184
|
+
# @param [String] url
|
185
|
+
#
|
186
|
+
# @overload redirect(url, status_code)
|
187
|
+
# @param [String] url
|
188
|
+
# @param [Fixnum] status_code
|
189
|
+
#
|
190
|
+
# @overload redirect(url, status_code, flash_messages)
|
191
|
+
# @param [String] url
|
192
|
+
# @param [Fixnum] status_code
|
193
|
+
# @param [Hash] flash_messages
|
194
|
+
#
|
195
|
+
# @overload redirect(url, flash_messages)
|
196
|
+
# @param [String] url
|
197
|
+
# @param [Hash] flash_messages
|
198
|
+
#
|
199
|
+
# @example
|
200
|
+
# redirect(dashboard, success: :user_created)
|
201
|
+
# redirect(new_location, 301, notice: 'This page has moved. Please update your bookmarks!!')
|
202
|
+
#
|
203
|
+
# @since 0.10.8
|
204
|
+
# @api public
|
205
|
+
def redirect(url, *args)
|
206
|
+
flashes = args.extract_options!
|
207
|
+
|
208
|
+
flashes.each do |type, message|
|
209
|
+
message = I18n.translate(message) if message.is_a?(Symbol) && defined?(I18n)
|
210
|
+
flash[type] = message
|
211
|
+
end
|
212
|
+
|
213
|
+
super(url, args)
|
214
|
+
end
|
215
|
+
alias_method :redirect_to, :redirect
|
216
|
+
|
217
|
+
###
|
218
|
+
# Returns the flash storage object
|
219
|
+
#
|
220
|
+
# @return [Storage]
|
221
|
+
#
|
222
|
+
# @since 0.10.8
|
223
|
+
# @api public
|
224
|
+
def flash
|
225
|
+
@_flash ||= Storage.new(env['rack.session'] ? session[:_flash] : {})
|
226
|
+
end
|
227
|
+
end # Helpers
|
228
|
+
end # Flash
|
229
|
+
end # Padrino
|
@@ -7,6 +7,16 @@ module Padrino
|
|
7
7
|
# locale enabled rendering, among other features.
|
8
8
|
#
|
9
9
|
module Rendering
|
10
|
+
##
|
11
|
+
# A SafeTemplate assumes that its output is safe.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
module SafeTemplate
|
15
|
+
def render(*)
|
16
|
+
super.html_safe
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
##
|
11
21
|
# Exception responsible for when an expected template did not exist.
|
12
22
|
#
|
@@ -25,19 +35,34 @@ module Padrino
|
|
25
35
|
] unless defined?(IGNORE_FILE_PATTERN)
|
26
36
|
|
27
37
|
##
|
28
|
-
# Default
|
38
|
+
# Default options used in the #resolve_template-method.
|
29
39
|
#
|
30
40
|
DEFAULT_RENDERING_OPTIONS = { :strict_format => false, :raise_exceptions => true } unless defined?(DEFAULT_RENDERING_OPTIONS)
|
31
41
|
|
32
42
|
class << self
|
43
|
+
##
|
44
|
+
# Default engine configurations for Padrino::Rendering
|
45
|
+
#
|
46
|
+
# @return {Hash<Symbol,Hash>}
|
47
|
+
# The configurations, keyed by engine.
|
48
|
+
def engine_configurations
|
49
|
+
@engine_configurations ||= {}
|
50
|
+
end
|
51
|
+
|
33
52
|
##
|
34
53
|
# Main class that register this extension.
|
35
54
|
#
|
36
55
|
def registered(app)
|
37
|
-
app
|
38
|
-
|
56
|
+
included(app)
|
57
|
+
engine_configurations.each do |engine, configs|
|
58
|
+
app.set engine, configs
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def included(base)
|
63
|
+
base.send(:include, InstanceMethods)
|
64
|
+
base.extend(ClassMethods)
|
39
65
|
end
|
40
|
-
alias :included :registered
|
41
66
|
end
|
42
67
|
|
43
68
|
##
|
@@ -152,11 +177,8 @@ module Padrino
|
|
152
177
|
# * Use render 'path/to/template.haml' (with explicit engine lookup)
|
153
178
|
# * Use render 'path/to/template', :layout => false
|
154
179
|
# * Use render 'path/to/template', :layout => false, :engine => 'haml'
|
155
|
-
# * Use render { :a => 1, :b => 2, :c => 3 } # => return a json string
|
156
180
|
#
|
157
181
|
def render(engine, data=nil, options={}, locals={}, &block)
|
158
|
-
# If engine is a hash then render data converted to json
|
159
|
-
content_type(:json, :charset => 'utf-8') and return engine.to_json if engine.is_a?(Hash)
|
160
182
|
|
161
183
|
# If engine is nil, ignore engine parameter and shift up all arguments
|
162
184
|
# render nil, "index", { :layout => true }, { :localvar => "foo" }
|
@@ -175,10 +197,10 @@ module Padrino
|
|
175
197
|
root = settings.respond_to?(:root) ? settings.root : ""
|
176
198
|
|
177
199
|
# Use @layout if it exists
|
178
|
-
|
179
|
-
|
200
|
+
layout_was = options[:layout]
|
201
|
+
options[:layout] = @layout if options[:layout].nil? || options[:layout] == true
|
180
202
|
# Resolve layouts similar to in Rails
|
181
|
-
if
|
203
|
+
if options[:layout].nil? && !settings.templates.has_key?(:layout)
|
182
204
|
layout_path, layout_engine = *resolved_layout
|
183
205
|
options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it
|
184
206
|
options[:layout] = false unless layout_engine == engine # TODO allow different layout engine
|
@@ -186,10 +208,12 @@ module Padrino
|
|
186
208
|
elsif options[:layout].present?
|
187
209
|
options[:layout] = settings.fetch_layout_path(options[:layout] || @layout)
|
188
210
|
end
|
211
|
+
# Default to original layout value if none found
|
212
|
+
options[:layout] ||= layout_was
|
189
213
|
|
190
214
|
# Cleanup the template
|
191
215
|
@current_engine, engine_was = engine, @current_engine
|
192
|
-
@_out_buf, _buf_was =
|
216
|
+
@_out_buf, _buf_was = ActiveSupport::SafeBuffer.new, @_out_buf
|
193
217
|
|
194
218
|
# Pass arguments to Sinatra render method
|
195
219
|
super(engine, data, options.dup, locals, &block)
|
@@ -290,3 +314,7 @@ module Padrino
|
|
290
314
|
end # InstanceMethods
|
291
315
|
end # Rendering
|
292
316
|
end # Padrino
|
317
|
+
|
318
|
+
require 'padrino-core/application/rendering/extensions/haml'
|
319
|
+
require 'padrino-core/application/rendering/extensions/erubis'
|
320
|
+
require 'padrino-core/application/rendering/extensions/slim'
|