Merge pull request #357 from trevor/padrino0.10.6
update vendor'd padrino 0.10.5 -> 0.10.6
This commit is contained in:
commit
2afbb40925
|
@ -28,7 +28,8 @@
|
||||||
* Add pid for cleanup
|
* Add pid for cleanup
|
||||||
* Use guard/listen for file watching
|
* Use guard/listen for file watching
|
||||||
* Merge full i18n support
|
* Merge full i18n support
|
||||||
* Implied file extensions (style.scss => sytle.css)
|
* Implied file extensions (style.scss => style.css)
|
||||||
|
* Padrino 0.10.6
|
||||||
|
|
||||||
2.0.14
|
2.0.14
|
||||||
====
|
====
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require 'middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers'
|
require 'middleman-core/vendor/padrino-helpers-0.10.6/lib/padrino-helpers'
|
||||||
|
|
||||||
# Built-in helpers
|
# Built-in helpers
|
||||||
module Middleman::CoreExtensions::DefaultHelpers
|
module Middleman::CoreExtensions::DefaultHelpers
|
||||||
|
@ -19,7 +19,7 @@ module Middleman::CoreExtensions::DefaultHelpers
|
||||||
app.helpers Helpers
|
app.helpers Helpers
|
||||||
|
|
||||||
app.ready do
|
app.ready do
|
||||||
::I18n.load_path += Dir["#{File.dirname(__FILE__)}/../vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/*.yml"]
|
::I18n.load_path += Dir["#{File.dirname(__FILE__)}/../vendor/padrino-helpers-0.10.6/lib/padrino-helpers/locale/*.yml"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias :included :registered
|
alias :included :registered
|
||||||
|
|
|
@ -1,270 +0,0 @@
|
||||||
module Padrino
|
|
||||||
class ApplicationSetupError < RuntimeError # @private
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Subclasses of this become independent Padrino applications (stemming from Sinatra::Application)
|
|
||||||
# These subclassed applications can be easily mounted into other Padrino applications as well.
|
|
||||||
#
|
|
||||||
class Application < Sinatra::Base
|
|
||||||
# Support for advanced routing, controllers, url_for
|
|
||||||
register Padrino::Routing
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the logger for this application.
|
|
||||||
#
|
|
||||||
# @return [Padrino::Logger] Logger associated with this app.
|
|
||||||
#
|
|
||||||
def logger
|
|
||||||
Padrino.logger
|
|
||||||
end
|
|
||||||
|
|
||||||
class << self
|
|
||||||
|
|
||||||
def inherited(base) # @private
|
|
||||||
logger.devel "Setup #{base}"
|
|
||||||
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
|
||||||
base.default_configuration!
|
|
||||||
base.prerequisites.concat([
|
|
||||||
File.join(base.root, "/models.rb"),
|
|
||||||
File.join(base.root, "/models/**/*.rb"),
|
|
||||||
File.join(base.root, "/lib.rb"),
|
|
||||||
File.join(base.root, "/lib/**/*.rb")
|
|
||||||
]).uniq!
|
|
||||||
Padrino.require_dependencies(base.prerequisites)
|
|
||||||
super(base) # Loading the subclass inherited method
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Reloads the application files from all defined load paths
|
|
||||||
#
|
|
||||||
# This method is used from our Padrino Reloader during development mode
|
|
||||||
# in order to reload the source files.
|
|
||||||
#
|
|
||||||
# @return [TrueClass]
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# MyApp.reload!
|
|
||||||
#
|
|
||||||
def reload!
|
|
||||||
logger.devel "Reloading #{self}"
|
|
||||||
@_dependencies = nil # Reset dependencies
|
|
||||||
reset! # Reset sinatra app
|
|
||||||
reset_router! # Reset all routes
|
|
||||||
Padrino.require_dependencies(self.app_file, :force => true) # Reload the app file
|
|
||||||
require_dependencies # Reload dependencies
|
|
||||||
default_filters! # Reload filters
|
|
||||||
default_routes! # Reload default routes
|
|
||||||
default_errors! # Reload our errors
|
|
||||||
I18n.reload! if defined?(I18n) # Reload also our translations
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Resets application routes to only routes not defined by the user
|
|
||||||
#
|
|
||||||
# @return [TrueClass]
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# MyApp.reset_routes!
|
|
||||||
#
|
|
||||||
def reset_routes!
|
|
||||||
reset_router!
|
|
||||||
default_routes!
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the routes of our app.
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# MyApp.routes
|
|
||||||
#
|
|
||||||
def routes
|
|
||||||
router.routes
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Setup the application by registering initializers, load paths and logger
|
|
||||||
# Invoked automatically when an application is first instantiated
|
|
||||||
#
|
|
||||||
# @return [TrueClass]
|
|
||||||
#
|
|
||||||
def setup_application!
|
|
||||||
return if @_configured
|
|
||||||
self.require_dependencies
|
|
||||||
self.default_filters!
|
|
||||||
self.default_routes!
|
|
||||||
self.default_errors!
|
|
||||||
if defined?(I18n)
|
|
||||||
I18n.load_path << self.locale_path
|
|
||||||
I18n.reload!
|
|
||||||
end
|
|
||||||
@_configured = true
|
|
||||||
@_configured
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Run the Padrino app as a self-hosted server using
|
|
||||||
# Thin, Mongrel or WEBrick (in that order)
|
|
||||||
#
|
|
||||||
# @see Padrino::Server#start
|
|
||||||
#
|
|
||||||
def run!(options={})
|
|
||||||
return unless Padrino.load!
|
|
||||||
Padrino.mount(self.to_s).to("/")
|
|
||||||
Padrino.run!(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# @return [Array]
|
|
||||||
# directory that need to be added to +$LOAD_PATHS+ from this application
|
|
||||||
#
|
|
||||||
def load_paths
|
|
||||||
@_load_paths ||= %w(models lib mailers controllers helpers).map { |path| File.join(self.root, path) }
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns default list of path globs to load as dependencies
|
|
||||||
# Appends custom dependency patterns to the be loaded for your Application
|
|
||||||
#
|
|
||||||
# @return [Array]
|
|
||||||
# list of path globs to load as dependencies
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# MyApp.dependencies << "#{Padrino.root}/uploaders/**/*.rb"
|
|
||||||
# MyApp.dependencies << Padrino.root('other_app', 'controllers.rb')
|
|
||||||
#
|
|
||||||
def dependencies
|
|
||||||
@_dependencies ||= [
|
|
||||||
"urls.rb", "config/urls.rb", "mailers/*.rb", "mailers.rb",
|
|
||||||
"controllers/**/*.rb", "controllers.rb", "helpers/**/*.rb", "helpers.rb"
|
|
||||||
].map { |file| Dir[File.join(self.root, file)] }.flatten
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# An array of file to load before your app.rb, basically are files wich our app depends on.
|
|
||||||
#
|
|
||||||
# By default we look for files:
|
|
||||||
#
|
|
||||||
# # List of default files that we are looking for:
|
|
||||||
# yourapp/models.rb
|
|
||||||
# yourapp/models/**/*.rb
|
|
||||||
# yourapp/lib.rb
|
|
||||||
# yourapp/lib/**/*.rb
|
|
||||||
#
|
|
||||||
# @example Adding a custom perequisite
|
|
||||||
# MyApp.prerequisites << Padrino.root('my_app', 'custom_model.rb')
|
|
||||||
#
|
|
||||||
def prerequisites
|
|
||||||
@_prerequisites ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
##
|
|
||||||
# Defines default settings for Padrino application
|
|
||||||
#
|
|
||||||
def default_configuration!
|
|
||||||
# Overwriting Sinatra defaults
|
|
||||||
set :app_file, File.expand_path(caller_files.first || $0) # Assume app file is first caller
|
|
||||||
set :environment, Padrino.env
|
|
||||||
set :reload, Proc.new { development? }
|
|
||||||
set :logging, Proc.new { development? }
|
|
||||||
set :method_override, true
|
|
||||||
set :sessions, false
|
|
||||||
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
|
||||||
set :views, Proc.new { File.join(root, "views") }
|
|
||||||
set :images_path, Proc.new { File.join(public, "images") }
|
|
||||||
set :protection, false
|
|
||||||
# Padrino specific
|
|
||||||
set :uri_root, "/"
|
|
||||||
set :app_name, self.to_s.underscore.to_sym
|
|
||||||
set :default_builder, 'StandardFormBuilder'
|
|
||||||
set :flash, defined?(Sinatra::Flash) || defined?(Rack::Flash)
|
|
||||||
set :authentication, false
|
|
||||||
# Padrino locale
|
|
||||||
set :locale_path, Proc.new { Dir[File.join(self.root, "/locale/**/*.{rb,yml}")] }
|
|
||||||
# Load the Global Configurations
|
|
||||||
class_eval(&Padrino.apps_configuration) if Padrino.apps_configuration
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# We need to add almost __sinatra__ images.
|
|
||||||
#
|
|
||||||
def default_routes!
|
|
||||||
configure :development do
|
|
||||||
get '*__sinatra__/:image.png' do
|
|
||||||
content_type :png
|
|
||||||
filename = File.dirname(__FILE__) + "/images/#{params[:image]}.png"
|
|
||||||
send_file filename
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# This filter it's used for know the format of the request, and automatically set the content type.
|
|
||||||
#
|
|
||||||
def default_filters!
|
|
||||||
before do
|
|
||||||
unless @_content_type
|
|
||||||
@_content_type = :html
|
|
||||||
response['Content-Type'] = 'text/html;charset=utf-8'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# This log errors for production environments
|
|
||||||
#
|
|
||||||
def default_errors!
|
|
||||||
configure :production do
|
|
||||||
error ::Exception do
|
|
||||||
boom = env['sinatra.error']
|
|
||||||
logger.error ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ")
|
|
||||||
response.status = 500
|
|
||||||
content_type 'text/html'
|
|
||||||
'<h1>Internal Server Error</h1>'
|
|
||||||
end unless errors.has_key?(::Exception)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Requires all files within the application load paths
|
|
||||||
#
|
|
||||||
def require_dependencies
|
|
||||||
Padrino.set_load_paths(*load_paths)
|
|
||||||
Padrino.require_dependencies(dependencies, :force => true)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Overrides the default middleware for Sinatra based on Padrino conventions
|
|
||||||
# Also initializes the application after setting up the middleware
|
|
||||||
def setup_default_middleware(builder)
|
|
||||||
setup_sessions builder
|
|
||||||
setup_flash builder
|
|
||||||
builder.use Padrino::ShowExceptions if show_exceptions?
|
|
||||||
builder.use Padrino::Logger::Rack, uri_root if Padrino.logger && logging?
|
|
||||||
builder.use Padrino::Reloader::Rack if reload?
|
|
||||||
builder.use Rack::MethodOverride if method_override?
|
|
||||||
builder.use Rack::Head
|
|
||||||
setup_protection builder
|
|
||||||
setup_application!
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO Remove this in a few versions (rack-flash deprecation)
|
|
||||||
# Move register Sinatra::Flash into setup_default_middleware
|
|
||||||
# Initializes flash using sinatra-flash or rack-flash
|
|
||||||
def setup_flash(builder)
|
|
||||||
register Sinatra::Flash if flash? && defined?(Sinatra::Flash)
|
|
||||||
if defined?(Rack::Flash) && !defined?(Sinatra::Flash)
|
|
||||||
logger.warn %Q{
|
|
||||||
[Deprecation] In Gemfile, 'rack-flash' should be replaced with 'sinatra-flash'!
|
|
||||||
Rack-Flash is not compatible with later versions of Rack and should be replaced.
|
|
||||||
}
|
|
||||||
builder.use Rack::Flash, :sweep => true if flash?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end # self
|
|
||||||
end # Application
|
|
||||||
end # Padrino
|
|
|
@ -112,21 +112,6 @@ module Padrino
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
|
||||||
# Determines whether the dependencies are locked by Bundler.
|
|
||||||
# otherwise return nil
|
|
||||||
#
|
|
||||||
# @return [:locked, :unlocked, nil]
|
|
||||||
# Returns +:locked+ if the +Gemfile.lock+ file exists, or +:unlocked+
|
|
||||||
# if only the +Gemfile+ exists.
|
|
||||||
#
|
|
||||||
# @deprecated Will be removed in 1.0.0
|
|
||||||
#
|
|
||||||
def bundle
|
|
||||||
return :locked if File.exist?(root('Gemfile.lock'))
|
|
||||||
return :unlocked if File.exist?(root("Gemfile"))
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# A Rack::Builder object that allows to add middlewares in front of all
|
# A Rack::Builder object that allows to add middlewares in front of all
|
||||||
# Padrino applications.
|
# Padrino applications.
|
269
middleman-core/lib/middleman-core/vendor/padrino-core-0.10.6/lib/padrino-core/application.rb
vendored
Normal file
269
middleman-core/lib/middleman-core/vendor/padrino-core-0.10.6/lib/padrino-core/application.rb
vendored
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
module Padrino
|
||||||
|
class ApplicationSetupError < RuntimeError # @private
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Subclasses of this become independent Padrino applications (stemming from Sinatra::Application)
|
||||||
|
# These subclassed applications can be easily mounted into other Padrino applications as well.
|
||||||
|
#
|
||||||
|
class Application < Sinatra::Base
|
||||||
|
# Support for advanced routing, controllers, url_for
|
||||||
|
register Padrino::Routing
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns the logger for this application.
|
||||||
|
#
|
||||||
|
# @return [Padrino::Logger] Logger associated with this app.
|
||||||
|
#
|
||||||
|
def logger
|
||||||
|
Padrino.logger
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
|
||||||
|
def inherited(base) # @private
|
||||||
|
begun_at = Time.now
|
||||||
|
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
||||||
|
base.default_configuration!
|
||||||
|
base.prerequisites.concat([
|
||||||
|
File.join(base.root, '/models.rb'),
|
||||||
|
File.join(base.root, '/models/**/*.rb'),
|
||||||
|
File.join(base.root, '/lib.rb'),
|
||||||
|
File.join(base.root, '/lib/**/*.rb')
|
||||||
|
]).uniq!
|
||||||
|
Padrino.require_dependencies(base.prerequisites)
|
||||||
|
logger.devel :setup, begun_at, base
|
||||||
|
super(base) # Loading the subclass inherited method
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reloads the application files from all defined load paths
|
||||||
|
#
|
||||||
|
# This method is used from our Padrino Reloader during development mode
|
||||||
|
# in order to reload the source files.
|
||||||
|
#
|
||||||
|
# @return [TrueClass]
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# MyApp.reload!
|
||||||
|
#
|
||||||
|
def reload!
|
||||||
|
logger.devel "Reloading #{settings}"
|
||||||
|
reset! # Reset sinatra app
|
||||||
|
reset_router! # Reset all routes
|
||||||
|
Padrino.require_dependencies(settings.app_file, :force => true) # Reload the app file
|
||||||
|
require_dependencies # Reload dependencies
|
||||||
|
default_filters! # Reload filters
|
||||||
|
default_routes! # Reload default routes
|
||||||
|
default_errors! # Reload our errors
|
||||||
|
I18n.reload! if defined?(I18n) # Reload also our translations
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Resets application routes to only routes not defined by the user
|
||||||
|
#
|
||||||
|
# @return [TrueClass]
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# MyApp.reset_routes!
|
||||||
|
#
|
||||||
|
def reset_routes!
|
||||||
|
reset_router!
|
||||||
|
default_routes!
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns the routes of our app.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# MyApp.routes
|
||||||
|
#
|
||||||
|
def routes
|
||||||
|
router.routes
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Setup the application by registering initializers, load paths and logger
|
||||||
|
# Invoked automatically when an application is first instantiated
|
||||||
|
#
|
||||||
|
# @return [TrueClass]
|
||||||
|
#
|
||||||
|
def setup_application!
|
||||||
|
return if @_configured
|
||||||
|
settings.require_dependencies
|
||||||
|
settings.default_filters!
|
||||||
|
settings.default_routes!
|
||||||
|
settings.default_errors!
|
||||||
|
if defined?(I18n)
|
||||||
|
I18n.load_path << settings.locale_path
|
||||||
|
I18n.reload!
|
||||||
|
end
|
||||||
|
@_configured = true
|
||||||
|
@_configured
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Run the Padrino app as a self-hosted server using
|
||||||
|
# Thin, Mongrel or WEBrick (in that order)
|
||||||
|
#
|
||||||
|
# @see Padrino::Server#start
|
||||||
|
#
|
||||||
|
def run!(options={})
|
||||||
|
return unless Padrino.load!
|
||||||
|
Padrino.mount(settings.to_s).to('/')
|
||||||
|
Padrino.run!(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# @return [Array]
|
||||||
|
# directory that need to be added to +$LOAD_PATHS+ from this application
|
||||||
|
#
|
||||||
|
def load_paths
|
||||||
|
@_load_paths ||= %w[models lib mailers controllers helpers].map { |path| File.join(settings.root, path) }
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns default list of path globs to load as dependencies
|
||||||
|
# Appends custom dependency patterns to the be loaded for your Application
|
||||||
|
#
|
||||||
|
# @return [Array]
|
||||||
|
# list of path globs to load as dependencies
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# MyApp.dependencies << "#{Padrino.root}/uploaders/**/*.rb"
|
||||||
|
# MyApp.dependencies << Padrino.root('other_app', 'controllers.rb')
|
||||||
|
#
|
||||||
|
def dependencies
|
||||||
|
[
|
||||||
|
'urls.rb', 'config/urls.rb', 'mailers/*.rb', 'mailers.rb',
|
||||||
|
'controllers/**/*.rb', 'controllers.rb', 'helpers/**/*.rb', 'helpers.rb'
|
||||||
|
].map { |file| Dir[File.join(settings.root, file)] }.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# An array of file to load before your app.rb, basically are files wich our app depends on.
|
||||||
|
#
|
||||||
|
# By default we look for files:
|
||||||
|
#
|
||||||
|
# # List of default files that we are looking for:
|
||||||
|
# yourapp/models.rb
|
||||||
|
# yourapp/models/**/*.rb
|
||||||
|
# yourapp/lib.rb
|
||||||
|
# yourapp/lib/**/*.rb
|
||||||
|
#
|
||||||
|
# @example Adding a custom perequisite
|
||||||
|
# MyApp.prerequisites << Padrino.root('my_app', 'custom_model.rb')
|
||||||
|
#
|
||||||
|
def prerequisites
|
||||||
|
@_prerequisites ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
##
|
||||||
|
# Defines default settings for Padrino application
|
||||||
|
#
|
||||||
|
def default_configuration!
|
||||||
|
# Overwriting Sinatra defaults
|
||||||
|
set :app_file, File.expand_path(caller_files.first || $0) # Assume app file is first caller
|
||||||
|
set :environment, Padrino.env
|
||||||
|
set :reload, Proc.new { development? }
|
||||||
|
set :logging, Proc.new { development? }
|
||||||
|
set :method_override, true
|
||||||
|
set :sessions, false
|
||||||
|
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
||||||
|
set :views, Proc.new { File.join(root, "views") }
|
||||||
|
set :images_path, Proc.new { File.join(public, "images") }
|
||||||
|
set :protection, false
|
||||||
|
# Padrino specific
|
||||||
|
set :uri_root, '/'
|
||||||
|
set :app_name, settings.to_s.underscore.to_sym
|
||||||
|
set :default_builder, 'StandardFormBuilder'
|
||||||
|
set :flash, defined?(Sinatra::Flash) || defined?(Rack::Flash)
|
||||||
|
set :authentication, false
|
||||||
|
# Padrino locale
|
||||||
|
set :locale_path, Proc.new { Dir[File.join(settings.root, '/locale/**/*.{rb,yml}')] }
|
||||||
|
# Load the Global Configurations
|
||||||
|
class_eval(&Padrino.apps_configuration) if Padrino.apps_configuration
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# We need to add almost __sinatra__ images.
|
||||||
|
#
|
||||||
|
def default_routes!
|
||||||
|
configure :development do
|
||||||
|
get '*__sinatra__/:image.png' do
|
||||||
|
content_type :png
|
||||||
|
filename = File.dirname(__FILE__) + "/images/#{params[:image]}.png"
|
||||||
|
send_file filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# This filter it's used for know the format of the request, and automatically set the content type.
|
||||||
|
#
|
||||||
|
def default_filters!
|
||||||
|
before do
|
||||||
|
unless @_content_type
|
||||||
|
@_content_type = :html
|
||||||
|
response['Content-Type'] = 'text/html;charset=utf-8'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# This log errors for production environments
|
||||||
|
#
|
||||||
|
def default_errors!
|
||||||
|
configure :production do
|
||||||
|
error ::Exception do
|
||||||
|
boom = env['sinatra.error']
|
||||||
|
logger.error ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ")
|
||||||
|
response.status = 500
|
||||||
|
content_type 'text/html'
|
||||||
|
'<h1>Internal Server Error</h1>'
|
||||||
|
end unless errors.has_key?(::Exception)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Requires all files within the application load paths
|
||||||
|
#
|
||||||
|
def require_dependencies
|
||||||
|
Padrino.set_load_paths(*load_paths)
|
||||||
|
Padrino.require_dependencies(dependencies, :force => true)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Overrides the default middleware for Sinatra based on Padrino conventions
|
||||||
|
# Also initializes the application after setting up the middleware
|
||||||
|
def setup_default_middleware(builder)
|
||||||
|
setup_sessions builder
|
||||||
|
setup_flash builder
|
||||||
|
builder.use Padrino::ShowExceptions if show_exceptions?
|
||||||
|
builder.use Padrino::Logger::Rack, uri_root if Padrino.logger && logging?
|
||||||
|
builder.use Padrino::Reloader::Rack if reload?
|
||||||
|
builder.use Rack::MethodOverride if method_override?
|
||||||
|
builder.use Rack::Head
|
||||||
|
setup_protection builder
|
||||||
|
setup_application!
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO Remove this in a few versions (rack-flash deprecation)
|
||||||
|
# Move register Sinatra::Flash into setup_default_middleware
|
||||||
|
# Initializes flash using sinatra-flash or rack-flash
|
||||||
|
def setup_flash(builder)
|
||||||
|
register Sinatra::Flash if flash? && defined?(Sinatra::Flash)
|
||||||
|
if defined?(Rack::Flash) && !defined?(Sinatra::Flash)
|
||||||
|
logger.warn %Q{
|
||||||
|
[Deprecation] In Gemfile, 'rack-flash' should be replaced with 'sinatra-flash'!
|
||||||
|
Rack-Flash is not compatible with later versions of Rack and should be replaced.
|
||||||
|
}
|
||||||
|
builder.use Rack::Flash, :sweep => true if flash?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end # self
|
||||||
|
end # Application
|
||||||
|
end # Padrino
|
|
@ -519,24 +519,24 @@ module Padrino
|
||||||
# Rewrite default routes.
|
# Rewrite default routes.
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# get :index # => "/"
|
# get :index # => "/"
|
||||||
# get :index, "/" # => "/"
|
# get :index, "/" # => "/"
|
||||||
# get :index, :map => "/" # => "/"
|
# get :index, :map => "/" # => "/"
|
||||||
# get :show, "/show-me" # => "/show-me"
|
# get :show, "/show-me" # => "/show-me"
|
||||||
# get :show, :map => "/show-me" # => "/show-me"
|
# get :show, :map => "/show-me" # => "/show-me"
|
||||||
# get "/foo/bar" # => "/show"
|
# get "/foo/bar" # => "/show"
|
||||||
# get :index, :parent => :user # => "/user/:user_id/index"
|
# get :index, :parent => :user # => "/user/:user_id/index"
|
||||||
# get :show, :with => :id, :parent => :user # => "/user/:user_id/show/:id"
|
# get :show, :with => :id, :parent => :user # => "/user/:user_id/show/:id"
|
||||||
# get :show, :with => :id # => "/show/:id"
|
# get :show, :with => :id # => "/show/:id"
|
||||||
# get [:show, :id] # => "/show/:id"
|
# get [:show, :id] # => "/show/:id"
|
||||||
# get :show, :with => [:id, :name] # => "/show/:id/:name"
|
# get :show, :with => [:id, :name] # => "/show/:id/:name"
|
||||||
# get [:show, :id, :name] # => "/show/:id/:name"
|
# get [:show, :id, :name] # => "/show/:id/:name"
|
||||||
# get :list, :provides => :js # => "/list.{:format,js)"
|
# get :list, :provides => :js # => "/list.{:format,js)"
|
||||||
# get :list, :provides => :any # => "/list(.:format)"
|
# get :list, :provides => :any # => "/list(.:format)"
|
||||||
# get :list, :provides => [:js, :json] # => "/list.{!format,js|json}"
|
# get :list, :provides => [:js, :json] # => "/list.{!format,js|json}"
|
||||||
# get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})"
|
# get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})"
|
||||||
# get :list, :priority => :low # Defers route to be last
|
# get :list, :priority => :low # Defers route to be last
|
||||||
#
|
# get /pattern/, :name => :foo, :generate_with => '/foo' # Generates :foo as /foo
|
||||||
def route(verb, path, *args, &block)
|
def route(verb, path, *args, &block)
|
||||||
options = case args.size
|
options = case args.size
|
||||||
when 2
|
when 2
|
||||||
|
@ -557,7 +557,7 @@ module Padrino
|
||||||
route_options = options.dup
|
route_options = options.dup
|
||||||
route_options[:provides] = @_provides if @_provides
|
route_options[:provides] = @_provides if @_provides
|
||||||
path, *route_options[:with] = path if path.is_a?(Array)
|
path, *route_options[:with] = path if path.is_a?(Array)
|
||||||
path, name, options = *parse_route(path, route_options, verb)
|
path, name, options, route_options = *parse_route(path, route_options, verb)
|
||||||
options.reverse_merge!(@_conditions) if @_conditions
|
options.reverse_merge!(@_conditions) if @_conditions
|
||||||
|
|
||||||
# Sinatra defaults
|
# Sinatra defaults
|
||||||
|
@ -571,7 +571,7 @@ module Padrino
|
||||||
invoke_hook(:route_added, verb, path, block)
|
invoke_hook(:route_added, verb, path, block)
|
||||||
|
|
||||||
# HTTPRouter route construction
|
# HTTPRouter route construction
|
||||||
route = router.add(path)
|
route = router.add(path, route_options)
|
||||||
route.name(name) if name
|
route.name(name) if name
|
||||||
priority_name = options.delete(:priority) || :normal
|
priority_name = options.delete(:priority) || :normal
|
||||||
priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
|
priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
|
||||||
|
@ -620,6 +620,9 @@ module Padrino
|
||||||
# We need save our originals path/options so we can perform correctly cache.
|
# We need save our originals path/options so we can perform correctly cache.
|
||||||
original = [path, options.dup]
|
original = [path, options.dup]
|
||||||
|
|
||||||
|
# options for the route directly
|
||||||
|
route_options = {}
|
||||||
|
|
||||||
# We need check if path is a symbol, if that it's a named route
|
# We need check if path is a symbol, if that it's a named route
|
||||||
map = options.delete(:map)
|
map = options.delete(:map)
|
||||||
|
|
||||||
|
@ -628,7 +631,11 @@ module Padrino
|
||||||
path = map ? map.dup : (path == :index ? '/' : path.to_s) # The route path
|
path = map ? map.dup : (path == :index ? '/' : path.to_s) # The route path
|
||||||
end
|
end
|
||||||
|
|
||||||
if path.kind_of?(String) # path i.e "/index" or "/show"
|
# Build our controller
|
||||||
|
controller = Array(@_controller).map { |c| c.to_s }
|
||||||
|
|
||||||
|
case path
|
||||||
|
when String # path i.e "/index" or "/show"
|
||||||
# Now we need to parse our 'with' params
|
# Now we need to parse our 'with' params
|
||||||
if with_params = options.delete(:with)
|
if with_params = options.delete(:with)
|
||||||
path = process_path_for_with_params(path, with_params)
|
path = process_path_for_with_params(path, with_params)
|
||||||
|
@ -643,9 +650,6 @@ module Padrino
|
||||||
options[:matching][:format] = /[^\.]+/
|
options[:matching][:format] = /[^\.]+/
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build our controller
|
|
||||||
controller = Array(@_controller).map { |c| c.to_s }
|
|
||||||
|
|
||||||
absolute_map = map && map[0] == ?/
|
absolute_map = map && map[0] == ?/
|
||||||
|
|
||||||
unless controller.empty?
|
unless controller.empty?
|
||||||
|
@ -656,10 +660,6 @@ module Padrino
|
||||||
path = File.join(controller_path, path)
|
path = File.join(controller_path, path)
|
||||||
end
|
end
|
||||||
# Here we build the correct name route
|
# Here we build the correct name route
|
||||||
if name
|
|
||||||
controller_name = controller.join("_")
|
|
||||||
name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Now we need to parse our 'parent' params and parent scope
|
# Now we need to parse our 'parent' params and parent scope
|
||||||
|
@ -678,12 +678,21 @@ module Padrino
|
||||||
path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
|
path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
|
||||||
path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
|
path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
|
||||||
path.squeeze!('/')
|
path.squeeze!('/')
|
||||||
|
when Regexp
|
||||||
|
route_options[:path_for_generation] = options.delete(:generate_with) if options.key?(:generate_with)
|
||||||
|
end
|
||||||
|
|
||||||
|
name = options.delete(:route_name) if name.nil? && options.key?(:route_name)
|
||||||
|
name = options.delete(:name) if name.nil? && options.key?(:name)
|
||||||
|
if name
|
||||||
|
controller_name = controller.join("_")
|
||||||
|
name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Merge in option defaults
|
# Merge in option defaults
|
||||||
options.reverse_merge!(:default_values => @_defaults)
|
options.reverse_merge!(:default_values => @_defaults)
|
||||||
|
|
||||||
[path, name, options]
|
[path, name, options, route_options]
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
|
@ -41,7 +41,6 @@ module Padrino
|
||||||
method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development
|
method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development
|
||||||
method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit."
|
method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit."
|
||||||
method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace."
|
method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace."
|
||||||
method_option :verbose, :type => :boolean, :aliases => "-v", :desc => "Log message to standard output."
|
|
||||||
def rake(*args)
|
def rake(*args)
|
||||||
prepare :rake
|
prepare :rake
|
||||||
args << "-T" if options[:list]
|
args << "-T" if options[:list]
|
||||||
|
@ -51,9 +50,8 @@ module Padrino
|
||||||
ARGV.clear
|
ARGV.clear
|
||||||
ARGV.concat(args)
|
ARGV.concat(args)
|
||||||
puts "=> Executing Rake #{ARGV.join(' ')} ..."
|
puts "=> Executing Rake #{ARGV.join(' ')} ..."
|
||||||
ENV['PADRINO_LOG_LEVEL'] ||= "test"
|
|
||||||
load File.expand_path('../rake.rb', __FILE__)
|
load File.expand_path('../rake.rb', __FILE__)
|
||||||
silence(:stdout) { require File.expand_path('config/boot.rb') }
|
require File.expand_path('config/boot.rb')
|
||||||
PadrinoTasks.init(true)
|
PadrinoTasks.init(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,10 +60,10 @@ module Padrino
|
||||||
prepare :console
|
prepare :console
|
||||||
require File.expand_path("../../version", __FILE__)
|
require File.expand_path("../../version", __FILE__)
|
||||||
ARGV.clear
|
ARGV.clear
|
||||||
puts "=> Loading #{options.environment} console (Padrino v.#{Padrino.version})"
|
|
||||||
require 'irb'
|
require 'irb'
|
||||||
require "irb/completion"
|
require "irb/completion"
|
||||||
require File.expand_path('config/boot.rb')
|
require File.expand_path('config/boot.rb')
|
||||||
|
puts "=> Loading #{Padrino.env} console (Padrino v.#{Padrino.version})"
|
||||||
require File.expand_path('../console', __FILE__)
|
require File.expand_path('../console', __FILE__)
|
||||||
IRB.start
|
IRB.start
|
||||||
end
|
end
|
||||||
|
@ -80,7 +78,8 @@ module Padrino
|
||||||
require 'padrino-core/command'
|
require 'padrino-core/command'
|
||||||
require 'padrino-gen/command'
|
require 'padrino-gen/command'
|
||||||
ARGV.shift
|
ARGV.shift
|
||||||
Padrino.bin_gen(ARGV)
|
ARGV << 'help' if ARGV.empty?
|
||||||
|
Padrino.bin_gen(*ARGV)
|
||||||
rescue
|
rescue
|
||||||
puts "<= You need padrino-gen! Run: gem install padrino-gen"
|
puts "<= You need padrino-gen! Run: gem install padrino-gen"
|
||||||
end
|
end
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -94,6 +94,7 @@ module Padrino
|
||||||
# Method for reloading required applications and their files.
|
# Method for reloading required applications and their files.
|
||||||
#
|
#
|
||||||
def reload!
|
def reload!
|
||||||
|
return unless Padrino::Reloader.changed?
|
||||||
Padrino.before_load.each(&:call) # Run before hooks
|
Padrino.before_load.each(&:call) # Run before hooks
|
||||||
Padrino::Reloader.reload! # detects the modified files
|
Padrino::Reloader.reload! # detects the modified files
|
||||||
Padrino.after_load.each(&:call) # Run after hooks
|
Padrino.after_load.each(&:call) # Run after hooks
|
|
@ -4,7 +4,7 @@ lv:
|
||||||
# Use the strftime parameters for formats.
|
# Use the strftime parameters for formats.
|
||||||
# When no format has been given, it uses default.
|
# When no format has been given, it uses default.
|
||||||
# You can provide other formats here if you like!
|
# You can provide other formats here if you like!
|
||||||
default: "%d.%m.%Y."
|
default: "%d.%m.%Y"
|
||||||
short: "%e. %B"
|
short: "%e. %B"
|
||||||
long: "%Y. gada %e. %B"
|
long: "%Y. gada %e. %B"
|
||||||
only_day: "%e"
|
only_day: "%e"
|
||||||
|
@ -21,7 +21,7 @@ lv:
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y. gada %e. %B, %H:%M"
|
default: "%Y. gada %e. %B, %H:%M"
|
||||||
short: "%d.%m.%Y., %H:%M"
|
short: "%d.%m.%Y, %H:%M"
|
||||||
long: "%Y. gada %e. %B, %H:%M:%S"
|
long: "%Y. gada %e. %B, %H:%M:%S"
|
||||||
am: "priekšpusdiena"
|
am: "priekšpusdiena"
|
||||||
pm: "pēcpusdiena"
|
pm: "pēcpusdiena"
|
|
@ -1,10 +1,10 @@
|
||||||
# Defines the log level for a Padrino project.
|
# Defines the log level for a Padrino project.
|
||||||
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
||||||
|
|
||||||
# Defines the logger used for a Padrino project.
|
# Defines the logger used for a Padrino project.
|
||||||
PADRINO_LOGGER = ENV['PADRINO_LOGGER'] unless defined?(PADRINO_LOGGER)
|
PADRINO_LOGGER = ENV['PADRINO_LOGGER'] unless defined?(PADRINO_LOGGER)
|
||||||
|
|
||||||
module Padrino
|
module Padrino
|
||||||
|
|
||||||
##
|
##
|
||||||
# @return [Padrino::Logger]
|
# @return [Padrino::Logger]
|
||||||
#
|
#
|
||||||
|
@ -35,21 +35,14 @@ module Padrino
|
||||||
# Padrino.logger = Buffered.new(STDOUT)
|
# Padrino.logger = Buffered.new(STDOUT)
|
||||||
#
|
#
|
||||||
def self.logger=(value)
|
def self.logger=(value)
|
||||||
|
value.extend(Padrino::Logger::Extensions) unless (Padrino::Logger::Extensions === value)
|
||||||
Thread.current[:padrino_logger] = value
|
Thread.current[:padrino_logger] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Extensions to the built in Ruby logger.
|
# Padrinos internal logger, using all of Padrino log extensions.
|
||||||
#
|
#
|
||||||
class Logger
|
class Logger
|
||||||
|
|
||||||
attr_accessor :level
|
|
||||||
attr_accessor :auto_flush
|
|
||||||
attr_reader :buffer
|
|
||||||
attr_reader :log
|
|
||||||
attr_reader :init_args
|
|
||||||
attr_accessor :log_static
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Ruby (standard) logger levels:
|
# Ruby (standard) logger levels:
|
||||||
#
|
#
|
||||||
|
@ -58,6 +51,7 @@ module Padrino
|
||||||
# :warn:: A warning
|
# :warn:: A warning
|
||||||
# :info:: generic (useful) information about system operation
|
# :info:: generic (useful) information about system operation
|
||||||
# :debug:: low-level information for developers
|
# :debug:: low-level information for developers
|
||||||
|
# :devel:: Development-related information that is unnecessary in debug mode
|
||||||
#
|
#
|
||||||
Levels = {
|
Levels = {
|
||||||
:fatal => 7,
|
:fatal => 7,
|
||||||
|
@ -68,6 +62,161 @@ module Padrino
|
||||||
:devel => -1,
|
:devel => -1,
|
||||||
} unless const_defined?(:Levels)
|
} unless const_defined?(:Levels)
|
||||||
|
|
||||||
|
module Extensions
|
||||||
|
##
|
||||||
|
# Generate the logging methods for {Padrino.logger} for each log level.
|
||||||
|
#
|
||||||
|
Padrino::Logger::Levels.each_pair do |name, number|
|
||||||
|
define_method(name) do |*args|
|
||||||
|
return if number < level
|
||||||
|
if args.size > 1
|
||||||
|
bench(args[0], args[1], args[2], name)
|
||||||
|
else
|
||||||
|
push(args * '', name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method(:"#{name}?") do
|
||||||
|
number >= level
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Append a to development logger a given action with time
|
||||||
|
#
|
||||||
|
# @param [string] action
|
||||||
|
# The action
|
||||||
|
#
|
||||||
|
# @param [float] time
|
||||||
|
# Time duration for the given action
|
||||||
|
#
|
||||||
|
# @param [message] string
|
||||||
|
# The message that you want to log
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# logger.bench 'GET', started_at, '/blog/categories'
|
||||||
|
# # => DEBUG - GET (0.056ms) - /blog/categories
|
||||||
|
#
|
||||||
|
def bench(action, began_at, message, level=:debug, color=:yellow)
|
||||||
|
@_pad ||= 8
|
||||||
|
@_pad = action.to_s.size if action.to_s.size > @_pad
|
||||||
|
duration = Time.now - began_at
|
||||||
|
color = :red if duration > 1
|
||||||
|
action = colorize(action.to_s.upcase.rjust(@_pad), color)
|
||||||
|
duration = colorize('%0.4fms' % duration, :bold, color)
|
||||||
|
push "#{action} (#{duration}) #{message}", level
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Appends a message to the log. The methods yield to an optional block and
|
||||||
|
# the output of this block will be appended to the message.
|
||||||
|
#
|
||||||
|
# @param [String] message
|
||||||
|
# The message that you want write to your stream
|
||||||
|
#
|
||||||
|
# @param [String] level
|
||||||
|
# The level one of :debug, :warn etc...
|
||||||
|
#
|
||||||
|
#
|
||||||
|
def push(message = nil, level = nil)
|
||||||
|
add(Padrino::Logger::Levels[level], format(message, level))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Formats the log message. This method is a noop and should be implemented by other
|
||||||
|
# logger components such as {Padrino::Logger}.
|
||||||
|
#
|
||||||
|
# @param [String] message
|
||||||
|
# The message to format
|
||||||
|
#
|
||||||
|
# @param [String,Symbol] level
|
||||||
|
# The log level, one of :debug, :warn...
|
||||||
|
def format(message, level)
|
||||||
|
message
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# The debug level, with some style added. May be reimplemented.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# stylized_level(:debug) => DEBUG
|
||||||
|
#
|
||||||
|
# @param [String,Symbol] level
|
||||||
|
# The log level
|
||||||
|
#
|
||||||
|
def stylized_level(level)
|
||||||
|
level.to_s.upcase.rjust(7)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Colorizes a string for colored console output. This is a noop and can be reimplemented
|
||||||
|
# to colorize the string as needed.
|
||||||
|
#
|
||||||
|
# @see
|
||||||
|
# ColorizedLogger
|
||||||
|
#
|
||||||
|
# @param [string]
|
||||||
|
# The string to be colorized.
|
||||||
|
#
|
||||||
|
# @param [Array<Symbol>]
|
||||||
|
# The colors to use. Should be applied in the order given.
|
||||||
|
def colorize(string, *colors)
|
||||||
|
string
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Turns a logger with LoggingExtensions into a logger with colorized output.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# Padrino.logger = Logger.new($stdout)
|
||||||
|
# Padrino.logger.colorize!
|
||||||
|
# Padrino.logger.debug("Fancy Padrino debug string")
|
||||||
|
def colorize!
|
||||||
|
self.extend(Colorize)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Colorize
|
||||||
|
# Colors for levels
|
||||||
|
ColoredLevels = {
|
||||||
|
:fatal => [:bold, :red],
|
||||||
|
:error => [:red],
|
||||||
|
:warn => [:yellow],
|
||||||
|
:info => [:green],
|
||||||
|
:debug => [:cyan],
|
||||||
|
:devel => [:magenta]
|
||||||
|
} unless defined?(ColoredLevels)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Colorize our level
|
||||||
|
#
|
||||||
|
# @param [String, Symbol] level
|
||||||
|
#
|
||||||
|
# @see Padrino::Logging::ColorizedLogger::ColoredLevels
|
||||||
|
#
|
||||||
|
def colorize(string, *colors)
|
||||||
|
colors.each do |c|
|
||||||
|
string = string.send(c)
|
||||||
|
end
|
||||||
|
string
|
||||||
|
end
|
||||||
|
|
||||||
|
def stylized_level(level)
|
||||||
|
style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * ''
|
||||||
|
[style, super, "\e[0m"] * ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
include Extensions
|
||||||
|
include Colorize
|
||||||
|
|
||||||
|
attr_accessor :level
|
||||||
|
attr_accessor :auto_flush
|
||||||
|
attr_reader :buffer
|
||||||
|
attr_reader :log
|
||||||
|
attr_reader :init_args
|
||||||
|
attr_accessor :log_static
|
||||||
|
|
||||||
@@mutex = {}
|
@@mutex = {}
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -110,16 +259,6 @@ module Padrino
|
||||||
}
|
}
|
||||||
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
||||||
|
|
||||||
# Colors for levels
|
|
||||||
ColoredLevels = {
|
|
||||||
:fatal => [:bold, :red],
|
|
||||||
:error => [:red],
|
|
||||||
:warn => [:yellow],
|
|
||||||
:info => [:green],
|
|
||||||
:debug => [:cyan],
|
|
||||||
:devel => [:magenta]
|
|
||||||
} unless defined?(ColoredLevels)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Setup a new logger
|
# Setup a new logger
|
||||||
#
|
#
|
||||||
|
@ -137,13 +276,14 @@ module Padrino
|
||||||
|
|
||||||
stream = case config[:stream]
|
stream = case config[:stream]
|
||||||
when :to_file
|
when :to_file
|
||||||
FileUtils.mkdir_p(Padrino.root("log")) unless File.exists?(Padrino.root("log"))
|
FileUtils.mkdir_p(Padrino.root('log')) unless File.exists?(Padrino.root('log'))
|
||||||
File.new(Padrino.root("log", "#{Padrino.env}.log"), "a+")
|
File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
|
||||||
when :null then StringIO.new
|
when :null then StringIO.new
|
||||||
when :stdout then $stdout
|
when :stdout then $stdout
|
||||||
when :stderr then $stderr
|
when :stderr then $stderr
|
||||||
else config[:stream] # return itself, probabilly is a custom stream.
|
else config[:stream] # return itself, probabilly is a custom stream.
|
||||||
end
|
end
|
||||||
|
|
||||||
Thread.current[:padrino_logger] = Padrino::Logger.new(config.merge(:stream => stream))
|
Thread.current[:padrino_logger] = Padrino::Logger.new(config.merge(:stream => stream))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -174,7 +314,7 @@ module Padrino
|
||||||
def initialize(options={})
|
def initialize(options={})
|
||||||
@buffer = []
|
@buffer = []
|
||||||
@auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
|
@auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
|
||||||
@level = options[:log_level] ? Levels[options[:log_level]] : Levels[:debug]
|
@level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
|
||||||
@log = options[:stream] || $stdout
|
@log = options[:stream] || $stdout
|
||||||
@log.sync = true
|
@log.sync = true
|
||||||
@mutex = @@mutex[@log] ||= Mutex.new
|
@mutex = @@mutex[@log] ||= Mutex.new
|
||||||
|
@ -183,18 +323,6 @@ module Padrino
|
||||||
@log_static = options.has_key?(:log_static) ? options[:log_static] : false
|
@log_static = options.has_key?(:log_static) ? options[:log_static] : false
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
|
||||||
# Colorize our level
|
|
||||||
#
|
|
||||||
# @param [String, Symbol] level
|
|
||||||
#
|
|
||||||
# @see Padrino::Logger::ColoredLevels
|
|
||||||
#
|
|
||||||
def colored_level(level)
|
|
||||||
style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * ''
|
|
||||||
[style, level.to_s.upcase.rjust(7), "\e[0m"] * ''
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Flush the entire buffer to the log object.
|
# Flush the entire buffer to the log object.
|
||||||
#
|
#
|
||||||
|
@ -217,42 +345,11 @@ module Padrino
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Appends a message to the log. The methods yield to an optional block and
|
# Adds a message to the log - for compatibility with other loggers.
|
||||||
# the output of this block will be appended to the message.
|
|
||||||
#
|
#
|
||||||
# @param [String] message
|
# @private
|
||||||
# The message that you want write to your stream
|
def add(level, message = nil)
|
||||||
#
|
write(message)
|
||||||
# @param [String] level
|
|
||||||
# The level one of :debug, :warn etc...
|
|
||||||
#
|
|
||||||
#
|
|
||||||
def push(message = nil, level = nil)
|
|
||||||
write @format_message % [colored_level(level), Time.now.strftime(@format_datetime).yellow, message.to_s.strip]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Append a to development logger a given action with time
|
|
||||||
#
|
|
||||||
# @param [string] action
|
|
||||||
# The action
|
|
||||||
#
|
|
||||||
# @param [float] time
|
|
||||||
# Time duration for the given action
|
|
||||||
#
|
|
||||||
# @param [message] string
|
|
||||||
# The message that you want to log
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# logger.bench 'GET', started_at, '/blog/categories'
|
|
||||||
# # => DEBUG - GET (0.056ms) - /blog/categories
|
|
||||||
#
|
|
||||||
def bench(action, began_at, message, level=:debug, color=:yellow)
|
|
||||||
@_pad ||= 8
|
|
||||||
@_pad = action.to_s.size if action.to_s.size > @_pad
|
|
||||||
duration = Time.now - began_at
|
|
||||||
color = :red if duration > 1
|
|
||||||
push "%s (" % action.to_s.upcase.rjust(@_pad).send(color) + "%0.4fms".bold.send(color) % duration + ") %s" % message.to_s, level
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -269,22 +366,8 @@ module Padrino
|
||||||
end
|
end
|
||||||
alias :write :<<
|
alias :write :<<
|
||||||
|
|
||||||
##
|
def format(message, level)
|
||||||
# Generate the logging methods for {Padrino.logger} for each log level.
|
@format_message % [stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip]
|
||||||
#
|
|
||||||
Levels.each_pair do |name, number|
|
|
||||||
define_method(name) do |*args|
|
|
||||||
return if number < level
|
|
||||||
if args.size > 1
|
|
||||||
bench(*args)
|
|
||||||
else
|
|
||||||
push(args * '', name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
define_method(:"#{name}?") do
|
|
||||||
number >= level
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -301,7 +384,6 @@ module Padrino
|
||||||
|
|
||||||
def call(env) # @private
|
def call(env) # @private
|
||||||
env['rack.logger'] = Padrino.logger
|
env['rack.logger'] = Padrino.logger
|
||||||
env['rack.errors'] = Padrino.logger.log
|
|
||||||
began_at = Time.now
|
began_at = Time.now
|
||||||
status, header, body = @app.call(env)
|
status, header, body = @app.call(env)
|
||||||
log(env, status, header, began_at)
|
log(env, status, header, began_at)
|
||||||
|
@ -309,28 +391,28 @@ module Padrino
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def log(env, status, header, began_at)
|
def log(env, status, header, began_at)
|
||||||
return if env['sinatra.static_file'] and !logger.log_static
|
return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static)
|
||||||
logger.bench(
|
logger.bench(
|
||||||
env["REQUEST_METHOD"],
|
env["REQUEST_METHOD"],
|
||||||
began_at,
|
began_at,
|
||||||
[
|
[
|
||||||
@uri_root.to_s,
|
@uri_root.to_s,
|
||||||
env["PATH_INFO"],
|
env["PATH_INFO"],
|
||||||
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
||||||
' - ',
|
' - ',
|
||||||
status.to_s[0..3].bold,
|
logger.colorize(status.to_s[0..3], :bold),
|
||||||
' ',
|
' ',
|
||||||
code_to_name(status)
|
code_to_name(status)
|
||||||
] * '',
|
] * '',
|
||||||
:debug,
|
:debug,
|
||||||
:magenta
|
:magenta
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def code_to_name(status)
|
def code_to_name(status)
|
||||||
::Rack::Utils::HTTP_STATUS_CODES[status.to_i] || ''
|
::Rack::Utils::HTTP_STATUS_CODES[status.to_i] || ''
|
||||||
end
|
end
|
||||||
end # Rack
|
end # Rack
|
||||||
end # Logger
|
end # Logger
|
||||||
end # Padrino
|
end # Padrino
|
||||||
|
@ -343,3 +425,4 @@ module Kernel # @private
|
||||||
Padrino.logger
|
Padrino.logger
|
||||||
end
|
end
|
||||||
end # Kernel
|
end # Kernel
|
||||||
|
|
|
@ -92,7 +92,7 @@ module Padrino
|
||||||
changed = false
|
changed = false
|
||||||
rotation do |file, mtime|
|
rotation do |file, mtime|
|
||||||
new_file = MTIMES[file].nil?
|
new_file = MTIMES[file].nil?
|
||||||
previous_mtime = MTIMES[file] ||= mtime
|
previous_mtime = MTIMES[file]
|
||||||
changed = true if new_file || mtime > previous_mtime
|
changed = true if new_file || mtime > previous_mtime
|
||||||
end
|
end
|
||||||
changed
|
changed
|
||||||
|
@ -103,7 +103,7 @@ module Padrino
|
||||||
# We lock dependencies sets to prevent reloading of protected constants
|
# We lock dependencies sets to prevent reloading of protected constants
|
||||||
#
|
#
|
||||||
def lock!
|
def lock!
|
||||||
klasses = ObjectSpace.classes.map { |klass| klass.name.to_s.split("::")[0] }.uniq
|
klasses = ObjectSpace.classes.map { |klass| klass.name.split('::')[0] }.uniq
|
||||||
klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class }
|
klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class }
|
||||||
Padrino::Reloader.exclude_constants.concat(klasses)
|
Padrino::Reloader.exclude_constants.concat(klasses)
|
||||||
end
|
end
|
||||||
|
@ -183,50 +183,50 @@ module Padrino
|
||||||
# Removes the specified class and constant.
|
# Removes the specified class and constant.
|
||||||
#
|
#
|
||||||
def remove_constant(const)
|
def remove_constant(const)
|
||||||
return if exclude_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) } &&
|
return if exclude_constants.compact.uniq.any? { |c| const.name.index(c) == 0 } &&
|
||||||
!include_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) }
|
!include_constants.compact.uniq.any? { |c| const.name.index(c) == 0 }
|
||||||
begin
|
begin
|
||||||
parts = const.to_s.split("::")
|
parts = const.to_s.sub(/^::(Object)?/, 'Object::').split('::')
|
||||||
base = parts.size == 1 ? Object : parts[0..-2].join("::").constantize
|
object = parts.pop
|
||||||
object = parts[-1].to_s
|
base = parts.empty? ? Object : Inflector.constantize(parts * '::')
|
||||||
base.send(:remove_const, object)
|
base.send :remove_const, object
|
||||||
logger.devel "Removed constant: #{const}"
|
logger.devel "Removed constant: #{const} from #{base}"
|
||||||
rescue NameError; end
|
rescue NameError; end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
##
|
##
|
||||||
# Return the mounted_apps providing the app location
|
# Return the mounted_apps providing the app location
|
||||||
# Can be an array because in one app.rb we can define multiple Padrino::Appplications
|
# Can be an array because in one app.rb we can define multiple Padrino::Appplications
|
||||||
#
|
#
|
||||||
def mounted_apps_of(file)
|
def mounted_apps_of(file)
|
||||||
file = figure_path(file)
|
file = figure_path(file)
|
||||||
Padrino.mounted_apps.find_all { |app| File.identical?(file, app.app_file) }
|
Padrino.mounted_apps.find_all { |app| File.identical?(file, app.app_file) }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns true if file is in our Padrino.root
|
# Returns true if file is in our Padrino.root
|
||||||
#
|
#
|
||||||
def in_root?(file)
|
def in_root?(file)
|
||||||
# This is better but slow:
|
# This is better but slow:
|
||||||
# Pathname.new(Padrino.root).find { |f| File.identical?(Padrino.root(f), figure_path(file)) }
|
# Pathname.new(Padrino.root).find { |f| File.identical?(Padrino.root(f), figure_path(file)) }
|
||||||
figure_path(file) =~ %r{^#{Regexp.escape(Padrino.root)}}
|
figure_path(file).index(Padrino.root) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths
|
# Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths
|
||||||
# and monitors them for any changes.
|
# and monitors them for any changes.
|
||||||
#
|
#
|
||||||
def rotation
|
def rotation
|
||||||
files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
|
files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
|
||||||
files = files | Padrino.mounted_apps.map { |app| app.app_file }
|
files = files | Padrino.mounted_apps.map { |app| app.app_file }
|
||||||
files = files | Padrino.mounted_apps.map { |app| app.app_obj.dependencies }.flatten
|
files = files | Padrino.mounted_apps.map { |app| app.app_obj.dependencies }.flatten
|
||||||
files.uniq.map { |file|
|
files.uniq.map do |file|
|
||||||
file = File.expand_path(file)
|
file = File.expand_path(file)
|
||||||
next if Padrino::Reloader.exclude.any? { |base| file =~ %r{^#{Regexp.escape(base)}} } || !File.exist?(file)
|
next if Padrino::Reloader.exclude.any? { |base| file.index(base) == 0 } || !File.exist?(file)
|
||||||
yield(file, File.mtime(file))
|
yield file, File.mtime(file)
|
||||||
}.compact
|
end.compact
|
||||||
end
|
end
|
||||||
end # self
|
end # self
|
||||||
|
|
||||||
##
|
##
|
|
@ -17,7 +17,7 @@ module Padrino
|
||||||
#
|
#
|
||||||
class Server < Rack::Server
|
class Server < Rack::Server
|
||||||
# Server Handlers
|
# Server Handlers
|
||||||
Handlers = [:thin, :mongrel, :webrick]
|
Handlers = [:thin, :mongrel, :trinidad, :webrick]
|
||||||
|
|
||||||
# Starts the application on the available server with specified options.
|
# Starts the application on the available server with specified options.
|
||||||
def self.start(app, opts={})
|
def self.start(app, opts={})
|
||||||
|
@ -44,7 +44,7 @@ module Padrino
|
||||||
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
||||||
super
|
super
|
||||||
ensure
|
ensure
|
||||||
puts "<= Padrino has ended his set (crowd applauds)" unless options[:daemonize]
|
puts "<= Padrino leaves the gun, takes the cannoli" unless options[:daemonize]
|
||||||
end
|
end
|
||||||
|
|
||||||
# The application the server will run.
|
# The application the server will run.
|
|
@ -11,7 +11,7 @@ require 'active_support/inflector/methods' # constantize
|
||||||
require 'active_support/inflector/inflections' # pluralize
|
require 'active_support/inflector/inflections' # pluralize
|
||||||
require 'active_support/inflections' # load default inflections
|
require 'active_support/inflections' # load default inflections
|
||||||
require 'yaml' unless defined?(YAML) # load yaml for i18n
|
require 'yaml' unless defined?(YAML) # load yaml for i18n
|
||||||
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/ # ruby color suppor for win
|
require 'win32console' if RUBY_PLATFORM =~ /(win|m)32/ # ruby color support for win
|
||||||
|
|
||||||
##
|
##
|
||||||
# This is an adapted version of active_support/core_ext/string/inflections.rb
|
# This is an adapted version of active_support/core_ext/string/inflections.rb
|
||||||
|
@ -113,8 +113,8 @@ module ObjectSpace
|
||||||
# Returns all the classes in the object space.
|
# Returns all the classes in the object space.
|
||||||
def classes
|
def classes
|
||||||
ObjectSpace.each_object(Module).select do |klass|
|
ObjectSpace.each_object(Module).select do |klass|
|
||||||
# Why this? Ruby when you remove a constant don't clean it from
|
# Why? Ruby, when you remove a costant dosen't remove it from
|
||||||
# rb_tables, this mean that here we can found classes that was
|
# rb_tables, this mean that here we can find classes that was
|
||||||
# removed.
|
# removed.
|
||||||
klass.name rescue false
|
klass.name rescue false
|
||||||
end
|
end
|
||||||
|
@ -191,8 +191,7 @@ end
|
||||||
##
|
##
|
||||||
# Loads our locale configuration files
|
# Loads our locale configuration files
|
||||||
#
|
#
|
||||||
|
### I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n) ### !!! FIXME middleman ###
|
||||||
# I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Used to determine if this file has already been required
|
# Used to determine if this file has already been required
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
module Padrino
|
module Padrino
|
||||||
# The version constant for the current version of Padrino.
|
# The version constant for the current version of Padrino.
|
||||||
VERSION = '0.10.5' unless defined?(Padrino::VERSION)
|
VERSION = '0.10.6' unless defined?(Padrino::VERSION)
|
||||||
|
|
||||||
#
|
#
|
||||||
# The current Padrino version.
|
# The current Padrino version.
|
|
@ -34,5 +34,5 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency("sinatra", "~> 1.3.1")
|
s.add_dependency("sinatra", "~> 1.3.1")
|
||||||
s.add_dependency("http_router", "~> 0.10.2")
|
s.add_dependency("http_router", "~> 0.10.2")
|
||||||
s.add_dependency("thor", "~> 0.14.3")
|
s.add_dependency("thor", "~> 0.14.3")
|
||||||
s.add_dependency("activesupport", "~> 3.1.0")
|
s.add_dependency("activesupport", "~> 3.2.0")
|
||||||
end
|
end
|
|
@ -44,6 +44,8 @@ class MiniTest::Spec
|
||||||
else
|
else
|
||||||
super(name, *args, &block)
|
super(name, *args, &block)
|
||||||
end
|
end
|
||||||
|
rescue Rack::Test::Error # no response yet
|
||||||
|
super(name, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :response :last_response
|
alias :response :last_response
|
|
@ -15,7 +15,6 @@ describe "Core" do
|
||||||
assert_respond_to Padrino, :load!
|
assert_respond_to Padrino, :load!
|
||||||
assert_respond_to Padrino, :reload!
|
assert_respond_to Padrino, :reload!
|
||||||
assert_respond_to Padrino, :version
|
assert_respond_to Padrino, :version
|
||||||
assert_respond_to Padrino, :bundle
|
|
||||||
assert_respond_to Padrino, :configure_apps
|
assert_respond_to Padrino, :configure_apps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,7 +22,6 @@ describe "Core" do
|
||||||
should 'validate global helpers' do
|
should 'validate global helpers' do
|
||||||
assert_equal :test, Padrino.env
|
assert_equal :test, Padrino.env
|
||||||
assert_match /\/test/, Padrino.root
|
assert_match /\/test/, Padrino.root
|
||||||
assert_equal nil, Padrino.bundle
|
|
||||||
assert_not_nil Padrino.version
|
assert_not_nil Padrino.version
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
||||||
|
require 'lumberjack'
|
||||||
|
require 'logger'
|
||||||
|
|
||||||
describe "PadrinoLogger" do
|
describe "PadrinoLogger" do
|
||||||
|
|
||||||
|
@ -98,3 +100,55 @@ describe "PadrinoLogger" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "alternate logger: Lumberjack" do
|
||||||
|
def setup_logger
|
||||||
|
@log = StringIO.new
|
||||||
|
Padrino.logger = Lumberjack::Logger.new(@log, :level => :debug)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "annotate the logger to support additional Padrino fancyness" do
|
||||||
|
setup_logger
|
||||||
|
Padrino.logger.debug("Debug message")
|
||||||
|
assert_match(/Debug message/, @log.string)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "colorize log output after colorize! is called" do
|
||||||
|
setup_logger
|
||||||
|
Padrino.logger.colorize!
|
||||||
|
|
||||||
|
mock_app do
|
||||||
|
enable :logging
|
||||||
|
get("/"){ "Foo" }
|
||||||
|
end
|
||||||
|
get "/"
|
||||||
|
|
||||||
|
assert_match /\e\[1m200\e\[0m OK/, @log.string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "alternate logger: stdlib logger" do
|
||||||
|
def setup_logger
|
||||||
|
@log = StringIO.new
|
||||||
|
Padrino.logger = Logger.new(@log)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "annotate the logger to support additional Padrino fancyness" do
|
||||||
|
setup_logger
|
||||||
|
Padrino.logger.debug("Debug message")
|
||||||
|
assert_match(/Debug message/, @log.string)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "colorize log output after colorize! is called" do
|
||||||
|
setup_logger
|
||||||
|
Padrino.logger.colorize!
|
||||||
|
|
||||||
|
mock_app do
|
||||||
|
enable :logging
|
||||||
|
get("/"){ "Foo" }
|
||||||
|
end
|
||||||
|
get "/"
|
||||||
|
|
||||||
|
assert_match /\e\[1m200\e\[0m OK/, @log.string
|
||||||
|
end
|
||||||
|
end
|
|
@ -78,6 +78,13 @@ describe "Routing" do
|
||||||
assert_equal "My lucky number: 99 99", body
|
assert_equal "My lucky number: 99 99", body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should 'accept regexp routes with generate with :generate_with' do
|
||||||
|
mock_app do
|
||||||
|
get(%r{/fob|/baz}, :name => :foo, :generate_with => '/fob') { "regexp" }
|
||||||
|
end
|
||||||
|
assert_equal "/fob", @app.url(:foo)
|
||||||
|
end
|
||||||
|
|
||||||
should "parse routes with question marks" do
|
should "parse routes with question marks" do
|
||||||
mock_app do
|
mock_app do
|
||||||
get("/foo/?"){ "okey" }
|
get("/foo/?"){ "okey" }
|
|
@ -1,103 +0,0 @@
|
||||||
module Padrino
|
|
||||||
module Helpers
|
|
||||||
##
|
|
||||||
# Helpers related to producing html tags within templates.
|
|
||||||
#
|
|
||||||
module TagHelpers
|
|
||||||
##
|
|
||||||
# Tag values escaped to html entities
|
|
||||||
#
|
|
||||||
ESCAPE_VALUES = {
|
|
||||||
"<" => "<",
|
|
||||||
">" => ">",
|
|
||||||
'"' => """
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Creates an html tag with given name, content and options
|
|
||||||
#
|
|
||||||
# @overload content_tag(name, content, options)
|
|
||||||
# @param [Symbol] name The html type of tag.
|
|
||||||
# @param [String] content The contents in the tag.
|
|
||||||
# @param [Hash] options The html options to include in this tag.
|
|
||||||
# @overload content_tag(name, options, &block)
|
|
||||||
# @param [Symbol] name The html type of tag.
|
|
||||||
# @param [Hash] options The html options to include in this tag.
|
|
||||||
# @param [Proc] block The block returning html content
|
|
||||||
#
|
|
||||||
# @return [String] The html generated for the tag.
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# content_tag(:p, "hello", :class => 'light')
|
|
||||||
# content_tag(:p, :class => 'dark') { ... }
|
|
||||||
#
|
|
||||||
# @api public
|
|
||||||
def content_tag(*args, &block)
|
|
||||||
name = args.first
|
|
||||||
options = args.extract_options!
|
|
||||||
tag_html = block_given? ? capture_html(&block) : args[1]
|
|
||||||
tag_result = tag(name, options.merge(:content => tag_html))
|
|
||||||
block_is_template?(block) ? concat_content(tag_result) : tag_result
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Creates an html input field with given type and options
|
|
||||||
#
|
|
||||||
# @param [Symbol] type
|
|
||||||
# The html type of tag to create.
|
|
||||||
# @param [Hash] options
|
|
||||||
# The html options to include in this tag.
|
|
||||||
#
|
|
||||||
# @return [String] The html for the input tag.
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# input_tag :text, :class => "test"
|
|
||||||
# input_tag :password, :size => "20"
|
|
||||||
#
|
|
||||||
# @api semipublic
|
|
||||||
def input_tag(type, options = {})
|
|
||||||
options.reverse_merge!(:type => type)
|
|
||||||
tag(:input, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Creates an html tag with the given name and options
|
|
||||||
#
|
|
||||||
# @param [Symbol] type
|
|
||||||
# The html type of tag to create.
|
|
||||||
# @param [Hash] options
|
|
||||||
# The html options to include in this tag.
|
|
||||||
#
|
|
||||||
# @return [String] The html for the input tag.
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# tag(:br, :style => 'clear:both')
|
|
||||||
# tag(:p, :content => "hello", :class => 'large')
|
|
||||||
#
|
|
||||||
# @api public
|
|
||||||
def tag(name, options={})
|
|
||||||
content, open_tag = options.delete(:content), options.delete(:open)
|
|
||||||
content = content.join("\n") if content.respond_to?(:join)
|
|
||||||
identity_tag_attributes.each { |attr| options[attr] = attr.to_s if options[attr] }
|
|
||||||
html_attrs = options.map { |a, v| v.nil? || v == false ? nil : "#{a}=\"#{escape_value(v)}\"" }.compact.join(" ")
|
|
||||||
base_tag = (html_attrs.present? ? "<#{name} #{html_attrs}" : "<#{name}")
|
|
||||||
base_tag << (open_tag ? ">" : (content ? ">#{content}</#{name}>" : " />"))
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
##
|
|
||||||
# Returns a list of attributes which can only contain an identity value (i.e selected)
|
|
||||||
#
|
|
||||||
def identity_tag_attributes
|
|
||||||
[:checked, :disabled, :selected, :multiple]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Escape tag values to their HTML/XML entities.
|
|
||||||
#
|
|
||||||
def escape_value(string)
|
|
||||||
string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)){|c| ESCAPE_VALUES[c] }
|
|
||||||
end
|
|
||||||
end # TagHelpers
|
|
||||||
end # Helpers
|
|
||||||
end # Padrino
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite' unless defined?(SupportLite)
|
require 'middleman-core/vendor/padrino-core-0.10.6/lib/padrino-core/support_lite' unless defined?(SupportLite) ### !!! FIXME middleman ###
|
||||||
|
### require 'padrino-core/support_lite' unless defined?(SupportLite) ### !!! FIXME middleman ###
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
# require 'i18n'
|
### require 'i18n' ### !!! FIXME middleman ###
|
||||||
require 'enumerator'
|
require 'enumerator'
|
||||||
require 'active_support/core_ext/string/conversions' # to_date
|
require 'active_support/core_ext/string/conversions' # to_date
|
||||||
require 'active_support/core_ext/float/rounding' # round
|
require 'active_support/core_ext/float/rounding' # round
|
||||||
|
@ -11,7 +12,7 @@ require 'active_support/inflector' # humanize
|
||||||
FileSet.glob_require('padrino-helpers/**/*.rb', __FILE__)
|
FileSet.glob_require('padrino-helpers/**/*.rb', __FILE__)
|
||||||
|
|
||||||
# Load our locales
|
# Load our locales
|
||||||
# I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"]
|
### I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"] ### !!! FIXME middleman ###
|
||||||
|
|
||||||
module Padrino
|
module Padrino
|
||||||
##
|
##
|
|
@ -17,13 +17,18 @@ module Padrino
|
||||||
# @example
|
# @example
|
||||||
# flash_tag(:notice, :id => 'flash-notice')
|
# flash_tag(:notice, :id => 'flash-notice')
|
||||||
# # Generates: <div class="notice">flash-notice</div>
|
# # Generates: <div class="notice">flash-notice</div>
|
||||||
|
# flash_tag(:error, :success)
|
||||||
|
# # Generates: <div class="error">flash-error</div>
|
||||||
|
# # <div class="success">flash-success</div>
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def flash_tag(kind, options={})
|
def flash_tag(*args)
|
||||||
flash_text = flash[kind]
|
options = args.extract_options!
|
||||||
return '' if flash_text.blank?
|
args.map do |kind|
|
||||||
options.reverse_merge!(:class => kind)
|
flash_text = flash[kind]
|
||||||
content_tag(:div, flash_text, options)
|
next if flash_text.blank?
|
||||||
|
content_tag(:div, flash_text, options.reverse_merge(:class => kind))
|
||||||
|
end.compact * "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -65,18 +70,17 @@ module Padrino
|
||||||
# @api public
|
# @api public
|
||||||
def link_to(*args, &block)
|
def link_to(*args, &block)
|
||||||
options = args.extract_options!
|
options = args.extract_options!
|
||||||
options = parse_js_attributes(options) # parses remote, method and confirm options
|
|
||||||
anchor = "##{CGI.escape options.delete(:anchor).to_s}" if options[:anchor]
|
anchor = "##{CGI.escape options.delete(:anchor).to_s}" if options[:anchor]
|
||||||
|
|
||||||
if block_given?
|
if block_given?
|
||||||
url = args[0] ? args[0] + anchor.to_s : anchor || 'javascript:void(0);'
|
url = args[0] ? args[0] + anchor.to_s : anchor || '#'
|
||||||
options.reverse_merge!(:href => url)
|
options.reverse_merge!(:href => url)
|
||||||
link_content = capture_html(&block)
|
link_content = capture_html(&block)
|
||||||
return '' unless parse_conditions(url, options)
|
return '' unless parse_conditions(url, options)
|
||||||
result_link = content_tag(:a, link_content, options)
|
result_link = content_tag(:a, link_content, options)
|
||||||
block_is_template?(block) ? concat_content(result_link) : result_link
|
block_is_template?(block) ? concat_content(result_link) : result_link
|
||||||
else
|
else
|
||||||
name, url = args[0], (args[1] ? args[1] + anchor.to_s : anchor || 'javascript:void(0);')
|
name, url = args[0], (args[1] ? args[1] + anchor.to_s : anchor || '#')
|
||||||
return name unless parse_conditions(url, options)
|
return name unless parse_conditions(url, options)
|
||||||
options.reverse_merge!(:href => url)
|
options.reverse_merge!(:href => url)
|
||||||
content_tag(:a, name, options)
|
content_tag(:a, name, options)
|
||||||
|
@ -119,8 +123,8 @@ module Padrino
|
||||||
desired_method = options[:method]
|
desired_method = options[:method]
|
||||||
options.delete(:method) if options[:method].to_s !~ /get|post/i
|
options.delete(:method) if options[:method].to_s !~ /get|post/i
|
||||||
options.reverse_merge!(:method => 'post', :action => url)
|
options.reverse_merge!(:method => 'post', :action => url)
|
||||||
options[:enctype] = "multipart/form-data" if options.delete(:multipart)
|
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
||||||
options["data-remote"] = "true" if options.delete(:remote)
|
options['data-remote'] = 'true' if options.delete(:remote)
|
||||||
inner_form_html = hidden_form_method_field(desired_method)
|
inner_form_html = hidden_form_method_field(desired_method)
|
||||||
inner_form_html += block_given? ? capture_html(&block) : submit_tag(name)
|
inner_form_html += block_given? ? capture_html(&block) : submit_tag(name)
|
||||||
content_tag('form', inner_form_html, options)
|
content_tag('form', inner_form_html, options)
|
||||||
|
@ -153,7 +157,7 @@ module Padrino
|
||||||
# @api public
|
# @api public
|
||||||
def feed_tag(mime, url, options={})
|
def feed_tag(mime, url, options={})
|
||||||
full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml'
|
full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml'
|
||||||
content_tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url))
|
tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -291,9 +295,9 @@ module Padrino
|
||||||
# @api public
|
# @api public
|
||||||
def javascript_include_tag(*sources)
|
def javascript_include_tag(*sources)
|
||||||
options = sources.extract_options!.symbolize_keys
|
options = sources.extract_options!.symbolize_keys
|
||||||
options.reverse_merge!(:type => 'text/javascript', :content => "")
|
options.reverse_merge!(:type => 'text/javascript')
|
||||||
sources.flatten.map { |source|
|
sources.flatten.map { |source|
|
||||||
tag(:script, options.reverse_merge(:src => asset_path(:js, source)))
|
content_tag(:script, nil, options.reverse_merge(:src => asset_path(:js, source)))
|
||||||
}.join("\n")
|
}.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -338,83 +342,76 @@ module Padrino
|
||||||
# @api semipublic
|
# @api semipublic
|
||||||
def asset_path(kind, source)
|
def asset_path(kind, source)
|
||||||
return source if source =~ /^http/
|
return source if source =~ /^http/
|
||||||
asset_folder = case kind
|
is_absolute = source =~ %r{^/}
|
||||||
when :css then 'stylesheets'
|
asset_folder = asset_folder_name(kind)
|
||||||
when :js then 'javascripts'
|
|
||||||
else kind.to_s
|
|
||||||
end
|
|
||||||
source = source.to_s.gsub(/\s/, '%20')
|
source = source.to_s.gsub(/\s/, '%20')
|
||||||
ignore_extension = (asset_folder.to_s == kind.to_s) # don't append extension
|
ignore_extension = (asset_folder.to_s == kind.to_s) # don't append an extension
|
||||||
source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/
|
source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/
|
||||||
result_path = source if source =~ %r{^/} # absolute path
|
result_path = is_absolute ? source : uri_root_path(asset_folder, source)
|
||||||
result_path ||= uri_root_path(asset_folder, source)
|
timestamp = asset_timestamp(result_path, is_absolute)
|
||||||
timestamp = asset_timestamp(result_path)
|
|
||||||
"#{result_path}#{timestamp}"
|
"#{result_path}#{timestamp}"
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
##
|
||||||
|
# Returns the uri root of the application with optional paths appended.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# uri_root_path("/some/path") => "/root/some/path"
|
||||||
|
# uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js"
|
||||||
|
#
|
||||||
|
def uri_root_path(*paths)
|
||||||
|
root_uri = self.class.uri_root if self.class.respond_to?(:uri_root)
|
||||||
|
File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns the uri root of the application.
|
# Returns the timestamp mtime for an asset
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# uri_root_path("/some/path") => "/base/some/path"
|
# asset_timestamp("some/path/to/file.png") => "?154543678"
|
||||||
#
|
# asset_timestamp("/some/absolute/path.png", true) => nil
|
||||||
def uri_root_path(*paths)
|
#
|
||||||
root_uri = self.class.uri_root if self.class.respond_to?(:uri_root)
|
def asset_timestamp(file_path, absolute=false)
|
||||||
File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths)
|
return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp)
|
||||||
end
|
public_file_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root)
|
||||||
|
stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path)
|
||||||
|
stamp ||= Time.now.to_i unless absolute
|
||||||
|
"?#{stamp}" if stamp
|
||||||
|
end
|
||||||
|
|
||||||
##
|
###
|
||||||
# Returns the timestamp mtime for an asset
|
# Returns the asset folder given a kind.
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# asset_timestamp("some/path/to/file.png") => "?154543678"
|
# asset_folder_name(:css) => 'stylesheets'
|
||||||
#
|
# asset_folder_name(:js) => 'javascripts'
|
||||||
def asset_timestamp(file_path)
|
# asset_folder_name(:images) => 'images'
|
||||||
return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp)
|
#
|
||||||
public_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root)
|
def asset_folder_name(kind)
|
||||||
stamp = Time.now.to_i unless public_path && File.exist?(public_path)
|
case kind
|
||||||
stamp ||= File.mtime(public_path).to_i
|
when :css then 'stylesheets'
|
||||||
"?#{stamp}"
|
when :js then 'javascripts'
|
||||||
|
else kind.to_s
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Parses link_to options for given correct conditions
|
# Parses link_to options for given correct conditions
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# parse_conditions("/some/url", :if => false) => true
|
# parse_conditions("/some/url", :if => false) => true
|
||||||
#
|
#
|
||||||
def parse_conditions(url, options)
|
def parse_conditions(url, options)
|
||||||
if options.has_key?(:if)
|
if options.has_key?(:if)
|
||||||
condition = options.delete(:if)
|
condition = options.delete(:if)
|
||||||
condition == :current ? url == request.path_info : condition
|
condition == :current ? url == request.path_info : condition
|
||||||
elsif condition = options.delete(:unless)
|
elsif condition = options.delete(:unless)
|
||||||
condition == :current ? url != request.path_info : !condition
|
condition == :current ? url != request.path_info : !condition
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Parses link_to options for given js declarations (remote, method, confirm)
|
|
||||||
# Not destructive on options; returns updated options
|
|
||||||
#
|
|
||||||
# parse_js_attributes(:remote => true, :confirm => "test", :method => :delete)
|
|
||||||
# => { "data-remote" => true, "data-method" => "delete", "data-confirm" => "test" }
|
|
||||||
#
|
|
||||||
def parse_js_attributes(options)
|
|
||||||
options = options.dup
|
|
||||||
options["data-remote"] = "true" if options.delete(:remote)
|
|
||||||
if link_confirm = options.delete(:confirm)
|
|
||||||
options["data-confirm"] = link_confirm
|
|
||||||
end
|
|
||||||
if link_method = options.delete(:method)
|
|
||||||
options["data-method"] = link_method
|
|
||||||
options["rel"] = "nofollow"
|
|
||||||
end
|
|
||||||
options
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end # AssetTagHelpers
|
end # AssetTagHelpers
|
||||||
end # Helpers
|
end # Helpers
|
||||||
end # Padrino
|
end # Padrino
|
|
@ -42,6 +42,37 @@ module Padrino
|
||||||
@template.text_field_tag field_name(field), options
|
@template.text_field_tag field_name(field), options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def number_field(field, options={})
|
||||||
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||||
|
options.merge!(:class => field_error(field, options))
|
||||||
|
@template.number_field_tag field_name(field), options
|
||||||
|
end
|
||||||
|
|
||||||
|
def telephone_field(field, options={})
|
||||||
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||||
|
options.merge!(:class => field_error(field, options))
|
||||||
|
@template.telephone_field_tag field_name(field), options
|
||||||
|
end
|
||||||
|
alias_method :phone_field, :telephone_field
|
||||||
|
|
||||||
|
def email_field(field, options={})
|
||||||
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||||
|
options.merge!(:class => field_error(field, options))
|
||||||
|
@template.email_field_tag field_name(field), options
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_field(field, options={})
|
||||||
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||||
|
options.merge!(:class => field_error(field, options))
|
||||||
|
@template.search_field_tag field_name(field), options
|
||||||
|
end
|
||||||
|
|
||||||
|
def url_field(field, options={})
|
||||||
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||||
|
options.merge!(:class => field_error(field, options))
|
||||||
|
@template.url_field_tag field_name(field), options
|
||||||
|
end
|
||||||
|
|
||||||
# f.text_area :summary, :value => "(enter summary)", :id => 'summary'
|
# f.text_area :summary, :value => "(enter summary)", :id => 'summary'
|
||||||
def text_area(field, options={})
|
def text_area(field, options={})
|
||||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
|
@ -74,13 +74,11 @@ module Padrino
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def form_tag(url, options={}, &block)
|
def form_tag(url, options={}, &block)
|
||||||
desired_method = options[:method]
|
desired_method = options[:method].to_s
|
||||||
data_method = options.delete(:method) if options[:method].to_s !~ /get|post/i
|
options.delete(:method) unless desired_method =~ /get|post/i
|
||||||
options.reverse_merge!(:method => "post", :action => url)
|
options.reverse_merge!(:method => 'post', :action => url)
|
||||||
options[:enctype] = "multipart/form-data" if options.delete(:multipart)
|
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
||||||
options["data-remote"] = "true" if options.delete(:remote)
|
options['accept-charset'] ||= 'UTF-8'
|
||||||
options["data-method"] = data_method if data_method
|
|
||||||
options["accept-charset"] ||= "UTF-8"
|
|
||||||
inner_form_html = hidden_form_method_field(desired_method)
|
inner_form_html = hidden_form_method_field(desired_method)
|
||||||
inner_form_html += capture_html(&block)
|
inner_form_html += capture_html(&block)
|
||||||
concat_content content_tag(:form, inner_form_html, options)
|
concat_content content_tag(:form, inner_form_html, options)
|
||||||
|
@ -140,9 +138,9 @@ module Padrino
|
||||||
# @param [Hash] options Error message display options.
|
# @param [Hash] options Error message display options.
|
||||||
# @option options [String] :header_tag ("h2")
|
# @option options [String] :header_tag ("h2")
|
||||||
# Used for the header of the error div
|
# Used for the header of the error div
|
||||||
# @option options [String] :id ("errorExplanation")
|
# @option options [String] :id ("field-errors")
|
||||||
# The id of the error div.
|
# The id of the error div.
|
||||||
# @option options [String] :class ("errorExplanation")
|
# @option options [String] :class ("field-errors")
|
||||||
# The class of the error div.
|
# The class of the error div.
|
||||||
# @option options [Array<Object>] :object
|
# @option options [Array<Object>] :object
|
||||||
# The object (or array of objects) for which to display errors,
|
# The object (or array of objects) for which to display errors,
|
||||||
|
@ -222,7 +220,7 @@ module Padrino
|
||||||
# The field on the +object+ to display the error for.
|
# The field on the +object+ to display the error for.
|
||||||
# @param [Hash] options
|
# @param [Hash] options
|
||||||
# The options to control the error display.
|
# The options to control the error display.
|
||||||
# @option options [String] :tag ("div")
|
# @option options [String] :tag ("span")
|
||||||
# The tag that encloses the error.
|
# The tag that encloses the error.
|
||||||
# @option options [String] :prepend ("")
|
# @option options [String] :prepend ("")
|
||||||
# The text to prepend before the field error.
|
# The text to prepend before the field error.
|
||||||
|
@ -289,29 +287,216 @@ module Padrino
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructs a text field input from the given options
|
# Creates a text field input with the given name and options
|
||||||
#
|
#
|
||||||
# @macro [new] input_field_doc
|
# @macro [new] text_field
|
||||||
# @param [String] name
|
# @param [Symbol] name
|
||||||
# The name of the input field.
|
# The name of the input to create.
|
||||||
# @param [Hash] options
|
# @param [Hash] options
|
||||||
# The html options for the input field.
|
# The HTML options to include in this field.
|
||||||
#
|
#
|
||||||
# @return [String] The html input field based on the +options+ specified
|
# @option options [String] :id
|
||||||
|
# Specifies a unique identifier for the field.
|
||||||
|
# @option options [String] :class
|
||||||
|
# Specifies the stylesheet class of the field.
|
||||||
|
# @option options [String] :name
|
||||||
|
# Specifies the name of the field.
|
||||||
|
# @option options [String] :accesskey
|
||||||
|
# Specifies a shortcut key to access the field.
|
||||||
|
# @option options [Integer] :tabindex
|
||||||
|
# Specifies the tab order of the field.
|
||||||
|
# @option options [Integer] :maxlength
|
||||||
|
# Specifies the maximum length, in characters, of the field.
|
||||||
|
# @option options [Integer] :size
|
||||||
|
# Specifies the width, in characters, of the field.
|
||||||
|
# @option options [String] :placeholder
|
||||||
|
# Specifies a short hint that describes the expected value of the field.
|
||||||
|
# @option options [Boolean] :hidden
|
||||||
|
# Specifies whether or not the field is hidden from view.
|
||||||
|
# @option options [Boolean] :spellcheck
|
||||||
|
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
||||||
|
# @option options [Boolean] :draggable
|
||||||
|
# Specifies whether or not the field is draggable. (true, false, :auto)
|
||||||
|
# @option options [String] :pattern
|
||||||
|
# Specifies the regular expression pattern that the field's value is checked against.
|
||||||
|
# @option options [Symbol] :autocomplete
|
||||||
|
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
||||||
|
# @option options [Boolean] :autofocus
|
||||||
|
# Specifies whether or not the field should automatically get focus when the page loads.
|
||||||
|
# @option options [Boolean] :required
|
||||||
|
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
||||||
|
# @option options [Boolean] :readonly
|
||||||
|
# Specifies whether or not the field is read only.
|
||||||
|
# @option options [Boolean] :disabled
|
||||||
|
# Specifies whether or not the field is disabled.
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
# Generated HTML with specified +options+
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# text_field_tag :username, :class => 'long'
|
# text_field_tag :first_name, :maxlength => 40, :required => true
|
||||||
|
# # => <input name="first_name" maxlength="40" required type="text">
|
||||||
|
#
|
||||||
|
# text_field_tag :last_name, :class => 'string', :size => 40
|
||||||
|
# # => <input name="last_name" class="string" size="40" type="text">
|
||||||
|
#
|
||||||
|
# text_field_tag :username, :placeholder => 'Your Username'
|
||||||
|
# # => <input name="username" placeholder="Your Username" type="text">
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def text_field_tag(name, options={})
|
def text_field_tag(name, options={})
|
||||||
options.reverse_merge!(:name => name)
|
input_tag(:text, options.reverse_merge!(:name => name))
|
||||||
input_tag(:text, options)
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates a number field input with the given name and options
|
||||||
|
#
|
||||||
|
# @macro [new] number_field
|
||||||
|
# @param [Symbol] name
|
||||||
|
# The name of the input to create.
|
||||||
|
# @param [Hash] options
|
||||||
|
# The HTML options to include in this field.
|
||||||
|
#
|
||||||
|
# @option options [String] :id
|
||||||
|
# Specifies a unique identifier for the field.
|
||||||
|
# @option options [String] :class
|
||||||
|
# Specifies the stylesheet class of the field.
|
||||||
|
# @option options [String] :name
|
||||||
|
# Specifies the name of the field.
|
||||||
|
# @option options [String] :accesskey
|
||||||
|
# Specifies a shortcut key to access the field.
|
||||||
|
# @option options [Integer] :tabindex
|
||||||
|
# Specifies the tab order of the field.
|
||||||
|
# @option options [Integer] :min
|
||||||
|
# Specifies the minimum value of the field.
|
||||||
|
# @option options [Integer] :max
|
||||||
|
# Specifies the maximum value of the field.
|
||||||
|
# @option options [Integer] :step
|
||||||
|
# Specifies the legal number intervals of the field.
|
||||||
|
# @option options [Boolean] :hidden
|
||||||
|
# Specifies whether or not the field is hidden from view.
|
||||||
|
# @option options [Boolean] :spellcheck
|
||||||
|
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
||||||
|
# @option options [Boolean] :draggable
|
||||||
|
# Specifies whether or not the field is draggable. (true, false, :auto)
|
||||||
|
# @option options [String] :pattern
|
||||||
|
# Specifies the regular expression pattern that the field's value is checked against.
|
||||||
|
# @option options [Symbol] :autocomplete
|
||||||
|
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
||||||
|
# @option options [Boolean] :autofocus
|
||||||
|
# Specifies whether or not the field should automatically get focus when the page loads.
|
||||||
|
# @option options [Boolean] :required
|
||||||
|
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
||||||
|
# @option options [Boolean] :readonly
|
||||||
|
# Specifies whether or not the field is read only.
|
||||||
|
# @option options [Boolean] :disabled
|
||||||
|
# Specifies whether or not the field is disabled.
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
# Generated HTML with specified +options+
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# number_field_tag :quanity, :class => 'numeric'
|
||||||
|
# # => <input name="quanity" class="numeric" type="number">
|
||||||
|
#
|
||||||
|
# number_field_tag :zip_code, :pattern => /[0-9]{5}/
|
||||||
|
# # => <input name="zip_code" pattern="[0-9]{5}" type="number">
|
||||||
|
#
|
||||||
|
# number_field_tag :credit_card, :autocomplete => :off
|
||||||
|
# # => <input name="credit_card" autocomplete="off" type="number">
|
||||||
|
#
|
||||||
|
# number_field_tag :age, :min => 18, :max => 120, :step => 1
|
||||||
|
# # => <input name="age" min="18" max="120" step="1" type="number">
|
||||||
|
#
|
||||||
|
# @api public
|
||||||
|
def number_field_tag(name, options={})
|
||||||
|
input_tag(:number, options.reverse_merge(:name => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates a telephone field input with the given name and options
|
||||||
|
#
|
||||||
|
# @macro text_field
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# telephone_field_tag :phone_number, :class => 'string'
|
||||||
|
# # => <input name="phone_number" class="string" type="tel">
|
||||||
|
#
|
||||||
|
# telephone_field_tag :cell_phone, :tabindex => 1
|
||||||
|
# telephone_field_tag :work_phone, :tabindex => 2
|
||||||
|
# telephone_field_tag :home_phone, :tabindex => 3
|
||||||
|
#
|
||||||
|
# # => <input name="cell_phone" tabindex="1" type="tel">
|
||||||
|
# # => <input name="work_phone" tabindex="2" type="tel">
|
||||||
|
# # => <input name="home_phone" tabindex="3" type="tel">
|
||||||
|
#
|
||||||
|
# @api public
|
||||||
|
def telephone_field_tag(name, options={})
|
||||||
|
input_tag(:tel, options.reverse_merge(:name => name))
|
||||||
|
end
|
||||||
|
alias_method :phone_field_tag, :telephone_field_tag
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates an email field input with the given name and options
|
||||||
|
#
|
||||||
|
# @macro text_field
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# email_field_tag :email, :placeholder => 'you@example.com'
|
||||||
|
# # => <input name="email" placeholder="you@example.com" type="email">
|
||||||
|
#
|
||||||
|
# email_field_tag :email, :value => 'padrinorb@gmail.com', :readonly => true
|
||||||
|
# # => <input name="email" value="padrinorb@gmail.com" readonly type="email">
|
||||||
|
#
|
||||||
|
# @api public
|
||||||
|
def email_field_tag(name, options={})
|
||||||
|
input_tag(:email, options.reverse_merge(:name => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates a search field input with the given name and options
|
||||||
|
#
|
||||||
|
# @macro text_field
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# search_field_tag :search, :placeholder => 'Search this website...'
|
||||||
|
# # => <input name="search" placeholder="Search this website..." type="search">
|
||||||
|
#
|
||||||
|
# search_field_tag :search, :maxlength => 15, :class => ['search', 'string']
|
||||||
|
# # => <input name="search" maxlength="15" class="search string">
|
||||||
|
#
|
||||||
|
# search_field_tag :search, :id => 'search'
|
||||||
|
# # => <input name="search" id="search" type="search">
|
||||||
|
#
|
||||||
|
# search_field_tag :search, :autofocus => true
|
||||||
|
# # => <input name="search" autofocus type="search">
|
||||||
|
#
|
||||||
|
# @api public
|
||||||
|
def search_field_tag(name, options={})
|
||||||
|
input_tag(:search, options.reverse_merge(:name => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates a url field input with the given name and options
|
||||||
|
#
|
||||||
|
# @macro text_field
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# url_field_tag :favorite_website, :placeholder => 'http://padrinorb.com'
|
||||||
|
# <input name="favorite_website" placeholder="http://padrinorb.com." type="url">
|
||||||
|
#
|
||||||
|
# url_field_tag :home_page, :class => 'string url'
|
||||||
|
# <input name="home_page" class="string url", type="url">
|
||||||
|
#
|
||||||
|
# @api public
|
||||||
|
def url_field_tag(name, options={})
|
||||||
|
input_tag(:url, options.reverse_merge(:name => name))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructs a hidden field input from the given options
|
# Constructs a hidden field input from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# hidden_field_tag :session_key, :value => "__secret__"
|
# hidden_field_tag :session_key, :value => "__secret__"
|
||||||
|
@ -325,7 +510,7 @@ module Padrino
|
||||||
##
|
##
|
||||||
# Constructs a text area input from the given options
|
# Constructs a text area input from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# text_area_tag :username, :class => 'long', :value => "Demo?"
|
# text_area_tag :username, :class => 'long', :value => "Demo?"
|
||||||
|
@ -339,7 +524,7 @@ module Padrino
|
||||||
##
|
##
|
||||||
# Constructs a password field input from the given options
|
# Constructs a password field input from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# password_field_tag :password, :class => 'long'
|
# password_field_tag :password, :class => 'long'
|
||||||
|
@ -353,7 +538,7 @@ module Padrino
|
||||||
##
|
##
|
||||||
# Constructs a check_box from the given options
|
# Constructs a check_box from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# check_box_tag :remember_me, :value => 'Yes'
|
# check_box_tag :remember_me, :value => 'Yes'
|
||||||
|
@ -367,7 +552,7 @@ module Padrino
|
||||||
##
|
##
|
||||||
# Constructs a radio_button from the given options
|
# Constructs a radio_button from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# radio_button_tag :remember_me, :value => 'true'
|
# radio_button_tag :remember_me, :value => 'true'
|
||||||
|
@ -381,7 +566,7 @@ module Padrino
|
||||||
##
|
##
|
||||||
# Constructs a file field input from the given options
|
# Constructs a file field input from the given options
|
||||||
#
|
#
|
||||||
# @macro input_field_doc
|
# @macro text_field
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# file_field_tag :photo, :class => 'long'
|
# file_field_tag :photo, :class => 'long'
|
|
@ -81,7 +81,7 @@ module Padrino
|
||||||
# @api public
|
# @api public
|
||||||
def simple_format(text, options={})
|
def simple_format(text, options={})
|
||||||
t = options.delete(:tag) || :p
|
t = options.delete(:tag) || :p
|
||||||
start_tag = tag(t, options.merge(:open => true))
|
start_tag = tag(t, options, true)
|
||||||
text = text.to_s.dup
|
text = text.to_s.dup
|
||||||
text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
|
text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
|
||||||
text.gsub!(/\n\n+/, "</#{t}>\n\n#{start_tag}") # 2+ newline -> paragraph
|
text.gsub!(/\n\n+/, "</#{t}>\n\n#{start_tag}") # 2+ newline -> paragraph
|
||||||
|
@ -375,7 +375,7 @@ module Padrino
|
||||||
javascript_mapping = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
|
javascript_mapping = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
|
||||||
html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { javascript_mapping[$1] }
|
html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { javascript_mapping[$1] }
|
||||||
end
|
end
|
||||||
|
alias :escape_javascript :js_escape_html
|
||||||
end # FormatHelpers
|
end # FormatHelpers
|
||||||
end # Helpers
|
end # Helpers
|
||||||
end # Padrino
|
end # Padrino
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue