Skip to content

Commit

Permalink
Item14237: Documented OO macros
Browse files Browse the repository at this point in the history
Other docs corrections.
  • Loading branch information
vrurg committed Oct 16, 2017
1 parent d804d39 commit 1abec12
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 29 deletions.
10 changes: 5 additions & 5 deletions EmptyExtension/lib/Foswiki/Extension/Empty.pm
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ callbackHandler 'Foswiki::App::handleRequestException', sub {
A core class may declare some of its methods as pluggable – i.e. let an
extension to have _before_, _around_, and _after_ handlers for the method –
similar (but not the same) to analogous functionality of [[CPAN:Moo][=Moo=]]
or [[CPAN:Moose][Moose]] but without subclassing of the core class. This feature
similar (but not the same) to analogous functionality of =[[CPAN:Moo][Moo]]= or
=[[CPAN:Moose][Moose]]= but without subclassing of the core class. This feature
is provided by =plugBefore=, =plugAround=, and =plugAfter= subroutines
correspondingly.
To allow support for this feature by a core class it must add =extensible=
parameter to =use Foswiki::Class=. This will implicitly apply
=Foswiki::Util::_ExtensibleRole= role to the class and export =pluggable=
To allow support for this feature by a core class it must apply =extensible=
modifier via =%PERLDOC{"Foswiki::Class"}%= parameters. This will implicitly
apply =Foswiki::Util::_ExtensibleRole= role to the class and export =pluggable=
subroutine to declare pluggable methods:
<verbatim>
Expand Down
22 changes: 19 additions & 3 deletions core/data/System/FoswikiV3Essentials.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1507948779" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1508119765" format="1.1" version="1"}%
%META:TOPICPARENT{name="DeveloperDocumentationCategory"}%
---+ Foswiki v3 Essentials
%TOC%
Expand Down Expand Up @@ -42,16 +42,32 @@ Basically, what makes v3 different from all previous versions are:
There are some under the hood changes in behaviour of some components like
=%PERLDOC{"Foswiki::Request"}%= initialization procedures; or alike.

---++ Basic concepts
---++ Basic Concepts

$ [[OOCodeConcepts]] : Main concepts of programming under %WIKITOOLNAME% v3.
$ [[EngineRevisedV3]] : Engine new role in Foswiki V3.
$ [[ChainedExecutionFlow]] : Callbacks and extensions chaining of calls.
$ [[CallbacksFramework]] : Callbacks framework

---++ New standards
---++ New Standards And Major Changes

$ [[SpecFileFormat]] : Config Specs v2
$ [[MacrosAsOO]] : Object oriented macros model

---+++ Configuration Management

All configuration-related functionality has been put into
%PERLDOC{"Foswiki::Config"}% class which is instantiated in
=%PERLDOC{"Foswiki::App" attr="cfg"}%= attribute. The functionality includes:

* Bootstraping
* Reading Local Site Configuration (LSC)
* Fetching and handling of configuration specs (see Config Specs v2 above)

---+++ Easy File Handling

New class =%PERLDOC{"Foswiki::File"}%= provides simple and easy to use interface
for fetching/writing files.

---++ Testing

Expand Down
54 changes: 54 additions & 0 deletions core/data/System/MacrosAsOO.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
%META:TOPICINFO{author="ProjectContributor" date="1508119765" format="1.1" version="1"}%
%META:TOPICPARENT{name="FoswikiV3Essentials"}%
---+ Macros OO Model
%TOC%

In Foswiki v3 macros management has been extracted into a dedicated class
=%PERLDOC{"Foswiki::Macros"}%. The class is responsible for keeping macros
registration information and for expanding them in a text. While the class
itself is nothing special and provides pretty clean and well documented API,
the two additional ways of implementing macros it introduces are of the real
interest here.

---++ Macro In a Class

The first way is declaring a class which will be instantiated into an object.
The object is created upon encountering first occurrence of the macro and then
is preserved until the macros manager object is destroyed. The macro class must
fulfill the following two requirements:

* consume =%PERLDOC{"Foswiki::Macro"}%= role
* implement method =expand()=

The second requirement is actually imposed by the =Foswiki::Macro= role.

The =expand()= sub is executed as a method of the macro object.

The advantages of this way are persistence and encapsulation of macro data.
Where previously subroutine handlers would have to use either some kind of
global persistent storage (=$Foswiki::Plugins::SESSION=, most of the time) or
=state= variables to preserve some of their data across calls, it is now
possible to use object attributes for this purpose. The approach also clears the
way for multi-application environment (see OOCodeConcepts topic).

---++ Macro In an Extension

The macro manager also supports macro declaration in an extension. This way
works through registering the extension class as the macro handler. Then the
macro manager relies upon extension manager to check if the extension is active
and obtain its object. Extension's class must provide a method named after the
macro. There could be more than one macro registered by same extension.

Macro methods are executed on the extension object.

In addition to the mentioned above advantages this approach adds direct access
of macro code to the extension's internal data. Additionally, as long as a
developer is using =tagHandler= (see
=%PERLDOC{"Foswiki::Extension::Empty" anchor="Custom_macros"}%=), it simplifies
bundling of an extension by keeping all code in the same location.

---+ Related

=%PERLDOC{"Foswiki::Macros"}%=, =%PERLDOC{"Foswiki::ExtManager"}%=,
=%PERLDOC{"Foswiki::Extension::Empty"}%=

4 changes: 2 additions & 2 deletions core/data/System/OOCodeConcepts.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1507948779" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1508119765" format="1.1" version="1"}%
%META:TOPICPARENT{name="FoswikiV3Essentials"}%
---+ Programming for Foswiki v3
%TOC%
Expand Down Expand Up @@ -256,7 +256,7 @@ with =Foswiki::AppObject= role applied it must create an application object.
Then either a corresponding attribute on application could be used to do the job
or necessary instance must be created using application's =create()= method.

---+++ $Foswiki::app, $Foswiki::cfg and muli-application environment
---+++ $Foswiki::app, $Foswiki::cfg and multi-application environment

It is common for Foswiki code to serve a single request, return a response and
shutdown – all within a single process. In this scenario it is guaranteed that
Expand Down
37 changes: 32 additions & 5 deletions core/lib/Foswiki/App.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ package Foswiki::App;
---+!! Class Foswiki::App
---++ SYNOPSIS
<verbatim>
# Basic PSGI starter script
use Foswiki::App;
my $app = sub {
my $env = shift;
return Foswiki::App->run( env => $env, );
};
</verbatim>
---++ DESCRIPTION
The core class of the project responsible for low-level and code glue
functionality.
Expand All @@ -18,7 +33,7 @@ hierarchy.
This class also provides the API for user-created code like extensions or
legacy plugins.
---++ Life cycle
---+++ Life cycle
Depending on the purpose of a new application object it could be created either
manually using =new()= method or by calling static method =run()=. The latter
Expand All @@ -37,7 +52,7 @@ check the current stage of application life by examining the context (see the
=context= attribute). In particular, =appStage= context could be used to find
out related information.
---++ Legacy support
---+++ Legacy support
Since the new %WIKITOOLNAME% core is not backward compatible with previous major
versions the legacy code must be somewhat changed to be able to work with the
Expand Down Expand Up @@ -79,7 +94,7 @@ extends qw(Foswiki::Object);

=begin TML
---++ Callbacks
---+++ Callbacks
This class is currently provides support for the following callbacks:
Expand All @@ -93,7 +108,7 @@ callback_names qw(handleRequestException postConfig);

=begin TML
---++ Active features
---+++ Active features
%FEATURES_INFO{ns="*"}%
Expand All @@ -115,7 +130,19 @@ features_provided
-desc => "Perl Specs",
-proposal => "OOConfigSpecsFormat",
-doc => 'SpecFileFormat',
];
],
NAMED_CALLBACKS => [
2.99, undef, undef,
-desc => "Named callbacks",
-doc => 'CallbacksFramework',
],
OOEXTENSIONS => [
2.99, undef, undef,
-desc => "OO Extensions",
-proposal => 'OONewPluginModel',
-doc => '%PERLDOC{"Foswiki::ExtManager"}%',
],
;

=begin TML
Expand Down
12 changes: 7 additions & 5 deletions core/lib/Foswiki/Class.pm
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ A class with this modifier wants to get callbacks support. This is done by:
1. exporting =callback_names= public method.
a subroutine =callback_names= is exported into a class' namespace and
=Foswiki::Util::Callbacks= role gets applied. =callback_names= accepts a list
and registers names from the list as callbacks supported by the class.
=%PERLDOC{"Foswiki::Util::Callbacks"}%= role gets applied. =callback_names=
accepts a list and registers names from the list as callbacks supported by the
class.
For example:
Expand All @@ -124,10 +125,11 @@ See =Foswiki::Util::Callbacks=.
---+++ extension
Extension support is provided by exporting subroutines =callbackHandler,
extBefore, extAfter, extClass, plugBefore, plugAround, plugAfter, tagHandler=.
Extension support is provided by exporting subroutines =callbackHandler=,
=extBefore=, =extAfter=, =extClass=, =plugBefore=, =plugAround=, =plugAfter=,
=tagHandler=.
See more in =Foswiki::Extension::Empty=.
See more in =%PERLDOC{"Foswiki::Extension::Empty"}%=.
---+++ extensible
Expand Down
38 changes: 30 additions & 8 deletions core/lib/Foswiki/Macros.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

package Foswiki::Macros;

=begin TML
---+!! Class Foswiki::Macros
---++ SYNOPSIS
<verbatim>
$app->macros->registerTagHandler("TAGNAME", \&tagHandler);
my $expanded = $app->macros->expandMacros( $text, $metaObject );
</verbatim>
---++ DESCRIPTION
This class is responsible for managing macros.
=cut

use Foswiki qw(%regex expandStandardEscapes);
use Foswiki::Attrs ();

Expand All @@ -12,9 +30,7 @@ use Assert;

=begin TML
---++!! Class Foswiki::Macros
Macro handling and expansion class.
---++ ATTRIBUTES
=cut

Expand All @@ -39,6 +55,12 @@ has _macros => (
default => sub { {} },
);

=begin TML
---++ METHODS
=cut

sub BUILD {
my $this = shift;

Expand Down Expand Up @@ -211,7 +233,7 @@ s/%TOC(?:\{(.*?)\})?%/$this->execMacro('TOC', $1, $topicObject, $text, $tocInsta

=begin TML
---++ ObjectMethod expandMacrosOnTopicCreation ( $topicObject )
---++ ObjectMethod expandMacrosOnTopicCreation( $topicObject )
* =$topicObject= - the topic
Expand All @@ -220,10 +242,10 @@ expanded during topic creation, in the body text and
PREFERENCE meta only. The expansion is in-place inside
the topic object.
# SMELL: no plugin handler
=cut

# SMELL: no plugin handler

sub expandMacrosOnTopicCreation {
my ( $this, $topicObject ) = @_;

Expand Down Expand Up @@ -322,7 +344,7 @@ sub expandMacrosOnTopicCreation {
}

=begin TML
---++ ObjectMethod exists($macro) -> boolean
---++ ObjectMethod exists( $macro ) -> boolean
Returns true if =$macro= is a registered macro.
Expand Down Expand Up @@ -739,7 +761,7 @@ sub execMacro {
else {
$macroObj = $this->_macros->{$macroName} =
$this->create( $this->registered->{$macroName} );
ASSERT( $this->_macros->{$macroName}->does('Foswiki::Macro'),
ASSERT( $this->_macros->{$macroName}->DOES('Foswiki::Macro'),
"Invalid macro module "
. $this->registered->{$macroName}
. "; must consume Foswiki::Macro role" )
Expand Down
2 changes: 1 addition & 1 deletion core/lib/Foswiki/Util/Localize.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

=begin TML
---++ Role Foswiki::Util::Localize
---++!! Role Foswiki::Util::Localize
This role determines classes which are able to simulate =local= Perl operator
using OO approach. They do it by providing two methods: =localize()= and
Expand Down

0 comments on commit 1abec12

Please sign in to comment.