The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
Revision history for Kelp

2.15 - 2024-07-03
            [Changes]
            - Kelp's req and res attributes were moved to Context and are now just facade methods
            - Added persistent_controllers config, which makes the system keep the reblessed instances

            [Deprecations]
            - new_anon method of Kelp is now deprecated due to incompatibilities with controllers

2.14 - 2024-07-02
            [Changes]
            - Fixed config files having incorrect line endings on Windows due to raw slurp
            - Fixed generation templates not handling UTF8 correctly

            [Tweaks]
            - Minimum version of Test::Deep was bumped to avoid Test::Deep::NoTest issue in tests

2.13 - 2024-07-01
            [New Interface]
            - Kelp::Base can now be imported with -attr
            - Added content_type_is method to Kelp::Request
            - Added a couple of is_* methods to Kelp::Request to match Kelp::Response's interface
              * is_text, is_html and is_xml have been added
            - Added merge to Kelp::Util, which implements the merge algorithm used by config

            [Changes]
            - Kelp::Base no longer imports namespace::autoclean with -strict
            - Fixed camelizing of controller names if they don't contain a hash sign
            - Fixed config loading Test::Builder through Test::Deep - now uses Test::Deep::NoTest

2.12 - 2024-06-26
            [Changes]
            - Kelp::Exception->throw now also works on objects (rethrows an exception)
            - Fixed installed config method not returning the default value
            - Fixed Kelp::Test being sensitive to utf8 configuration of the JSON encoder
            - Config module now allows overriding of the config merging routine

2.11 - 2024-06-25
            [New Interface]
            - Added a second optional argument to set_content_type in Response, which sets charset

            [Changes]
            - Fixed incorrect reading of filehandles passed to template
            - Fixed load_package from Kelp::Util failing if package is loaded and not in a file matching its name
            - It is now easier to customize Kelp::Response render behavior
            - Added a cookbook example of extending request and response to automatically handle YAML

2.10 - 2024-06-24
            [New Interface]
            - PSGI-compatible applications can now be mounted directly by using 'psgi' route flag
            - Added a bunch of new methods with suffix '_param' to Kelp::Request, which work like 'param' but fetch from specific place
            - Added charset, charset_decode methods to Kelp::Request
            - Added charset, charset_encode methods to Kelp::Response
            - Added is_production, get_encoder methods and request_charset, encoder_modules, context attributes to Kelp
            - Added Kelp::Module::Encoder, a base class for encoders (like JSON, to be used by the new get_encoder method)
            - Added adapt_psgi, effective_charset, charset_encode, charset_decode, load_package functions to Kelp::Util
            - Added a third, optional argument to camelize in Kelp::Util

            [General]
            - Fixed Route destination getting executed if a response was already rendered by a previous one
              * Rendering a response in a bridge will work the same as if the bridge returned a false value
              * If more than one normal routes were matched, they will be run until one of them renders or returns a defined value
              * Delayed responses will no longer override a previously rendered normal response
              * The destination will still be run if the render happened inside 'before_dispatch' hook
            - Response 'render' method will now assume you passed a json-encoded string if content type is json and body is not a reference
              * The json string will still get its charset encoded, so the encoder should be utf8-disabled
            - Kelp now tracks its context via 'context' attribute
              * App will now rememeber if it was reblessed and will only rebless once into given controller per request
              * This fixes before_finalize not working when reimplemented inside a controller
              * This also improves performance if a lot of bridges are defined as methods inside a controller
            - Fixed Kelp attribute 'charset' being readonly (was documented as read/write)
            - Fixed template bugs:
              * templates named '0' are now getting properly rendered
              * template is now correctly providing an 'app' object by default, with the correct rebless context
              * template now correctly rewinds a filehandle after reading from it, allowing reuse
            - Fixed ::Null modules containing testing behavior - now they really do nothing
            - Repeatedly fetching parameters from json request with the param method is now much faster
            - Kelp::Module::Logger now sorts keys in Data::Dumper output
            - Kelp can now be debugged using KELP_DEBUG environmental variable
            - Performance of accessors and request/response building was improved
            - 'Kelp' script has been renamed to 'kelp-generator' and documented
            - Documentation was vastly improved

            [Encoding]
            - Request data will now be properly decoded using either charset from Content-Type or request_charset
              * Request body parameters and content are automatically decoded
              * Path and query is automatically decoded, but always uses request_charset
              * Headers, cookies and sessions are unaffected (session encoding must be configured at the middleware level)
              * Explicitly setting request_charset to undef will disable all automatic decoding
              * Please use methods with prefix 'raw_' from Kelp::Request to access undecoded request data if needed
              * Not decoding input was a bug which needed to be fixed (the response was already being encoded correctly, so double encoding could happen)
            - Calling json and xml from Kelp::Response now also sets the charset in Content-Type header
            - Framework now internally uses a UTF8-disabled JSON encoder
              * The extra encoder will be created with the same options as the normal one, but without utf8
              * It will no longer react to runtime changes in config of the main encoder
              * Application will now encode the JSON response manually using proper charset
            - Methods with prefix 'raw_' were added to Kelp::Request, returning undecoded request data (see "Bug fixes" below)

            [Configuration]
            - Added log_format, date_format configuration values to Kelp::Module::Logger
            - Added stdout configuration value to Kelp::Module::Logger::Simple
            - Added default_modes attribute and an optional argument for 'get' which will be the default value returned to Module::Config
            - Kelp::Module::Config method 'get' never croaks if the config value was not set at all
            - Application can be now configured to do no encoding of responses by setting 'charset' to undef
            - Application now has a second charset configuration used for requests: request_charset
            - Fixed Kelp::Module::Config::Less using the same reference for middleware and modules

            [Testing]
            - Kelp::Test no longer uses HTTP::Cookies, implements a much slimmer cookie jar with the same interface
              * The new cookie jar only stores key/value pairs without any special data for cookies like domains, paths or expiration dates
            - Kelp::Test now has a new import flag: '-utf8'
              * Importing with this flag will automatically set Test::More to encode wide characters on output
            - Added charset attribute to Kelp::Test
            - Added full_content_type_is and content_bytes_are methods to Kelp::Test

            [Deprecations]
            - Scalar context behavior of the param method called without arguments on json request is now deprecated
              * This is done in effort to make param method easier to use and harder to misuse

            [Backward-Incompatible Changes]
            - Application now tries to decode request data - see [Encoding]
            - Routes no longer allow regex unless the pattern is a Regexp object (qr//)
              * This was a result of a bug - they were never documented to support regex and would not build correctly with it
              * Any non-placeholder regex syntax is now correctly quoted and matched as text
              * This fix helps to avoid bugs which may cause serious issues, like pattern '/index.html' matching '/index/html'
            - Kelp::Exception no longer renders its body attribute, but instead logs it if it is present
              * Throwing Kelp::Exception now produces error template or plaintext response with proper HTTP status string
              * Log will happen at 'error' level, while regular errors are going to 'critical'
              * Status 500 exceptions will behave the same as errors - print their body on non-production
              * Rendering the body was dangerous as it could leak internal data if misused
            - Application main handler now clears all headers when an error or exception is caught
              * This fixes a class of bugs where content encoding of the error page was mismatching the rendered error

            [Tweaks]
            - 'kelp' template has been adjusted to match framework looks
            - Added a homepage on GitHub
            - Kelp now has a logo
            - Kelp is now developed by the Kelp-framework organization on GitHub

2.00 - 2024-06-10
            [New Features]
            - Added a return value to 'add' method from Kelp::Routes,
              * it can be used to call add again, adding a child and making the parent a bridge
            - Added new placeholder to routes: >slurpy (a mix of optional + wildcard)
            - Added before_dispatch hook in Kelp
            - Added Kelp::Util, which contains some general utilities (previously as private code in Kelp::Routes)
            - Added has_name and dest methods to Kelp::Routes::Pattern
            - Kelp::Generator has a new filename shortcut: DOT (dotfiles support)

            [Changes]
            - Kelp::Routes module overhaul
              * Handles reblessing the app into a controller class by itself, with rebless => 1
              * Kelp::Routes::Controller is no longer required, but will be kept for backward compatibility
              * Resolves all of its checks at application build time (not during the request dispatching)
              * Does stricter validation of routing configuration
              * Route building errors can now be turned into exceptions (rather than just being skipped), with fatal => 1
              * Easier to subclass due to new overridable methods: format_to and load_destination
              * More performant at runtime, especially for deeply nested trees with many bridges
            - Removed safe_param configuration field, since param method is now safe by default
            - Improved the quality of configuration generated by the 'kelp' template

            [Backward-Incompatible Changes]
            - Disable unsafe param calls (cgi_param may be used instead if necessary)
            - Routes with invalid destinations will no longer be added and yield HTTP status 404 instead of 500
            - Some specific extensions of Kelp::Routes may no longer work correctly due to stricter build-time route checks

            [Bug fixes]
            - Instances created with new_anon now have correct default 'base' for routes
            - Fixed bridge behavior in some cases by removing duplicated slashes from non-regex pattern
            - Fixed unnamed wildcard not being honored in non-regex patterns as documented
            - Fixed ?placeholder possibly matching other routes, for example '/not/?here' matching '/nothing'
            - Fixed *placeholder not honoring rules from checks while matching a pattern
            - Optional capture groups in custom-regex routes no longer produce a warning when not matched
            - Kelp::Generator now ignores empty lines in index files

            [Examples]
            - Added an example script for benchmarking router matching and dispatching speeds in ex/router_bench.pl

1.07 - 2024-06-02
            [Changes]
            - Kelp::Routes now uses a dedicated method to build a pattern object

1.06 - 2022-05-09
            [Changes]
            - Removed broken homepage link

1.05 - 2021-01-21
            [New Features]
            - Added HTTP exceptions through Kelp::Exception

            [New Documentation]
            - Added Kelp::Generator

            [Changes]
            - Kelp::Module::JSON now uses JSON::MaybeXS
            - POD fixes and improvements

1.04 - 2021-01-18
            [New Features]
            - Added new_anon constructor, allowing for multiple instances of an app
            - Added safe_param configuration - see Kelp::Request::param
            - Added Kelp::Generator, allowing for pluggable generation templates and custom generation scripts
            - Rewrote the CLI script using Kelp::Generator
            - Added a welcome HTML page to generated application listing registered routes and config

            [New Documentation]
            - Cookbook: template layouts
            - Cookbook: deploying

            [Changes]
            - List context Kelp::Request::param call with parameter now is deprecated without safe_param
            - Kelp::Module::JSON will now prefer Cpanel::JSON::XS before other options
            - Kelp script now requires --type=less for a Kelp::Less app, instead of --less
            - All of Kelp file slurping is now done using Path::Tiny
            - POD fixes and improvements

            [Bug fixes]
            - exception thrown during response JSON encoding with no explicit content_type will now show correct error cause

1.03 - 2021-01-11
            [New Features]
            - Kelp::Request now holds the name of a route
            - Kelp script can now use tabs for indentation with --tabs flag

            [New Documentation]
            - Added Kelp::Manual - moved from old Kelp POD
            - Added Kelp::Manual::Cookbook

            [Changes]
            - POD fixes

1.02 - 2018-01-08
            [Bug fixes]
            - clean namespace inside import, fix for Path::Tiny

1.01 - 2017-12-29
            No changes. Stable version.

0.9091 - 2016-11-08
            [Changes]
            - Change bridge error respose. Bridges will return 403 Forbidden (Konstantin Yakunin)
            - attr can be ether scalar, undef or CODEref but not HASHREF or ARRAYREF (Nikolay Mishin)
            - POD (Nikolay Mishin)

0.9071 - 2015-08-10
            [Bug Fixes]

            - Bridges will correctly return 401 (instead of 500) when non existing location is accessed (Konstantin Yakunin)
            - Undefined value warning fixed. (Ben Hengst)
            - Correct handle errors on deployment and silence STDERR in Stack Trace tests (Konstantin Yakunin)

            [New Features]
            - New attributes request_obj and response_obj used to specify the name of the request and response classes. (Ben Hengst)

0.9051 - 2015-04-02
            [Bug Fixes]

            - Stringify 500 errors avoiding the JSON-ification of returned structures and blessed objects. (basiliscos)
            - Increate the level of Test::Bulder in Kelp::Test, providing more relevant messages upon error. (basiliscos)
            - POD typos corrected

            [New Features]
            - Add json_content method to Kelp::Test, allowing for the testing of the returned JSON structure.
            - Abstract the initialization of the Config and Routes modules
            - More POD and examples added (roy-tate, Christian Froemmel, Perlover)

0.9021 - 2014-12-14

            [Bug Fixes]

            - POD fixes

            [New features]

            - Session now accepts hashref, which also allows for the destruction
              of the enitire session.
            - Add "include" function to config files, making it possible to include
              other file into the configuration.

0.9015 - 2014-08-08

            [Bug Fixes]

            - Fix a typo causing a fatal error in Routes::Controller
            - Fix debug and error keywords in Kelp::Less
            - Remove an explicit return undef, per Perl::Critic

            [New Features and Improvements]

            - Allow for route methods outside of base class
              It is now possible to add a route that lives outside of the base class
              by prefixing it with '+'. This works for both Perl and camelized
              strings.

            - Add config keyword to Kelp::Less

            - Virtualize the logger instantiation
              Add a _logger function in Module::Logger, which creates the logger
              instance, making it easier to subclass the Logger module.
              Add a Logger::Simple module, which dumps everything to STDERR
              This module is convenient to use during development with Kelp::Less.

            - Update bin/Kelp
              * bin/Kelp --less <name> will now create a psgi file with the specified name
                (previously it would always create app.psgi).
              * Existing files will not be overwritten, unless --force specified.

            - Simplify Less application boilerplate
              Add a Config subclass with simplified configuration that will be used by
              default by any Kelp::Less application. This configuration will not load
              any modules or middleware, leaving it up to the user to manually load
              any modules needed.
              Additionally, bin/Kelp --less <name> will now only generate the psgi
              application, and not any other folders, views, templates etc.

            - Downgrade confess to croak and croak to die
              Kelp::Response used confess and croak excessively. Both changed to die,
              so that the user can control how much stack trace they want via the
              'long_error' attribute or the KELP_LONG_ERROR env variable.


0.9012 - 2014-07-12

            [New features]
            - Add access to the application instance from the config files
            - Kelp.pm methods 'requiest' and 'response' renamed to 'build_request' and 'build_response', in order
              to minimize cofusion. NOTE: If your application is overriding any of those, make sure to rename them too.
            - Replace explicit UTF-8 encoding with $app->charset
            - Rename pattern attribute 'via' to 'method'. 'via' will still work as a shortcut to 'method', so
              this will not break backwards compatibility.

            [Fixes]
            - POD fixes

            [Other]
            - Using Pod::Markdown::Github to generate README.md from Kelp.pm

0.9001 - 2014-05-30

            [Bug Fixes:]
            - Curly braces get stripped from pattern checks
            - Remove HTTP_X headers from Kelp::Request (security hole)

            [New features]
            - Allow for extending Kelp::Routes and using custom routers (Maurice Aubrey)
            - Create Kelp::Routes::Controller, which reblesses the web app into a controller class (Maurice Aubrey)
            - Set env KELP_CONFIG_WARN to warn for missing config files
            - Set rendered to true when redirecting (Julio Fraire)
            - Add request_ok method to Kelp::Test
            - Config module optionally registers _cfg method, to help manipulate the configuration.
            - Add a cookie jar to Kelp::Test


0.4602 - 2014-03-31
            Replace $json->property with $json->get_utf8 in order to maintain compatibility across different JSON implementations

0.4601 - 2014-03-27
            If no placeholders in route, param array should be empty (Maurice Aubrey)
            Move route cache to a CHI-like interface, in order to allow for custom cache modules
            Don't double encode JSON repsonse (Ruslan Zakirov)

0.4570 - 2014-03-02
            Allow attributes to set undef values
            do not append default template extension if ext() is undef
            Added POD
            Added tests

0.4560 - 2013-11-19
            Allow for fully qualified Kelp module names
            Config merge sigils will now only work for ARRAY
            POD and typo fixes

0.4550 - 2013-11-11
            Flip nginx env vars.
            Change param to accept no JSON content or non-hash JSON
            Make Kelp::Test::request only load the PSGI app once
            POD and comments typo fixes

0.4501 - 2013-08-14
            Minor fixes
            Add render_binary
            Add missing header_like
            POD changes

0.4011 - 2013-07-05
            Removed modules_disable and middleware_disable, and added the ability to add and remove elements in an array by adding a '+' or '-' in front of the key name.

0.4001 - 2013-07-02
            Added modules_disable and middleware_disable arrays in config
            Added a REMOTE_USER fallback for nginx
            Added loaded_modules attribute to Kelp
            Fixed utf8 encoding for OSX
            Added a session convenience method
            PSGI creation remodeled to leverage the StackTrace middleware
            Introduced render_error method in Kelp::Response, which will look for error templates (404, 500, etc)

0.3101 - 2013-06-13
            Remove dependency of Template, replace it with Template::Tiny.
            Reason being that Template does not pass its tests under Perl 5.18.
            Use Kelp::Module::Template::Toolkit (available on CPAN) if your code
            depends on Template.

0.3001 - 2013-05-25
            Fix typo in test paths
            Bridges accessed directly will now return 401 - Unathorized
            Introduce "panic" and "finalize" methods
            Add "long_error" attribute
            Rename "before_render" to "before_finalize"
            Change all _croak statements to return panic, improving the natural flow of the route logic

0.2191 - 2013-05-14
            Add arguments to load_module
            Fix tests and small issues

0.2190 - 2013-05-05
            Add property for partial rendering
            Address an issue with nginx and headers
            Add more pod

0.2182 - 2013-05-02
            Fix issue with content-type params
            Set explicit utf8 encoding for module Template
            Replace wizardly Perl code with Class::Inspector

0.2181 - 2013-04-20
            Fix test failing under Perl 5.10

0.218 - 2013-04-19
            Add auto load class when adding a route.

0.217 - 2013-04-17
            Fix Github issue #1
            Revamp the Template module to allow for more standard subclassing
            Remove Config::Hash from test units

0.21 - 2013-04-16
            Allow for using templates w/o extension.
            Allow for subclassing the templates module.
            Implement testing of a Less app, via the psgi attribute.

0.2 - 2013-04-13
            Complete rewrite of the Config module, allow for subclassing of it.
            Write more tests.
            Write more POD.

0.1 - 2013-04-12
            First upload to CPAN