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=='' ) %]
+        &nbsp;<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 &rsaquo;  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&amp;q=[% authid %]&amp;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