view release on metacpan or search on metacpan
--- #YAML:1.0
name: ASP4x-Linker
version: 1.003
abstract: In-page persistence of widget-specific variables.
author:
- John Drago <jdrago_999@yahoo.com>
license: perl
distribution_type: module
test_requires:
Test::More: 0
requires:
Carp: 0
ASP4: 1.044
Router::Generic: 0.016
recommends:
Apache2::RequestRec: 0
no_index:
directory:
inc/Module/Install/Metadata.pm view on Meta::CPAN
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
my @scalar_keys = qw{
name
module_name
abstract
author
version
distribution_type
tests
installdirs
};
my @tuple_keys = qw{
configure_requires
build_requires
requires
recommends
bundles
inc/Module/Install/Metadata.pm view on Meta::CPAN
while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
$self->feature( $name, @$mods );
}
return $self->{values}{features}
? @{ $self->{values}{features} }
: ();
}
sub no_index {
my $self = shift;
my $type = shift;
push @{ $self->{values}{no_index}{$type} }, @_ if $type;
return $self->{values}{no_index};
}
sub read {
my $self = shift;
$self->include_deps( 'YAML::Tiny', 0 );
require YAML::Tiny;
my $data = YAML::Tiny::LoadFile('META.yml');
lib/ASP4x/Linker.pm view on Meta::CPAN
{
my ($s, $args) = @_;
my $vars = $s->vars( $args, 1 );
no warnings 'uninitialized';
my ($uri) = split /\?/, $s->base_href;
my $context = ASP4::HTTPContext->current;
my $server = $context->server;
my @inputs = map {qq(<input type="hidden" name="@{[ $server->URLEncode( $_ ) ]}" value="@{[ $server->URLEncode( $vars->{$_} ) ]}" />)}
keys %$vars;
return join "\n", @inputs;
}# end hidden_fields()
sub vars
{
my ($s, $args) = @_;
my @parts = ( );
lib/ASP4x/Linker.pm view on Meta::CPAN
=item * The incoming form data from the original request
=item * Individually-set values for each widget in the collection.
=item * Any properties provided as an argument to C<uri()>.
=back
=head2 hidden_fields( [$properties] )
Returns a string of XHTML hidden input fields (<input type="hidden" name="$name" value="$value" />).
Useful if your persistence logic involves repeated form submissions rather than hyperlinks.
The C<$properties> argument is the same as in the C<uri()> method.
=head2 vars( [$properties] )
Returns a hashref representing the intersect of all widgets' names and attributes.
Supposing you setup your linker like this:
t/010-basic/020-basic.t view on Meta::CPAN
"widgetB" => {
"page_size" => undef,
"sort_col" => undef,
"sort_dir" => undef,
"page_number" => undef
}
},
{
"widgetC" => {
"color" => undef,
"type" => undef,
"size" => undef
}
},
{
"widgetD" => {
"color" => undef,
"type" => undef,
"size" => undef
}
}
], "Data structure looks right";
};
T1: {
ok( my $res = $api->ua->get('/?widgetA.page_size=1&widgetB.page_size=2&widgetC.color=red&widgetD.size=large'), "GET /" );
ok( my $info = decode_json($res->content), "JSON is good" );
is_deeply $info, [
t/010-basic/020-basic.t view on Meta::CPAN
"widgetB" => {
"page_size" => 2,
"sort_col" => undef,
"sort_dir" => undef,
"page_number" => undef
}
},
{
"widgetC" => {
"color" => 'red',
"type" => undef,
"size" => undef
}
},
{
"widgetD" => {
"color" => undef,
"type" => undef,
"size" => 'large'
}
}
], "Data structure looks right";
};
T2: {
ok( my $res = $api->ua->get('/?widgetA.page_size=20&widgetA.page_number=40&widgetA.sort_col=name&widgetA.sort_dir=DESC&widgetB.page_size=10&widgetB.page_number=100&widgetB.sort_col=date&widgetB.sort_dir=ASC&widgetC.color=red&widgetC.type=shirt&widg...
ok( my $info = decode_json($res->content), "JSON is good" );
is_deeply $info, [
{
"widgetA" => {
"page_size" => 20,
"sort_col" => 'name',
"sort_dir" => 'DESC',
"page_number" => 40
}
},
t/010-basic/020-basic.t view on Meta::CPAN
"widgetB" => {
"page_size" => 10,
"sort_col" => 'date',
"sort_dir" => 'ASC',
"page_number" => 100
}
},
{
"widgetC" => {
"color" => 'red',
"type" => 'shirt',
"size" => 'small'
}
},
{
"widgetD" => {
"color" => 'black',
"type" => 'hat',
"size" => 'large'
}
}
], "Data structure looks right";
};
t/010-basic/030-vars.t view on Meta::CPAN
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is_deeply
$linker->vars(undef, 1), {
'widgetB.page_number' => undef,
'widgetC.type' => undef,
'widgetD.size' => undef,
'widgetA.page_size' => undef,
'widgetB.sort_dir' => undef,
'widgetC.size' => undef,
'widgetD.color' => undef,
'widgetD.type' => undef,
'widgetA.page_number' => undef,
'widgetA.sort_col' => undef,
'widgetB.sort_col' => undef,
'widgetC.color' => undef,
'widgetA.sort_dir' => undef,
'widgetB.page_size' => undef
}, "Default";
$linker->widget('widgetA')->set( page_size => 10 );
is_deeply
$linker->vars(undef, 1), {
'widgetB.page_number' => undef,
'widgetC.type' => undef,
'widgetD.size' => undef,
'widgetA.page_size' => 10,
'widgetB.sort_dir' => undef,
'widgetC.size' => undef,
'widgetD.color' => undef,
'widgetD.type' => undef,
'widgetA.page_number' => undef,
'widgetA.sort_col' => undef,
'widgetB.sort_col' => undef,
'widgetC.color' => undef,
'widgetA.sort_dir' => undef,
'widgetB.page_size' => undef
}, "widgetA.page_size=10";
};
t/010-basic/030-vars.t view on Meta::CPAN
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is_deeply
$linker->vars(undef, 1), {
'widgetB.page_number' => undef,
'widgetC.type' => undef,
'widgetD.size' => undef,
'widgetA.page_size' => 100,
'widgetB.sort_dir' => undef,
'widgetC.size' => undef,
'widgetD.color' => undef,
'widgetD.type' => undef,
'widgetA.page_number' => undef,
'widgetA.sort_col' => undef,
'widgetB.sort_col' => undef,
'widgetC.color' => undef,
'widgetA.sort_dir' => undef,
'widgetB.page_size' => undef
}, "Default";
$linker->widget('widgetA')->set( page_size => 10 );
is_deeply
$linker->vars(undef, 1), {
'widgetB.page_number' => undef,
'widgetC.type' => undef,
'widgetD.size' => undef,
'widgetA.page_size' => 10,
'widgetB.sort_dir' => undef,
'widgetC.size' => undef,
'widgetD.color' => undef,
'widgetD.type' => undef,
'widgetA.page_number' => undef,
'widgetA.sort_col' => undef,
'widgetB.sort_col' => undef,
'widgetC.color' => undef,
'widgetA.sort_dir' => undef,
'widgetB.page_size' => undef
}, "widgetA.page_size=10";
};
t/010-basic/040-links.t view on Meta::CPAN
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is( $linker->uri() => '/', "/" );
is(
$linker->uri({
widgetA => { page_number => 2 }
}) => '/?widgetA.page_number=2'
t/010-basic/040-links.t view on Meta::CPAN
sort_col => 'name',
sort_dir => 'ASC'
}
}) => '/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC'
);
};
WITH_VARS: {
$api->ua->get('/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat');
my $linker = ASP4x::Linker->new();
$linker->add_widget(
name => "widgetA",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is(
$linker->uri() => '/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => { page_number => 2 }
}) => '/?widgetA.page_number=2&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
}
}) => '/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
},
widgetB => {
page_size => 10
}
}) => '/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=10&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
is(
$linker->uri({
NO_EXISTO => { blah => 'blech' },
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
};
WITH_VARS_AND_ROUTER: {
my $router = Router::Generic->new();
$router->add_route(
name => 'FooRoute',
path => '/foo/:bar/baz',
target => '/index.asp',
method => 'GET'
);
$api->ua->get('/');
$api->context->config->web->{router} = $router;
$api->ua->get('/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat');
my $linker = ASP4x::Linker->new();
$linker->add_widget(
name => "widgetA",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is_deeply $linker->widget('widgetA')->vars, {
page_number => 24,
page_size => undef,
sort_col => undef,
sort_dir => undef,
}, 'widgetA.vars';
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({yay=>'woot'}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat&yay=woot',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat&yay=woot'
);
is(
$linker->uri({
widgetA => { page_number => 2 }
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
}
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
},
widgetB => {
page_size => 10
}
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=10&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
is(
$linker->uri({
NO_EXISTO => { blah => 'blech' },
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
$linker->widget('widgetB')->set( page_size => 20 );
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=20&widgetC.color=blue&widgetD.type=hat',
'widgetB.page_size = 20'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
$linker->reset();
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
};
WITH_VARS_AND_ROUTER_POSTED: {
last;
my $router = Router::Generic->new();
$router->add_route(
name => 'FooRoute',
t/010-basic/040-links.t view on Meta::CPAN
target => '/index.asp',
method => '*'
);
$api->ua->get('/');
$api->context->config->web->{router} = $router;
$api->ua->post('/foo/bar/baz/', {
'widgetA.page_number' => 24,
'widgetB.page_size' => 100,
'widgetC.color' => 'blue',
'widgetD.type' => 'hat',
});
my $linker = ASP4x::Linker->new();
$linker->add_widget(
name => "widgetA",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
is_deeply $linker->widget('widgetA')->vars, {
page_number => 24,
page_size => undef,
sort_col => undef,
sort_dir => undef,
}, 'widgetA.vars';
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => { page_number => 2 }
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
}
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetA => {
page_number => 2,
page_size => 20,
sort_col => 'name',
sort_dir => 'ASC'
},
widgetB => {
page_size => 10
}
}) => '/foo/bar/baz/?widgetA.page_number=2&widgetA.page_size=20&widgetA.sort_col=name&widgetA.sort_dir=ASC&widgetB.page_size=10&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
is(
$linker->uri({
NO_EXISTO => { blah => 'blech' },
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
$linker->widget('widgetB')->set( page_size => 20 );
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=20&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=20&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red&widgetD.color=orange&widgetD.type=hat'
);
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
$linker->reset();
is(
$linker->uri() => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat',
'/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=100&widgetC.color=blue&widgetD.type=hat'
);
is(
$linker->uri({
widgetB => {
page_size => 10
},
widgetC => {
color => 'red@hot'
},
widgetD => {
color => 'orange'
}
}) => '/foo/bar/baz/?widgetA.page_number=24&widgetB.page_size=10&widgetC.color=red%40hot&widgetD.color=orange&widgetD.type=hat'
);
};
t/010-basic/050-hidden-fields.t view on Meta::CPAN
attrs => [qw( page_number page_size )]
);
$linker->add_widget(
name => 'albums',
attrs => [qw( page_number page_size )]
);
is
$linker->hidden_fields() =>
q(<input type="hidden" name="albums.page_size" value="" />
<input type="hidden" name="artists.page_number" value="" />
<input type="hidden" name="albums.page_number" value="" />
<input type="hidden" name="artists.page_size" value="" />),
"Hidden Fields look right";
$linker->widget('albums')->set( page_number => 1 );
is
$linker->hidden_fields() =>
q(<input type="hidden" name="albums.page_size" value="" />
<input type="hidden" name="artists.page_number" value="" />
<input type="hidden" name="albums.page_number" value="1" />
<input type="hidden" name="artists.page_size" value="" />),
"Hidden Fields look right";
is
$linker->hidden_fields() =>
q(<input type="hidden" name="albums.page_size" value="" />
<input type="hidden" name="artists.page_number" value="" />
<input type="hidden" name="albums.page_number" value="" />
<input type="hidden" name="artists.page_size" value="" />),
"Auto-reset works";
my $args = {
albums => { page_size => 20, page_number => 4 },
artists => { page_size => 5, page_number => 10 }
};
is
$linker->hidden_fields($args) =>
q(<input type="hidden" name="albums.page_size" value="20" />
<input type="hidden" name="artists.page_number" value="10" />
<input type="hidden" name="albums.page_number" value="4" />
<input type="hidden" name="artists.page_size" value="5" />),
"Auto-reset works";
t/htdocs/index.asp view on Meta::CPAN
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetB",
attrs => [qw/ page_number page_size sort_dir sort_col /]
);
$linker->add_widget(
name => "widgetC",
attrs => [qw/ size type color /]
);
$linker->add_widget(
name => "widgetD",
attrs => [qw/ size type color /]
);
my @result = map {
my $widget = $_;
my $res = {
$widget->name => {
map { ($_ => $widget->get( $_ )) }
$widget->attrs
}
};