From ce10d864a7c3ec0a750523376e9ab9a3f8e3f39c Mon Sep 17 00:00:00 2001 From: Jared Camins-Esakov <jcamins@cpbibliography.com> Date: Thu, 31 May 2012 07:24:29 -0400 Subject: [PATCH] Bug 8204: Add user friendly authority view to OPAC Content-Type: text/plain; charset="UTF-8" Up until now, the only authority view in the OPAC was a rather-unfriendly expanded MARC view. This patch adds a user-friendly view similar to the biblio details view. Specific features to be aware of: * Right-to-left text in the MARC21 880 field will show up in the appropriate location with the appropriate alignment and wrapping * There is very little CSS styling. Any suggestions for how to make the display more attractive would be gratefully received. To test: 1) Do a search for an authority in the OPAC. 2) Choose an authority record to view. 3) Observe that the view is more user-friendly and polished. --- C4/AuthoritiesMarc.pm | 58 +++++-- koha-tmpl/opac-tmpl/prog/en/css/opac.css | 13 ++- .../prog/en/modules/opac-auth-MARCdetail.tt | 2 + .../opac-tmpl/prog/en/modules/opac-auth-detail.tt | 174 ++++++++++++++++++++ opac/opac-authoritiesdetail.pl | 152 +++++++++--------- 5 files changed, 305 insertions(+), 94 deletions(-) create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-detail.tt diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index c92c319..bfaec45 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -1037,12 +1037,13 @@ sub BuildSummary { # // form foreach my $field ($record->field('7..')) { my $lang = substr($field->subfield('8'),3,3); - push @otherscript, { lang => $lang, term => $field->subfield('a') }; + push @otherscript, { lang => $lang, term => $field->subfield('a'), direction => 'ltr' }; } } else { # construct MARC21 summary # FIXME - looping over 1XX is questionable # since MARC21 authority should have only one 1XX + my $subfields_to_report; foreach my $field ($record->field('1..')) { my $tag = $field->tag(); next if "152" eq $tag; @@ -1050,34 +1051,37 @@ sub BuildSummary { # in MARC21 -- purely local tags really ought to be # 9XX if ($tag eq '100') { - push @authorized, $field->as_string('abcdefghjklmnopqrstvxyz68'); + $subfields_to_report = 'abcdefghjklmnopqrstvxyz'; } elsif ($tag eq '110') { - push @authorized, $field->as_string('abcdefghklmnoprstvxyz68'); + $subfields_to_report = 'abcdefghklmnoprstvxyz'; } elsif ($tag eq '111') { - push @authorized, $field->as_string('acdefghklnpqstvxyz68'); + $subfields_to_report = 'acdefghklnpqstvxyz'; } elsif ($tag eq '130') { - push @authorized, $field->as_string('adfghklmnoprstvxyz68'); + $subfields_to_report = 'adfghklmnoprstvxyz'; } elsif ($tag eq '148') { - push @authorized, $field->as_string('abvxyz68'); + $subfields_to_report = 'abvxyz'; } elsif ($tag eq '150') { - push @authorized, $field->as_string('abvxyz68'); + $subfields_to_report = 'abvxyz'; } elsif ($tag eq '151') { - push @authorized, $field->as_string('avxyz68'); + $subfields_to_report = 'avxyz'; } elsif ($tag eq '155') { - push @authorized, $field->as_string('abvxyz68'); + $subfields_to_report = 'abvxyz'; } elsif ($tag eq '180') { - push @authorized, $field->as_string('vxyz68'); + $subfields_to_report = 'vxyz'; } elsif ($tag eq '181') { - push @authorized, $field->as_string('vxyz68'); + $subfields_to_report = 'vxyz'; } elsif ($tag eq '182') { - push @authorized, $field->as_string('vxyz68'); + $subfields_to_report = 'vxyz'; } elsif ($tag eq '185') { - push @authorized, $field->as_string('vxyz68'); + $subfields_to_report = 'vxyz'; + } + if ($subfields_to_report) { + push @authorized, $field->as_string($subfields_to_report); } else { push @authorized, $field->as_string(); } - } #See From - foreach my $field ($record->field('4..')) { + } + foreach my $field ($record->field('4..')) { #See From my $type = 'seefrom'; $type = $marc21controlrefs{substr $field->subfield('w'), '0'} if ($field->subfield('w')); if ($type eq 'subfi') { @@ -1085,8 +1089,8 @@ sub BuildSummary { } else { push @seefrom, { heading => $field->as_string($marc21subfields), type => $type }; } - } #See Also - foreach my $field ($record->field('5..')) { + } + foreach my $field ($record->field('5..')) { #See Also my $type = 'seealso'; $type = $marc21controlrefs{substr $field->subfield('w'), '0'} if ($field->subfield('w')); if ($type eq 'subfi') { @@ -1098,7 +1102,27 @@ sub BuildSummary { foreach my $field ($record->field('6..')) { push @notes, $field->as_string(); } + foreach my $field ($record->field('880')) { + my $linkage = $field->subfield('6'); + my $category = substr $linkage, 0, 1; + if ($category eq '1') { + $category = 'preferred'; + } elsif ($category eq '4') { + $category = 'seefrom'; + } elsif ($category eq '5') { + $category = 'seealso'; + } + my $type; + if ($field->subfield('w')) { + $type = $marc21controlrefs{substr $field->subfield('w'), '0'}; + } else { + $type = $category; + } + my $direction = $linkage =~ m#/r$# ? 'rtl' : 'ltr'; + push @otherscript, { term => $field->as_string($subfields_to_report), category => $category, type => $type, direction => $direction }; + } } + $summary{mainentry} = $authorized[0]; $summary{authorized} = \@authorized; $summary{notes} = \@notes; $summary{seefrom} = \@seefrom; diff --git a/koha-tmpl/opac-tmpl/prog/en/css/opac.css b/koha-tmpl/opac-tmpl/prog/en/css/opac.css index 1e5b0c6..d4e7071 100644 --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ b/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -2594,9 +2594,20 @@ ul.ui-tabs-nav li { } .authref .label { - font-style: italic; + font-style: italic; } +.authstanza { + margin-top: 1em; +} + +.authstanzaheading { + font-weight: bold; +} + +.authstanza li { + margin-left: 0.5em; +} /* jQuery UI Datepicker */ .ui-datepicker-trigger { diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-MARCdetail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-MARCdetail.tt index 8e87d71..3863fad 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-MARCdetail.tt @@ -35,6 +35,8 @@ function showChildren(mynumber) { <div class="yui-b"><div class="yui-g"> <div id="userauthdetails" class="container"> + <div id="views"><span class="view"><a id="MARCview" href="/cgi-bin/koha/opac-authoritiesdetail.pl?authid=[% authid %]">Normal view</a></span> <span class="view"><span id="MARCview">MARC view</span></span></div> + [% IF ( displayhierarchy ) %] <div class="hierarchies"> diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-detail.tt new file mode 100644 index 0000000..c94348f --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth-detail.tt @@ -0,0 +1,174 @@ +[% BLOCK authtypelabel %] + [% UNLESS ( type=='seefrom' || type=='seealso' || type=='' ) %] + <span class="type">[% FILTER trim %][% SWITCH type %] + [% CASE 'earlier' %]Earlier heading + [% CASE 'later' %]Later heading + [% CASE 'acronym' %]Acronym + [% CASE 'musical' %]Musical composition + [% CASE 'broader' %]Broader heading + [% CASE 'narrower' %]Narrower heading + [% CASE %][% type %] + [% END %][% END %]</span> + [% END %] +[% END %] +[% BLOCK otherscript %] + [% FOREACH heading IN headings %] + [% IF heading.category == wantcategory %] + [% IF heading.direction == 'ltr' %] + <div class="heading otherscript [% heading.category %]"> + <span class="[% heading.category %]">[% heading.term %]</span> + </div> + [% ELSIF heading.direction == 'rtl' %] + <div class="heading otherscript [% heading.category %] rtl"> + <span class="[% heading.category %]">[% heading.term %]</span> + </div> + [% END %] + [% END %] + [% END %] +[% END %] +[% BLOCK authheadingdisplay %] + [% IF authid %]<a href="/cgi-bin/koha/opac-authoritiesdetail.pl?authid=[% authid %]">[% heading %]</a> + [% ELSIF search %]<a href="/cgi-bin/koha/opac-authorities-home.pl?op=do_search&type=opac&operator=contains&marclist=mainentry&and_ora=and&orderby=HeadingAsc&value=[% search %]">[% heading %]</a> + [% ELSE %][% heading %] + [% END %] +[% END %] +[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Entry +[% INCLUDE 'doc-head-close.inc' %] +[% IF ( displayhierarchy ) %] +<link rel="stylesheet" type="text/css" href="[% themelang %]/css/hierarchy.css"> +[% END %] +<script language="JavaScript" type="text/javascript"> +$(document).ready(function() { + $('#authdescriptions').tabs(); +}); + +[% IF ( displayhierarchy ) %] +function showParents(mynumber) { + var parents=document.getElementsByName(mynumber+'p') + for(i=0;i<parents.length;i++){ + if (parents[i].style.display == "none") { + parents[i].style.display ="block"; + } else { + parents[i].style.display ="none"; + } + } +} +function showChildren(mynumber) { + var children=document.getElementsByName(mynumber+'c') + for(i=0;i<children.length;i++){ + if (children[i].style.display == "none") { + children[i].style.display = "block"; + } else { + children[i].style.display = "none"; + } + } +} +[% END %] +</script> +</head> +<body id="opac-authoritiesdetail"> + +<div id="doc3" class="yui-t1"> + <div id="bd"> +[% INCLUDE 'masthead.inc' %] + <div id="yui-main"> + <div class="yui-b"><div class="yui-g"> + + <div id="views"><span class="view"><span id="Normalview">Normal view</span></span> <span class="view"><a id="MARCview" href="/cgi-bin/koha/opac-authoritiesdetail.pl?authid=[% authid %]&marc=1">MARC view</a></span></div> + +<div id="userauthdetails" class="container"> + +[% IF ( displayhierarchy ) %] + +<div class="hierarchies"> +[% FOREACH loophierarchie IN loophierarchies %] + <div class="hierarchy"> + [% FOREACH loopelemen IN loophierarchie.loopelement %] + <div id="[% loopelemen.loopauthid %]" class="[% loopelemen.class %]"> + [% IF ( loopelemen.current_value ) %] + [% loopelemen.value %] + [% ELSE %] + <a href="opac-authoritiesdetail.pl?authid=[% loopelemen.loopauthid %]" title="Term">[% loopelemen.value %]</a> + [% END %] + [% IF ( loopelemen.ifchildren ) %] + <sub><a class="parents" title="Narrower terms" href="JavaScript:showChildren('[% loopelemen.loopauthid %]');">+</a></sub><br/> + [% FOREACH loopchildre IN loopelemen.loopchildren %] + <div name="[% loopchildre.loopauthid %]c" class="child"> <a href="opac-authoritiesdetail.pl?authid=[% loopchildre.childauthid %]">[% loopchildre.childvalue %]</a></div> + [% END %] + [% END %] + </div> + [% END %] + + </div> +[% END %] +</div> +[% END %] +<h1>[% summary.mainentry %] ([% authtypetext %])</h1> +<div class="usedin">Used in <a href="opac-search.pl?type=opac&q=[% authid %]&idx=an,phr">[% count %] records</a></div> +<div class="authstanza"> +[% FOREACH authorize IN summary.authorized %] +<div class="heading authorized"><span class="label">Preferred form: </span><span class="authorized">[% authorize %]</span></div> +[% END %] +[% PROCESS otherscript headings=summary.otherscript wantcategory='preferred' %] +</div> +[% IF summary.seefrom %] + <div class="authstanza seefrom"> + <div class="authstanzaheading">Used for/see from:</div> + <ul class="seefrom"> + [% FOREACH seefro IN summary.seefrom %] + <li class="heading seefrom"><!--<span class="label">Used for/see from:</span>--> + <span class="seefrom">[% PROCESS authheadingdisplay heading=seefro.heading search=seefrosearch authid=seefro.authid %]</span> + [% PROCESS authtypelabel type=seefro.type | trim %] + </li> + [% END %] + [% PROCESS otherscript headings=summary.otherscript wantcategory='seefrom' %] + </div> +[% END %] +[% IF summary.seealso %] + <div class="authstanza seealso"> + <div class="authstanzaheading">See also:</div> + <ul class="seelso"> + [% FOREACH seeals IN summary.seealso %] + <li class="heading seealso"> + [% IF seeals.type %]<span class="label">[% PROCESS authtypelabel type=seeals.type | trim %]:</span>[% END %] + <span class="seealso">[% PROCESS authheadingdisplay heading=seeals.heading search=seeals.search authid=seeals.authid %]</span> + </li> + [% END %] + [% PROCESS otherscript headings=summary.otherscript wantcategory='seealso' %] + </div> +[% END %] +[% IF marcflavour == 'UNIMARC' && summary.otherscript %] + <div class="authstanza"> + [% FOREACH otherscrip IN summary.otherscript %] + <div class="heading otherscript"><span class="label">See also[% PROCESS language lang=otherscript.lang | trim %] term:</span> + <span class="otherscript">[% otherscrip.term %]</span> + </div> + [% END %] + </div> +[% END %] +<div id="authdescriptions" class="toptabs"> +<ul> + <li id="tab_descriptions" class="ui-tabs-selected"><a href="#descriptions">Notes</a></li> +</ul> +<div id="descriptions"> +<div class="content_set"> +[% FOREACH note IN summary.notes %] +<p class="note">[% note %]</p> +[% END %] +</div> +</div> +</div> +</div> +</div> + +</div> +</div> +</div> +[% IF ( OpacNav ) %] +<div class="yui-b"> +<div id="leftmenus" class="container"> +[% INCLUDE 'navigation.inc' %] +</div> +</div>[% END %] +</div> +[% INCLUDE 'opac-bottom.inc' %] diff --git a/opac/opac-authoritiesdetail.pl b/opac/opac-authoritiesdetail.pl index 2884373..278db99 100755 --- a/opac/opac-authoritiesdetail.pl +++ b/opac/opac-authoritiesdetail.pl @@ -53,7 +53,7 @@ my $query = new CGI; my $dbh = C4::Context->dbh; my $display_hierarchy = C4::Context->preference("AuthDisplayHierarchy"); -my $show_marc = $query->param('marc') || 1; # Currently only MARC view is available +my $show_marc = $query->param('marc'); # open template my ( $template, $loggedinuser, $cookie ) = get_template_and_user( @@ -68,8 +68,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( my $authid = $query->param('authid'); my $authtypecode = &GetAuthTypeCode( $authid ); -my $tagslib = &GetTagsLabels( 0, $authtypecode ); - my $record; if ($display_hierarchy){ @@ -101,90 +99,92 @@ else { } my $count = CountUsage($authid); -# find the marc field/subfield used in biblio by this authority -my $sth = - $dbh->prepare( - "select distinct tagfield from marc_subfield_structure where authtypecode=?" - ); -$sth->execute($authtypecode); -my $biblio_fields; -while ( my ($tagfield) = $sth->fetchrow ) { - $biblio_fields .= $tagfield . "9,"; + +my $authtypes = getauthtypes(); +my @authtypesloop = (); +foreach my $thisauthtype ( keys %{$authtypes} ) { + push @authtypesloop, + { value => $thisauthtype, + selected => $thisauthtype eq $authtypecode, + authtypetext => $authtypes->{$thisauthtype}{'authtypetext'}, + }; } -chop $biblio_fields; +$template->{VARS}->{'authtypesloop'} = \@authtypesloop; +$template->{VARS}->{'authtypetext'} = $authtypes->{$authtypecode}{'authtypetext'}; +$template->{VARS}->{'authid'} = $authid; +$template->{VARS}->{'count'} = $count; + +# find the marc field/subfield used in biblio by this authority +if ($show_marc) { + my $tagslib = &GetTagsLabels( 0, $authtypecode ); + my $sth = + $dbh->prepare( + "select distinct tagfield from marc_subfield_structure where authtypecode=?" + ); + $sth->execute($authtypecode); + my $biblio_fields; + while ( my ($tagfield) = $sth->fetchrow ) { + $biblio_fields .= $tagfield . "9,"; + } + chop $biblio_fields; # fill arrays -my @loop_data = (); -my $tag; + my @loop_data = (); + my $tag; -# loop through each tab 0 through 9 -# for (my $tabloop = 0; $tabloop<=10;$tabloop++) { # loop through each tag -my @fields = $record->fields(); -foreach my $field (@fields) { - my @subfields_data; - - # skip UNIMARC fields <200, they are useless for a patron - next if C4::Context->preference('MarcFlavour') eq 'UNIMARC' && $field->tag() <200; - - # if tag <10, there's no subfield, use the "@" trick - if ( $field->tag() < 10 ) { - next if ( $tagslib->{ $field->tag() }->{'@'}->{hidden} ); - my %subfield_data; - $subfield_data{marc_lib} = $tagslib->{ $field->tag() }->{'@'}->{lib}; - $subfield_data{marc_value} = $field->data(); - $subfield_data{marc_subfield} = '@'; - $subfield_data{marc_tag} = $field->tag(); - push( @subfields_data, \%subfield_data ); - } - else { - my @subf = $field->subfields; - - # loop through each subfield - for my $i ( 0 .. $#subf ) { - $subf[$i][0] = "@" unless $subf[$i][0]; - next if ( $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{hidden} ); - # skip useless subfields (for patrons) - next if $subf[$i][0] =~ /7|8|9/; + my @fields = $record->fields(); + foreach my $field (@fields) { + my @subfields_data; + +# skip UNIMARC fields <200, they are useless for a patron + next if C4::Context->preference('MarcFlavour') eq 'UNIMARC' && $field->tag() <200; + +# if tag <10, there's no subfield, use the "@" trick + if ( $field->tag() < 10 ) { + next if ( $tagslib->{ $field->tag() }->{'@'}->{hidden} ); my %subfield_data; - $subfield_data{marc_lib} = - $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{lib}; - $subfield_data{marc_subfield} = $subf[$i][0]; + $subfield_data{marc_lib} = $tagslib->{ $field->tag() }->{'@'}->{lib}; + $subfield_data{marc_value} = $field->data(); + $subfield_data{marc_subfield} = '@'; $subfield_data{marc_tag} = $field->tag(); - $subfield_data{isurl} = $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{isurl}; - $subfield_data{marc_value} = $subf[$i][1]; push( @subfields_data, \%subfield_data ); } + else { + my @subf = $field->subfields; + +# loop through each subfield + for my $i ( 0 .. $#subf ) { + $subf[$i][0] = "@" unless $subf[$i][0]; + next if ( $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{hidden} ); +# skip useless subfields (for patrons) + next if $subf[$i][0] =~ /7|8|9/; + my %subfield_data; + $subfield_data{marc_lib} = + $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{lib}; + $subfield_data{marc_subfield} = $subf[$i][0]; + $subfield_data{marc_tag} = $field->tag(); + $subfield_data{isurl} = $tagslib->{ $field->tag() }->{ $subf[$i][0] }->{isurl}; + $subfield_data{marc_value} = $subf[$i][1]; + push( @subfields_data, \%subfield_data ); + } + } + if ( $#subfields_data >= 0 ) { + my %tag_data; + $tag_data{tag} = + $field->tag() + . ' ' + . C4::Koha::display_marc_indicators($field) + . ' - ' . $tagslib->{ $field->tag() }->{lib}; + $tag_data{subfield} = \@subfields_data; + push( @loop_data, \%tag_data ); + } } - if ( $#subfields_data >= 0 ) { - my %tag_data; - $tag_data{tag} = - $field->tag() - . ' ' - . C4::Koha::display_marc_indicators($field) - . ' - ' . $tagslib->{ $field->tag() }->{lib}; - $tag_data{subfield} = \@subfields_data; - push( @loop_data, \%tag_data ); - } -} -$template->param( "Tab0XX" => \@loop_data ); - -my $authtypes = getauthtypes(); -my @authtypesloop = (); -foreach my $thisauthtype ( keys %{$authtypes} ) { - push @authtypesloop, - { value => $thisauthtype, - selected => $thisauthtype eq $authtypecode, - authtypetext => $authtypes->{$thisauthtype}{'authtypetext'}, - }; + $template->param( "Tab0XX" => \@loop_data ); +} else { + my $summary = BuildSummary($record, $authid, $authtypecode); + $template->{VARS}->{'summary'} = $summary; } -$template->param( - authid => $authid, - count => $count, - biblio_fields => $biblio_fields, - authtypetext => $authtypes->{$authtypecode}{'authtypetext'}, - authtypesloop => \@authtypesloop, -); output_html_with_http_headers $query, $cookie, $template->output; -- 1.7.2.5