in $r->params, or anything else, is DEPRECATED and likely to break in future
releases. Be good, and use proper method calls.
- is_applicable() renamed to is_model_applicable(), and returns boolean
- instead of a status code. Old-style is_applicable() will still work,
- but issues a warning.
+Incompatible API changes:
+ Maypole:
+ - is_applicable() renamed to is_model_applicable(), and returns boolean
+ instead of a status code. Old-style is_applicable() will still work,
+ but issues a warning.
API additions and enhancements:
Maypole::Application:
- user() attribute, and get_user() method (no-op)
- get_session() now called during handler_guts() before authenticate()
- new preprocess_path() method added and called by parse_path(),
- parse_path() will leave any properties set by preprocess_path() in
- place
+ parse_path() will leave any properties set by preprocess_path() in
+ place
- start_request_hook() added
- - setup() split into setup(), setup_model(), and load_model_subclass()
+ - setup() split into setup(), setup_model(), and load_model_subclass()
- added new path processing methods for ssl and default table/action
- - added make_path() and make_uri()
+ - added make_path()
+ - added make_uri()
Templates:
- Improved pager macro/include
Fix to TT error reporting (bug 13991)
Template xhtml validation (bug 13975)
Apache2 fix in Apache::MVC (bug 13888)
- Fixed inheritance issues in Mp::Application - Mp::App now manipulates the caller's
- @ISA directly, and doesn't inject itself into the chain (bugs 12923 & 14120)
+ Fixed inheritance issues in Mp::Application - Mp::App now manipulates the
+ caller's @ISA directly, and doesn't inject itself into the chain (bugs
+ 12923 & 14120)
Improved Template error reporting (14133)
Maypole::Session::generate_unique_id() now returns the id (bug 14124)
Moved ar accessor to Apache::MVC (bug 14014)
Refactored core to support further development in 2.11 and onwards
- Fixed related_class method (bug 14566)
+ Fixed related_class() method (bug 14566)
Added a cgi() attribute in Maypole::CGI
Documentation:
Fix to documentation for CGI::Maypole (bug 7263)
Simplified Net::Amazon example (bug 14073)
- Numerous major and minor updates to docs, plus:
- - renamed Maypole::Manual::Request to Maypole::Manual::Cookbook
- - added Maypole::Manual::Install, with material removed from
+ Numerous major and minor updates to docs.
+ Renamed Maypole::Manual::Request to Maypole::Manual::Cookbook
+ Added Maypole::Manual::Install, with material removed from
Maypole::Manual::About
- - added Maypole::Manual::Inheritance
- - added Maypole::Manual::Terminology
+ Added Maypole::Manual::Inheritance
+ Added Maypole::Manual::Terminology
- updated Maypole::Manual::View
- updated Maypole::View:TT
An adapter class that allows Maypole to work in a number of different server \r
environments. The currently available frontends are:\r
\r
- Frontend Distribution Environment\r
- ==============================================\r
- CGI::Maypole Maypole CGI\r
- Apache::MVC Maypole Apache/mod_perl and Apache2/mod_perl2\r
- MasonX::Maypole MasonX::Maypole Apache/mod_perl with Mason\r
+ Frontend Distribution Environment\r
+ ==============================================\r
+ CGI::Maypole Maypole CGI\r
+ Apache::MVC Maypole Apache/mod_perl or Apache2/mod_perl2\r
+ MasonX::Maypole MasonX::Maypole Apache/mod_perl with Mason\r
\r
The driver class inherits from the appropriate frontend, which inherits from \r
L<Maypole>.\r
\r
=item command\r
\r
-In some of the standard factory templates, an C<action> is called a C<command>.\r
+In some of the standard factory templates, an C<action> is referred to as a \r
+C<command>.\r
\r
=item template\r
\r
An abstract concept in Maypole, i.e. there is no specific controller class. \r
\r
The main sequence of events that occur during the processing of a request is\r
-controlled by methods in C<Maypole.pm>. Thus, major parts of the controller are\r
-in the same class as the request object. This may seem a bit strange, but in\r
-practice it works well.\r
+controlled by methods in C<Maypole.pm>. Thus, the controller logic is in the\r
+same class as the request object. This may seem a bit strange, but in practice\r
+it works well.\r
\r
More detailed events within the processing of a request are actually handled by \r
methods in the Maypole 'model'. For instance, switching from one template to \r
\r
=item model\r
\r
-In Maypole, the model is the set of classes representing individual tables in \r
-the database. Tables are related to each other in a more or less complex \r
-way. Each table class inherits from a Maypole model class, such as \r
-L<Maypole::Model::CDBI> or L<Maypole::Model::CDBI::Plain>. \r
+In Maypole, the 'model' is the set of classes representing individual tables in\r
+the database. Tables are related to each other in a more or less complex way.\r
+Each table class inherits from a Maypole model class, such as\r
+L<Maypole::Model::CDBI> or L<Maypole::Model::CDBI::Plain>.\r
\r
-In fact, much of the functionality provided by the Maypole model class, may be \r
-better thought of as being controller code. And much of the custom code written \r
-by developers to support specific applications, is in fact controller code. \r
+The functionality provided by the Maypole model class is more accurately\r
+described as a Presentation Model (see below). In complex Maypole applications,\r
+it is good practise to separate the domain model (the 'heart' of the\r
+application) into a separate class hierarchy (see\r
+L<Maypole::Manual::Inheritance).\r
\r
-The distinction is probably unimportant when using Maypole in 'default' mode - \r
+The distinction is relatively unimportant when using Maypole in 'default' mode - \r
i.e. using L<Maypole::Model::CDBI>, and allowing Maypole to autogenerate the \r
'model' classes straight out of the database. \r
\r
However, in many applications, a more complex domain model is required, or may\r
-already exist (see L<Maypole::Manual::Inheritance>). In this case, the Maypole\r
-model is more clearly seen as a layer that sits on top of the custom domain\r
-model, and controls access to it from the web UI. In this kind of situation, it\r
-seems more helpful to think of the Maypole model as part of the controller (or\r
-as a Presentation Model - see below).\r
+already exist. In this case, the Maypole model is more clearly seen as a layer\r
+that sits on top of the domain model, mediating access to it from the web UI, \r
+via the controller.\r
\r
This conceptualisation helps developers maintain a separation between the\r
-Maypole model classes, and their own domain model. Without this distinction,\r
-developers may add domain-specific code to the Maypole model classes. To a\r
-certain extent, this is fine. But if you find yourself adding lots of\r
-non-Exported methods to your Maypole model classes, and these methods are not\r
-there to directly support Exported methods, consider whether you could separate\r
-out the domain model into a separate hierarchy of classes that you import into\r
-the Maypole model. See L<Maypole::Manual::Inheritance>.\r
-\r
-Otherwise, there will be two uncoupled code bases, living in the same files,\r
-interacting through a relatively small number of methods. These methods should\r
-in fact become the public API of the domain model, which should be moved to a\r
-separate class hierarchy.\r
-\r
-The distinction between the Maypole model, the domain model, and the model in \r
-the MVC pattern, is fuzzy and variable. In straightforward Maypole applications, \r
-they're all pretty much the same thing. In more advanced applications, they \r
-begin to diverge. See C<Presentation Model>. \r
+Maypole model classes (presentation model), and the domain model. Without this\r
+distinction, developers may add domain-specific code to the Maypole model\r
+classes. To a certain extent, in simple applications, this is fine. But if you\r
+find yourself adding lots of non-Exported methods to your Maypole model classes,\r
+and these methods are not there to directly support Exported methods, consider\r
+whether you could separate out the domain model into a separate hierarchy of\r
+classes - see L<Maypole::Manual::Inheritance>.\r
+\r
+Otherwise, the 'model' classes may develop into two quite uncoupled code bases,\r
+but which co-exist in the same files. They will interact through a relatively\r
+small number of methods. These methods should in fact become the public API of\r
+the domain model, which should be moved to a separate class hierarchy. At some\r
+point, the convenience of dropping new methods into the 'shared' classes will be\r
+outweighed by the heuristic advantage of separating different layers into\r
+separate class hierarchies.\r
\r
=head3 Presentation Model\r
\r
-This pattern seems to more accurately describe the role of the Maypole model.\r
+This pattern more accurately describes the role of the Maypole model.\r
Martin Fowler describes I<Presentation Model> in L<Separting presentation logic\r
from the View|http://www.martinfowler.com/eaaDev/OrganizingPresentations.html>\r
and L<Presentation\r
Model|http://www.martinfowler.com/eaaDev/PresentationModel.html>.\r
\r
-The View sends events (e.g. an HTTP request that triggers an Exported method) to\r
-the Presentation Model. This layer responds by interacting with the underlying\r
-domain model, and stores the results in a bunch of variables, which represent\r
-the new state of the View. The View then queries the Presentation Model to\r
-retrieve these new values. In Maypole, this is the role of the C<vars()> method \r
-on L<Maypole::View::Base>, which transmits the new values to the templates. \r
+The user sends an event (e.g. an HTTP request) to the Controller. The Controller\r
+translates the request into a method call on the Presentation Model. The\r
+Presentation Model interacts with the underlying Domain Model, and stores the\r
+results in a bunch of variables, which I<represent the new state of the View>\r
+(that's why it's a Presentation Model, not a Domain Model). The View then\r
+queries the Presentation Model to retrieve these new values. In Maypole, this is\r
+the role of the C<vars()> method on L<Maypole::View::Base>, which transmits the\r
+new values to the templates.\r
\r
=back\r
\r