How to display specific contributors
Based on this question, asked on the EPrints Tech list: How can I add the field “Thesis Advisor” from Contributors to the Abstract Pages?
Note: The question on the tech list specified EPrints 3.4.2. The below is based on 3.3.16, but may be useful as a starting point.
Below are three approaches that may do what you need.
Method 1 - EPScript function
1) In EPScript, there is an undocumented function - filter_compound_list
which accepts:
- a field (contributors)
- a sub-field name to filter on (type)
- a value to filter to (http://www.loc.gov/loc.terms/relators/THS)
- the field to return (name)
This can produce a text-string of one field from the compound field. If a thesis had two supervisors, the following example would produce:
Smith, John and Bond, James
<epc:if test="contributors">
<epc:print expr="filter_compound_list(contributors,'type','http://www.loc.gov/loc.terms/relators/THS','name')" />
</epc:if>
Method 2 - EPScript logic - foreach
This method is a bit more flexible, but you have to construct the values from the parts manually. It does allow you to reference the id
sub-field if required.
It also may leave empty wrapping elements in the output (e.g. the ul
in the example below if there are contributors, but none are the required type.
<epc:if test="contributors">
<ul>
<epc:foreach expr="contributors" iterator="contr">
<epc:if test="$contr{type}='http://www.loc.gov/loc.terms/relators/THS'">
<li>
<epc:print expr="$contr{name}{given}" /> <epc:print expr="$contr{name}{family}" />
<epc:if test="$contr{id}">(<epc:print expr="$contr{id}"/>)</epc:if>
</li>
</epc:if>
</epc:foreach>
</ul>
</epc:if>
Method 3 - Custom EPScript function
This is the most complex, but also offers the most flexibility - if you're able to understand the EPrints::Script::Compiled
module and write your own functions.
There are two parts - adding custom methods to EPScript, and calling them from the citation file.
1 ### This should be added to a file e.g. EPRINTS_ROOT/archives/ARCHIVEID/cfg/cfg.d/z_epscript_additions.pl
2
3 # Open block
4 {
5
6 # Write into EPrints::Script::Compiled
7 package EPrints::Script::Compiled;
8
9 use strict;
10
11 # Example usage in citation file:
12 #
13 # <epc:if test="$item.render_contributors_filtered('http://www.loc.gov/loc.terms/relators/THS',1)">
14 # <h2><epc:phrase ref="contributor_type_typename_http://www.loc.gov/loc.terms/relators/THS"/></h2>
15 # <epc:print expr="$item.render_contributors_filtered('http://www.loc.gov/loc.terms/relators/THS')"/>
16 # </epc:if>
17 #
18 # The first call includes the 'test' parameter, which can be used to determine whether surrounding
19 # elements need to be displayed - in the above example the <h2>.
20
21 sub run_render_contributors_filtered
22 {
23 my( $self, $state, $eprint, $contributor_type, $test ) = @_;
24
25 if( !defined $eprint->[0] || ref($eprint->[0]) ne "EPrints::DataObj::EPrint" )
26 {
27 $self->runtime_error( "Can only call render_contributors_filtered() on eprint objects not ".
28 ref($eprint->[0]) );
29 }
30
31 if( !defined $contributor_type )
32 {
33 $self->runtime_error( "You need to specify a contributor type you want to render." );
34 }
35
36 my @filtered_contributors = grep{ defined $_->{type} && $_->{type} eq $contributor_type->[0] } @{ $eprint->[0]->value( "contributors" ) };
37
38 if( $test )
39 {
40 return [ 0, "BOOLEAN" ] if( scalar @filtered_contributors < 1 );
41 return [ 1, "BOOLEAN" ];
42 }
43
44 # NB this is based on EPrints::Extras::render_related_url
45 # It is over-complicated for this use-case, as we could just use
46 # $state->{session}->render_name( $row->{name} )
47 # but if other compound fields are being used with similar code
48 # being able to get to the 'render_value' for the sub fields is useful.
49
50 my $field = $eprint->[0]->dataset->field( "contributors" );
51 my $f = $field->get_property( "fields_cache" );
52 my $fmap = {};
53 foreach my $field_conf ( @{$f} )
54 {
55 my $fieldname = $field_conf->{name};
56 my $field = $field->{dataset}->get_field( $fieldname );
57 $fmap->{$field_conf->{sub_name}} = $field;
58 }
59
60 my $ul = $state->{session}->make_element( "ul" );
61
62 foreach my $row ( @filtered_contributors )
63 {
64 my $li = $state->{session}->make_element( "li" );
65 $li->appendChild( $fmap->{name}->render_single_value( $state->{session}, $row->{name} ) );
66 if( defined $row->{id} )
67 {
68 $li->appendChild( $state->{session}->make_text( " (" ) );
69 $li->appendChild( $state->{session}->make_text( $row->{id} ) );
70 $li->appendChild( $state->{session}->make_text( ")" ) );
71 }
72 $ul->appendChild( $li );
73 }
74 return [ $ul, "XHTML" ];
75 }
76
77 } #End block
The above example is also available at: https://gist.github.com/jesusbagpuss/2efc96ed05cf9121b925063a20677120