—use
strict;
use
warnings;
=head1 NAME
Articulate::Construction::LocationBased - Create an item based on its location
=head1 ATTRIBUTES
=head3 types
This should be a hashref mapping types to class names to be used in constructors, where a type in this case is the penultimate endpoint of locations with an even number of parts
So:
article: Articulate::Item::Article
...would result in C</article/foo> or C<zone/public/article/foo> becoming C<Articulate::Item::Article>s but not C<article>, C<zone/article>, or C<zone/public/article>.
=head1 METHODS
=head3 construct
$self->construct( {
location => 'zone/public/article/hello-world',
meta => { ... }
content => " ... "
} );
Attempts to construct the item. Determines the desired class based on the mapping in the C<types> attribute, then calls C<< $class->new($args) >> on the class. Returns C<undef> if no appropriate class found.
In the above example, C<< $self->types->{article} >> would be consulted.
If the location is root or not a multiple of 2 (e.g. C<zone/public> is even and a C<zone> but C<zone/public/article> is odd), returns C<undef>.
=cut
use
Moo;
use
Articulate::Syntax;
use
Module::Load ();
has
types
=> (
is
=>
'rw'
,
default
=>
sub
{ {} },
);
sub
construct {
my
$self
=
shift
;
my
$args
=
shift
;
my
$location
= loc(
$args
->{location} );
if
(
scalar
(
@$location
) and 0 == (
scalar
(
@$location
) % 2 ) ) {
if
(
exists
$self
->types->{
$location
->[-2] } ) {
my
$class
=
$self
->types->{
$location
->[-2] };
Module::Load::load(
$class
);
return
$class
->new(
$args
);
}
}
return
undef
;
}
1;