Mailing List Archive

complicated map example in a utility template - need code help
Hi all

my other puzzle, I'm updating the standard /util/get_contributor.mc template that David wrote - to add links to the Contributor bio story - if it exists. I wrote a subroutine that adds this link for a single contributor instance however I can't figure out how to insert this subroutine, in an elegant way, into the complex map/join for a multiple contributor array.

Here's the last part of the code:

<%init>;
# Get the list of contributors.
my @contribs = defined $type
? grep { $_->get_grp->get_name eq $type} $asset->get_contributors
: $asset->get_contributors;
unless (@contribs) {
# If there are no contributors, just output the default and return.
$m->print($default);
return 1;
}


#DAWN ADDED, works : search for the first published Profile story where this contributor is the related contributor
sub get_profile {
my ($profile) = $story->list({
element_key_name => 'profile',
contrib_id => $_[0]->get_id,
Limit => 1,
unexpired => 1,
publish_status => '1',
});
$profile->get_uri if defined $profile;
}

if ($#contribs == 0) {
# There's just one contributor. Format and return.

#DAWN ADDED, works for single contrib:
my $uri = get_profile($contribs[0]);

if($uri){
$m->print('<a href="'.$uri.'">'.$contribs[0]->get_name($format).'</a>');
}else{
$m->print($contribs[0]->get_name($format));
}

return 1;
}
if ($sort) {
# We need to resort them.
my $get = $sort eq 'full_name' ? sub { $_[0]->get_name($format) } :
Bric::Util::Grp::Parts::Member::Contrib->my_meths->{$sort}{get_meth};
@contribs = sort { lc $get->($a) cmp lc $get->($b) } @contribs;
}

# Grab the last name in the list.
my $last = pop @contribs;
# Output the list.

# DAWN QUESTION: How do I add the get_profile subroutine into this map business below - and create a conditional test - in an elegant way? Maybe I should be pushing values onto a new array?
$m->print(join($sep, map { '<a href="'.$uri.'">'.$_->get_name($format).'</a>' } @contribs),
$final, '<a href="'.$uri.'">'.$last->get_name($format).'</a>');

return 1;
</%init>
Re: complicated map example in a utility template - need code help [ In reply to ]
On Jun 22, 2011, at 9:52 AM, Dawn Buie wrote:

> #DAWN ADDED, works : search for the first published Profile story where this contributor is the related contributor
> sub get_profile {
> my ($profile) = $story->list({
> element_key_name => 'profile',
> contrib_id => $_[0]->get_id,
> Limit => 1,
> unexpired => 1,
> publish_status => '1',
> });
> $profile->get_uri if defined $profile;
> }

I suggest you use

my $get_profile = sub {...}

Because `sub get_profile` is a global variable and thus not confined to this template. Not great to pollute the global namespace with something that might accidentally be called elsewhere.

> if ($#contribs == 0) {

Clearer:

if (@contribs == 1) {

> # There's just one contributor. Format and return.
>
> #DAWN ADDED, works for single contrib:
> my $uri = get_profile($contribs[0]);
>
> if($uri){
> $m->print('<a href="'.$uri.'">'.$contribs[0]->get_name($format).'</a>');
> }else{
> $m->print($contribs[0]->get_name($format));
> }
>
> return 1;
> }
> if ($sort) {
> # We need to resort them.
> my $get = $sort eq 'full_name' ? sub { $_[0]->get_name($format) } :
> Bric::Util::Grp::Parts::Member::Contrib->my_meths->{$sort}{get_meth};
> @contribs = sort { lc $get->($a) cmp lc $get->($b) } @contribs;
> }
>
> # Grab the last name in the list.
> my $last = pop @contribs;
> # Output the list.
>
> # DAWN QUESTION: How do I add the get_profile subroutine into this map business below - and create a conditional test - in an elegant way? Maybe I should be pushing values onto a new array?
> $m->print(join($sep, map { '<a href="'.$uri.'">'.$_->get_name($format).'</a>' } @contribs),
> $final, '<a href="'.$uri.'">'.$last->get_name($format).'</a>');

I think I'd add a format_contributor function like so:

my $format_contributor = sub {
my $contrib = shift;
my $name = encode_entities $contrib->get_name($format);
my $uri = $get_profile->($contrib) or return $name;
return qq{<a href="$uri">$name</a>};
};

Then just use it inline like so:

if (@contribs == 1) {
$m->print($format_contributor->($contribs[0]));
} else {
my $last = pop @contribs;
$m->print(
join($sep, map { $format_contributor->($_) } @contribs),
$final, $format->contributor->($last),
);
}

HTH,

David