diff --git a/src/kemal.cr b/src/kemal.cr index 3262341..713b1d7 100644 --- a/src/kemal.cr +++ b/src/kemal.cr @@ -7,26 +7,26 @@ require "./kemal/ext/*" require "./kemal/helpers/*" module Kemal - # Overload of self.run with the default startup logging + # Overload of `self.run` with the default startup logging. def self.run(port : Int32?) self.run port do log "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}" end end - # Overload of self.run without port - fixex #399 + # Overload of `self.run` without port. def self.run self.run(nil) end - # Overload of self.run to allow just a block + # Overload of `self.run` to allow just a block. def self.run(&block) self.run nil, &block end # The command to run a `Kemal` application. - # The port can be given to `#run` but is optional. - # If not given Kemal will use `Kemal::Config#port` + # + # If *port* is not given Kemal will use `Kemal::Config#port` def self.run(port : Int32? = nil, &block) Kemal::CLI.new config = Kemal.config @@ -61,7 +61,7 @@ module Kemal config.server ||= HTTP::Server.new(config.host_binding, config.port, config.handlers) {% if !flag?(:without_openssl) %} - config.server.not_nil!.tls = config.ssl + config.server.not_nil!.tls = config.ssl {% end %} config.running = true diff --git a/src/kemal/common_exception_handler.cr b/src/kemal/common_exception_handler.cr index 2862d99..1a1f883 100644 --- a/src/kemal/common_exception_handler.cr +++ b/src/kemal/common_exception_handler.cr @@ -1,5 +1,5 @@ module Kemal - # Kemal::CommonExceptionHandler handles all the exceptions including 404, custom errors and 500. + # Handles all the exceptions, including 404, custom errors and 500. class CommonExceptionHandler include HTTP::Handler INSTANCE = new diff --git a/src/kemal/common_log_handler.cr b/src/kemal/common_log_handler.cr index 99b68ad..9643434 100644 --- a/src/kemal/common_log_handler.cr +++ b/src/kemal/common_log_handler.cr @@ -1,5 +1,5 @@ module Kemal - # Kemal::CommonLogHandler uses STDOUT by default and handles the logging of request/response process time. + # Uses `STDOUT` by default and handles the logging of request/response process time. class CommonLogHandler < Kemal::BaseLogHandler @io : IO diff --git a/src/kemal/config.cr b/src/kemal/config.cr index 30cbe2d..1c7f837 100644 --- a/src/kemal/config.cr +++ b/src/kemal/config.cr @@ -1,9 +1,10 @@ module Kemal - # Kemal::Config stores all the configuration options for a Kemal application. + # Stores all the configuration options for a Kemal application. # It's a singleton and you can access it like. # - # Kemal.config - # + # ``` + # Kemal.config + # ``` class Config INSTANCE = Config.new HANDLERS = [] of HTTP::Handler @@ -12,9 +13,9 @@ module Kemal ERROR_HANDLERS = {} of Int32 => HTTP::Server::Context, Exception -> String {% if flag?(:without_openssl) %} - @ssl : Bool? + @ssl : Bool? {% else %} - @ssl : OpenSSL::SSL::Context::Server? + @ssl : OpenSSL::SSL::Context::Server? {% end %} getter custom_handler_position diff --git a/src/kemal/dsl.cr b/src/kemal/dsl.cr index c005e15..15b3742 100644 --- a/src/kemal/dsl.cr +++ b/src/kemal/dsl.cr @@ -1,5 +1,7 @@ # Kemal DSL is defined here and it's baked into global scope. -# The DSL currently consists of +# +# The DSL currently consists of: +# # - get post put patch delete options # - WebSocket(ws) # - before_* diff --git a/src/kemal/ext/context.cr b/src/kemal/ext/context.cr index 143e098..e76f7b3 100644 --- a/src/kemal/ext/context.cr +++ b/src/kemal/ext/context.cr @@ -1,5 +1,6 @@ -# HTTP::Server::Context is the class which holds HTTP::Request and HTTP::Server::Response alongside with -# information such as request params, request/response content_type, session e.g +# `HTTP::Server::Context` is the class which holds `HTTP::Request` and +# `HTTP::Server::Response` alongside with information such as request params, +# request/response content_type, session data and alike. # # Instances of this class are passed to an `HTTP::Server` handler. class HTTP::Server diff --git a/src/kemal/filter_handler.cr b/src/kemal/filter_handler.cr index 9cc7409..1d842f2 100644 --- a/src/kemal/filter_handler.cr +++ b/src/kemal/filter_handler.cr @@ -10,7 +10,7 @@ module Kemal Kemal.config.add_filter_handler(self) end - # The call order of the filters is before_all -> before_x -> X -> after_x -> after_all + # The call order of the filters is `before_all -> before_x -> X -> after_x -> after_all`. def call(context : HTTP::Server::Context) return call_next(context) unless context.route_defined? call_block_for_path_type("ALL", context.request.path, :before, context) @@ -24,7 +24,8 @@ module Kemal context end - # :nodoc: This shouldn't be called directly, it's not private because I need to call it for testing purpose since I can't call the macros in the spec. + # :nodoc: This shouldn't be called directly, it's not private because + # I need to call it for testing purpose since I can't call the macros in the spec. # It adds the block for the corresponding verb/path/type combination to the tree. def _add_route_filter(verb : String, path, type, &block : HTTP::Server::Context -> _) lookup = lookup_filters_for_path_type(verb, path, type) @@ -35,12 +36,16 @@ module Kemal end end - # This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter` + # This can be called directly but it's simpler to just use the macros, + # it will check if another filter is not already defined for this + # verb/path/type and proceed to call `add_route_filter` def before(verb : String, path : String = "*", &block : HTTP::Server::Context -> _) _add_route_filter verb, path, :before, &block end - # This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter` + # This can be called directly but it's simpler to just use the macros, + # it will check if another filter is not already defined for this + # verb/path/type and proceed to call `add_route_filter` def after(verb : String, path : String = "*", &block : HTTP::Server::Context -> _) _add_route_filter verb, path, :after, &block end diff --git a/src/kemal/handler.cr b/src/kemal/handler.cr index 9fdbbb0..2102bf4 100644 --- a/src/kemal/handler.cr +++ b/src/kemal/handler.cr @@ -1,5 +1,6 @@ module Kemal # `Kemal::Handler` is a subclass of `HTTP::Handler`. + # # It adds `only`, `only_match?`, `exclude`, `exclude_match?`. # These methods are useful for custom handlers for conditional execution. class Handler @@ -32,14 +33,16 @@ module Kemal # # However this is not done automatically. All handlers must inherit from `Kemal::Handler`. # - # class OnlyHandler < Kemal::Handler - # only ["/"] + # ``` + # class OnlyHandler < Kemal::Handler + # only ["/"] # - # def call(env) - # return call_next(env) unless only_match?(env) - # puts "If the path is / i will be doing some processing here." - # end - # end + # def call(env) + # return call_next(env) unless only_match?(env) + # puts "If the path is / i will be doing some processing here." + # end + # end + # ``` def only_match?(env : HTTP::Server::Context) @@only_routes_tree.find(radix_path(env.request.method, env.request.path)).found? end @@ -51,14 +54,16 @@ module Kemal # # However this is not done automatically. All handlers must inherit from `Kemal::Handler`. # - # class ExcludeHandler < Kemal::Handler - # exclude ["/"] + # ``` + # class ExcludeHandler < Kemal::Handler + # exclude ["/"] # - # def call(env) - # return call_next(env) if exclude_match?(env) - # puts "If the path is not / i will be doing some processing here." - # end - # end + # def call(env) + # return call_next(env) if exclude_match?(env) + # puts "If the path is not / i will be doing some processing here." + # end + # end + # ``` def exclude_match?(env : HTTP::Server::Context) @@exclude_routes_tree.find(radix_path(env.request.method, env.request.path)).found? end diff --git a/src/kemal/helpers/helpers.cr b/src/kemal/helpers/helpers.cr index a0eb787..ed23c9c 100644 --- a/src/kemal/helpers/helpers.cr +++ b/src/kemal/helpers/helpers.cr @@ -1,13 +1,13 @@ -# Adds given Kemal::Handler to handlers chain. +# Adds given `Kemal::Handler` to handlers chain. # There are 5 handlers by default and all the custom handlers # goes between the first 4 and the last `Kemal::RouteHandler`. # -# - Kemal::InitHandler -# - Kemal::CommonLogHandler -# - Kemal::CommonExceptionHandler -# - Kemal::StaticFileHandler +# - `Kemal::InitHandler` +# - `Kemal::CommonLogHandler` +# - `Kemal::CommonExceptionHandler` +# - `Kemal::StaticFileHandler` # - Here goes custom handlers -# - Kemal::RouteHandler +# - `Kemal::RouteHandler` def add_handler(handler : HTTP::Handler) Kemal.config.add_handler handler end @@ -17,6 +17,7 @@ def add_handler(handler : HTTP::Handler, position : Int32) end # Sets public folder from which the static assets will be served. +# # By default this is `/public` not `src/public`. def public_folder(path : String) Kemal.config.public_folder = path @@ -31,7 +32,9 @@ end # Enables / Disables logging. # This is enabled by default. # -# logging false +# ``` +# logging false +# ``` def logging(status : Bool) Kemal.config.logging = status end @@ -41,22 +44,26 @@ end # A custom logger must inherit from `Kemal::BaseLogHandler` and must implement # `call(env)`, `write(message)` methods. # -# class MyCustomLogger < Kemal::BaseLogHandler +# ``` +# class MyCustomLogger < Kemal::BaseLogHandler # -# def call(env) -# puts "I'm logging some custom stuff here." -# call_next(env) # => This calls the next handler -# end -# -# # This is used from `log` method. -# def write(message) -# STDERR.puts message # => Logs the output to STDERR -# end +# def call(env) +# puts "I'm logging some custom stuff here." +# call_next(env) # => This calls the next handler # end # +# # This is used from `log` method. +# def write(message) +# STDERR.puts message # => Logs the output to STDERR +# end +# end +# ``` +# # Now that we have a custom logger here's how we use it # -# logger MyCustomLogger.new +# ``` +# logger MyCustomLogger.new +# ``` def logger(logger : Kemal::BaseLogHandler) Kemal.config.logger = logger Kemal.config.add_handler logger @@ -65,12 +72,16 @@ end # Enables / Disables static file serving. # This is enabled by default. # +# ``` # serve_static false +# ``` # # Static server also have some advanced customization options like `dir_listing` and # `gzip`. # +# ``` # serve_static {"gzip" => true, "dir_listing" => false} +# ``` def serve_static(status : (Bool | Hash)) Kemal.config.serve_static = status end @@ -78,9 +89,11 @@ end # Helper for easily modifying response headers. # This can be used to modify a response header with the given hash. # -# def call(env) -# headers(env, {"custom-header" => "This is a custom value"}) -# end +# ``` +# def call(env) +# headers(env, {"X-Custom-Header" => "This is a custom value"}) +# end +# ``` def headers(env : HTTP::Server::Context, additional_headers : Hash(String, String)) env.response.headers.merge!(additional_headers) end @@ -88,11 +101,15 @@ end # Send a file with given path and base the mime-type on the file extension # or default `application/octet-stream` mime_type. # -# send_file env, "./path/to/file" +# ``` +# send_file env, "./path/to/file" +# ``` # # Optionally you can override the mime_type # -# send_file env, "./path/to/file", "image/jpeg" +# ``` +# send_file env, "./path/to/file", "image/jpeg" +# ``` def send_file(env : HTTP::Server::Context, path : String, mime_type : String? = nil) config = Kemal.config.serve_static file_path = File.expand_path(path, Dir.current) @@ -184,11 +201,15 @@ end # Send a file with given data and default `application/octet-stream` mime_type. # -# send_file env, data_slice +# ``` +# send_file env, data_slice +# ``` # # Optionally you can override the mime_type # -# send_file env, data_slice, "image/jpeg" +# ``` +# send_file env, data_slice, "image/jpeg" +# ``` def send_file(env : HTTP::Server::Context, data : Slice(UInt8), mime_type : String? = nil) mime_type ||= "application/octet-stream" env.response.content_type = mime_type @@ -198,14 +219,15 @@ end # Configures an `HTTP::Server::Response` to compress the response # output, either using gzip or deflate, depending on the `Accept-Encoding` request header. -# It's disabled by default. +# +# Disabled by default. def gzip(status : Bool = false) add_handler HTTP::CompressHandler.new if status end # Adds headers to `Kemal::StaticFileHandler`. This is especially useful for `CORS`. # -# ```ruby +# ``` # static_headers do |response, filepath, filestat| # if filepath =~ /\.html$/ # response.headers.add("Access-Control-Allow-Origin", "*") diff --git a/src/kemal/helpers/macros.cr b/src/kemal/helpers/macros.cr index e217197..4b5e309 100644 --- a/src/kemal/helpers/macros.cr +++ b/src/kemal/helpers/macros.cr @@ -13,16 +13,20 @@ CONTENT_FOR_BLOCKS = Hash(String, Tuple(String, Proc(String))).new # You call `content_for`, generally from a view, to capture a block of markup # giving it an identifier: # -# # index.ecr -# <% content_for "some_key" do %> -# ... -# <% end %> +# ``` +# # index.ecr +# <% content_for "some_key" do %> +# ... +# <% end %> +# ``` # # Then, you call `yield_content` with that identifier, generally from a # layout, to render the captured block: # -# # layout.ecr -# <%= yield_content "some_key" %> +# ``` +# # layout.ecr +# <%= yield_content "some_key" %> +# ``` # # ## And How Is This Useful? # @@ -53,8 +57,9 @@ end # Render view with a layout as the superview. # -# render "src/views/index.ecr", "src/views/layout.ecr" -# +# ``` +# render "src/views/index.ecr", "src/views/layout.ecr" +# ``` macro render(filename, layout) __content_filename__ = {{filename}} content = render {{filename}} @@ -69,7 +74,9 @@ end # Halt execution with the current context. # Returns 200 and an empty response by default. # -# halt env, status_code: 403, response: "Forbidden" +# ``` +# halt env, status_code: 403, response: "Forbidden" +# ``` macro halt(env, status_code = 200, response = "") {{env}}.response.status_code = {{status_code}} {{env}}.response.print {{response}} @@ -79,12 +86,13 @@ end # Extends context storage with user defined types. # +# ``` # class User # property name # end # # add_context_storage_type(User) -# +# ``` macro add_context_storage_type(type) {{ HTTP::Server::Context::STORE_MAPPINGS.push(type) }} end diff --git a/src/kemal/init_handler.cr b/src/kemal/init_handler.cr index 3c61f33..4728949 100644 --- a/src/kemal/init_handler.cr +++ b/src/kemal/init_handler.cr @@ -1,6 +1,6 @@ module Kemal - # Kemal::InitHandler is the first handler thus initializes the context with default values. - # Such as *Content-Type*, *X-Powered-By* headers. + # Initializes the context with default values, such as + # *Content-Type* or *X-Powered-By* headers. class InitHandler include HTTP::Handler INSTANCE = new diff --git a/src/kemal/param_parser.cr b/src/kemal/param_parser.cr index e2a4ca8..b8a6c35 100644 --- a/src/kemal/param_parser.cr +++ b/src/kemal/param_parser.cr @@ -1,7 +1,7 @@ module Kemal - # ParamParser parses the request contents including query_params and body - # and converts them into a params hash which you can within the environment - # context. + # Parses the request contents including query_params and body + # and converts them into a params hash which you can use within + # the environment context. class ParamParser URL_ENCODED_FORM = "application/x-www-form-urlencoded" APPLICATION_JSON = "application/json" @@ -78,9 +78,9 @@ module Kemal end # Parses JSON request body if Content-Type is `application/json`. - # If request body is a JSON Hash then all the params are parsed and added into `params`. - # If request body is a JSON Array it's added into `params` as `_json` and can be accessed - # like params["_json"] + # + # - If request body is a JSON `Hash` then all the params are parsed and added into `params`. + # - If request body is a JSON `Array` it's added into `params` as `_json` and can be accessed like `params["_json"]`. private def parse_json return unless @request.body && @request.headers["Content-Type"]?.try(&.starts_with?(APPLICATION_JSON)) diff --git a/src/kemal/route.cr b/src/kemal/route.cr index 4dfb877..cfcf29e 100644 --- a/src/kemal/route.cr +++ b/src/kemal/route.cr @@ -1,6 +1,7 @@ module Kemal # Route is the main building block of Kemal. - # It takes 3 parameters: Method, path and a block to specify + # + # It takes 3 parameters: http *method*, *path* and a *handler* to specify # what action to be done if the route is matched. struct Route getter method, path, handler diff --git a/src/kemal/route_handler.cr b/src/kemal/route_handler.cr index ded2c0b..3860073 100644 --- a/src/kemal/route_handler.cr +++ b/src/kemal/route_handler.cr @@ -1,8 +1,8 @@ require "radix" module Kemal - # Kemal::RouteHandler is the main handler which handles all the HTTP requests. Routing, parsing, rendering e.g - # are done in this handler. + # Main handler which handles all the HTTP requests. + # Routing, parsing, rendering e.g are done in this handler. class RouteHandler include HTTP::Handler INSTANCE = new diff --git a/src/kemal/websocket.cr b/src/kemal/websocket.cr index 211faec..2b65f8e 100644 --- a/src/kemal/websocket.cr +++ b/src/kemal/websocket.cr @@ -1,6 +1,5 @@ module Kemal - # Route is the main building block of Kemal. - # It takes 3 parameters: Method, path and a block to specify + # Takes 2 parameters: *path* and a *handler* to specify # what action to be done if the route is matched. class WebSocket < HTTP::WebSocketHandler getter proc diff --git a/src/kemal/websocket_handler.cr b/src/kemal/websocket_handler.cr index 583a989..6d5d880 100644 --- a/src/kemal/websocket_handler.cr +++ b/src/kemal/websocket_handler.cr @@ -1,5 +1,5 @@ module Kemal - # Kemal::WebSocketHandler is used for building a WebSocket route. + # Used for building a WebSocket route. # For each WebSocket route a new handler is created and registered to global handlers. class WebSocketHandler include HTTP::Handler