@@ -, +, @@ - OpenURLinOPACResults: enable or disable this feature - OpenURLResolverURL: url of the openURL resolver - OpenURLText: text of the link - OpenURLImageLocation: image of the link - Title should be in rft.jtitle instead of rft.title - rft.date, rft.aulast, rft.aufirst, rft.au, rft.pub and rft.pages have no meaning for a subscription, so they are simply removed from URL $var .= "&$value" --- C4/Biblio.pm | 133 +++++++++++--------- C4/XSLT.pm | 22 +++- installer/data/mysql/sysprefs.sql | 5 + installer/data/mysql/updatedatabase.pl | 27 ++++ .../prog/en/modules/admin/preferences/opac.pref | 27 ++++ koha-tmpl/opac-tmpl/prog/en/css/opac.css | 5 +- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 22 ++++ .../opac-tmpl/prog/en/modules/opac-results.tt | 18 +++ .../prog/en/xslt/MARC21slim2OPACDetail.xsl | 59 +++++++++ .../prog/en/xslt/MARC21slim2OPACResults.xsl | 61 ++++++++- .../prog/en/xslt/UNIMARCslim2OPACDetail.xsl | 60 +++++++++ .../prog/en/xslt/UNIMARCslim2OPACResults.xsl | 59 +++++++++ opac/opac-detail.pl | 14 +++ opac/opac-search.pl | 18 ++- 14 files changed, 465 insertions(+), 65 deletions(-) --- a/C4/Biblio.pm +++ a/C4/Biblio.pm @@ -29,6 +29,7 @@ use MARC::File::USMARC; use MARC::File::XML; use POSIX qw(strftime); use Module::Load::Conditional qw(can_load); +use URI::Escape; # GetCOinSBiblio use C4::Koha; use C4::Dates qw/format_date/; @@ -1301,48 +1302,45 @@ sub GetCOinSBiblio { my $record = shift; # get the coin format - if ( ! $record ) { - return; - } + return unless ( $record ); + my $pos7 = substr $record->leader(), 7, 1; my $pos6 = substr $record->leader(), 6, 1; my $mtx; my $genre; my ( $aulast, $aufirst ) = ( '', '' ); - my $oauthors = ''; - my $title = ''; - my $subtitle = ''; + my @authors; + my $title; + my $hosttitle; my $pubyear = ''; my $isbn = ''; my $issn = ''; my $publisher = ''; my $pages = ''; - my $titletype = 'b'; + my $titletype = ''; # For the purposes of generating COinS metadata, LDR/06-07 can be # considered the same for UNIMARC and MARC21 - my $fmts6; - my $fmts7; - %$fmts6 = ( - 'a' => 'book', - 'b' => 'manuscript', - 'c' => 'book', - 'd' => 'manuscript', - 'e' => 'map', - 'f' => 'map', - 'g' => 'film', - 'i' => 'audioRecording', - 'j' => 'audioRecording', - 'k' => 'artwork', - 'l' => 'document', - 'm' => 'computerProgram', - 'o' => 'document', - 'r' => 'document', - ); - %$fmts7 = ( - 'a' => 'journalArticle', - 's' => 'journal', - ); + my $fmts6 = { + 'a' => 'book', + 'b' => 'manuscript', + 'c' => 'book', + 'd' => 'manuscript', + 'e' => 'map', + 'f' => 'map', + 'g' => 'film', + 'i' => 'audioRecording', + 'j' => 'audioRecording', + 'k' => 'artwork', + 'l' => 'document', + 'm' => 'computerProgram', + 'o' => 'document', + 'r' => 'document', + }; + my $fmts7 = { + 'a' => 'journalArticle', + 's' => 'journal', + }; $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book'; @@ -1353,6 +1351,7 @@ sub GetCOinSBiblio { ##### We must transform mtx to a valable mtx and document type #### if ( $genre eq 'book' ) { $mtx = 'book'; + $titletype = 'b'; } elsif ( $genre eq 'journal' ) { $mtx = 'journal'; $titletype = 'j'; @@ -1364,26 +1363,25 @@ sub GetCOinSBiblio { $mtx = 'dc'; } - $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre"; - if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) { # Setting datas $aulast = $record->subfield( '700', 'a' ) || ''; $aufirst = $record->subfield( '700', 'b' ) || ''; - $oauthors = "&rft.au=$aufirst $aulast"; + push @authors, "$aufirst $aulast" if ($aufirst or $aulast); # others authors if ( $record->field('200') ) { for my $au ( $record->field('200')->subfield('g') ) { - $oauthors .= "&rft.au=$au"; + push @authors, $au; } } - $title = - ( $mtx eq 'dc' ) - ? "&rft.title=" . $record->subfield( '200', 'a' ) - : "&rft.title=" . $record->subfield( '200', 'a' ) . "&rft.btitle=" . $record->subfield( '200', 'a' ); - $pubyear = $record->subfield( '210', 'd' ) || ''; + + $title = $record->subfield( '200', 'a' ); + my $subfield_210d = $record->subfield('210', 'd'); + if ($subfield_210d and $subfield_210d =~ /(\d{4})/) { + $pubyear = $1; + } $publisher = $record->subfield( '210', 'c' ) || ''; $isbn = $record->subfield( '010', 'a' ) || ''; $issn = $record->subfield( '011', 'a' ) || ''; @@ -1393,34 +1391,24 @@ sub GetCOinSBiblio { # Setting datas if ( $record->field('100') ) { - $oauthors .= "&rft.au=" . $record->subfield( '100', 'a' ); + push @authors, $record->subfield( '100', 'a' ); } # others authors if ( $record->field('700') ) { for my $au ( $record->field('700')->subfield('a') ) { - $oauthors .= "&rft.au=$au"; + push @authors, $au; } } - $title = "&rft." . $titletype . "title=" . $record->subfield( '245', 'a' ); - $subtitle = $record->subfield( '245', 'b' ) || ''; - $title .= $subtitle; + $title = $record->subfield( '245', 'a' ) . $record->subfield( '245', 'b' ); if ($titletype eq 'a') { $pubyear = $record->field('008') || ''; $pubyear = substr($pubyear->data(), 7, 4) if $pubyear; $isbn = $record->subfield( '773', 'z' ) || ''; $issn = $record->subfield( '773', 'x' ) || ''; - if ($mtx eq 'journal') { - $title .= "&rft.title=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a'))); - } else { - $title .= "&rft.btitle=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')) || ''); - } - foreach my $rel ($record->subfield( '773', 'g' )) { - if ($pages) { - $pages .= ', '; - } - $pages .= $rel; - } + $hosttitle = $record->subfield( '773', 't' ) || $record->subfield( '773', 'a'); + my @rels = $record->subfield( '773', 'g' ); + $pages = join(', ', @rels); } else { $pubyear = $record->subfield( '260', 'c' ) || ''; $publisher = $record->subfield( '260', 'b' ) || ''; @@ -1429,12 +1417,39 @@ sub GetCOinSBiblio { } } - my $coins_value = -"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear&rft.pages=$pages"; - $coins_value =~ s/(\ |&[^a])/\+/g; - $coins_value =~ s/\"/\"\;/g; -#&rft.au=&rft.btitle=&rft.date=&rft.pages=&rft.isbn=&rft.aucorp=&rft.place=&rft.pub=&rft.edition=&rft.series=&rft.genre=" + my @params = ( + [ 'ctx_ver', 'Z39.88-2004' ], + [ 'rft_val_fmt', "info:ofi/fmt:kev:mtx:$mtx" ], + [ ($mtx eq 'dc' ? 'rft.type' : 'rft.genre'), $genre ], + [ "rft.${titletype}title", $title ], + ); + + # rft.title is authorized only once, so by checking $titletype + # we ensure that rft.title is not already in the list. + if ($hosttitle and $titletype) { + push @params, [ 'rft.title', $hosttitle ]; + } + + push @params, ( + [ 'rft.isbn', $isbn ], + [ 'rft.issn', $issn ], + ); + + # If it's a subscription, these informations have no meaning. + if ($genre ne 'journal') { + push @params, ( + [ 'rft.aulast', $aulast ], + [ 'rft.aufirst', $aufirst ], + (map { [ 'rft.au', $_ ] } @authors), + [ 'rft.pub', $publisher ], + [ 'rft.date', $pubyear ], + [ 'rft.pages', $pages ], + ); + } + + my $coins_value = join( '&', + map { $$_[1] ? $$_[0] . '=' . uri_escape( $$_[1] ) : () } @params ); return $coins_value; } --- a/C4/XSLT.pm +++ a/C4/XSLT.pm @@ -157,7 +157,7 @@ sub _get_best_default_xslt_filename { } sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items, $variables ) = @_; my $xslfilename = C4::Context->preference($xslsyspref); if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { my $htdocs; @@ -207,14 +207,30 @@ sub XSLTParse4Display { UseControlNumber IntranetBiblioDefaultView BiblioDefaultView singleBranchMode OPACItemLocation DisplayIconsXSLT AlternateHoldingsField AlternateHoldingsSeparator - TrackClicks / ) + TrackClicks + OPACShowOpenURL OpenURLResolverURL + OpenURLImageLocation OpenURLText / ) { my $sp = C4::Context->preference( $syspref ); next unless defined($sp); $sysxml .= "$sp\n"; } $sysxml .= "\n"; - $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml\<\/record\>/; + + $variables ||= {}; + if (C4::Context->preference('OPACShowOpenURL')) { + my ($biblio) = GetBiblioItemByBiblioNumber($biblionumber); + my @itypes = split( /\s/, C4::Context->preference('OPACHideOpenURLForItemTypes') ); + if (not grep /^$biblio->{itemtype}$/, @itypes) { + $variables->{COinS} = C4::Biblio::GetCOinSBiblio($orig_record); + } + } + my $varxml = "\n"; + while (my ($key, $value) = each %$variables) { + $varxml .= "$value\n"; + } + $varxml .= "\n"; + $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml$varxml\<\/record\>/; if ($fixamps) { # We need to correct the ampersand entities that Zebra outputs $xmlrecord =~ s/\&amp;/\&/g; } --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -423,4 +423,9 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('yuipath','local','local|http://yui.yahooapis.com/2.5.1/build','Insert the path to YUI libraries, choose local if you use koha offline','Choice'), ('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'), ('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo') +('OpenURLResolverURL', '', NULL, 'URL of OpenURL Resolver', 'Free') +('OpenURLText', '', NULL, 'Text of OpenURL links (or image title if OpenURLImageLocation is defined)', 'Free') +('OpenURLImageLocation', '', NULL, 'Location of image for OpenURL links', 'Free') +('OPACShowOpenURL', '', NULL, 'Enable display of OpenURL links in OPAC search results and detail page', 'YesNo') +('OPACHideOpenURLForItemTypes', '', NULL, 'Allow hiding the OpenURL link for some item types', 'Free') ; --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -7743,6 +7743,33 @@ if(CheckVersion($DBversion)) { SetVersion($DBversion); } +$DBversion = "XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('OpenURLResolverURL', '', 'URL of OpenURL Resolver', NULL, 'Free') + "); + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('OpenURLText', '', 'Text of OpenURL links (or image title if OpenURLImageLocation is defined)', NULL, 'Free'); + "); + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('OpenURLImageLocation', '', 'Location of image for OpenURL links', NULL, 'Free'); + "); + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('OPACShowOpenURL', '', 'Enable display of OpenURL links in OPAC search results and detail page', NULL, 'YesNo'); + "); + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('OPACHideOpenURLForItemTypes', '', 'Allow hiding the OpenURL link for some item types', NULL, 'Free'); + "); + print "Upgrade to $DBversion done (Add sysprefs for OpenURL)\n"; + SetVersion($DBversion); +} + + =head1 FUNCTIONS =head2 TableExists($table) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -280,6 +280,33 @@ OPAC: homebranch: 'home library' holdingbranch: 'holding library' - "is the logged in user's library. The second tab will contain all other items." + - + - 'Complete URL of OpenURL resolver (starting with http:// or https://):' + - pref: OpenURLResolverURL + class: url + - + - 'Text of OpenURL links (or image title if OpenURLImageLocation is defined):' + - pref: OpenURLText + - + - 'Location of image for OpenURL links:' + - pref: OpenURLImageLocation + class: url + - '
Can be a complete URL starting with http:// or' + - 'https:// or the name of a file in images directory' + - '
Examples:' + - '
- http://www.example.com/img/openurl.png' + - '
- OpenURL/OpenURL.png (file is in opac-tmpl/<opacthemes>/images/OpenURL/OpenURL.png)' + - + - pref: OPACShowOpenURL + choices: + yes: Enable + no: Disable + - 'display of OpenURL link in OPAC search results and detail page.' + - + - 'List of item type codes (separated by spaces) for those you do not want to show the OpenURL link:' + - pref: OPACHideOpenURLForItemTypes + - '
' + - 'It uses biblioitems.itemtype field, so if you map a MARC field to it, and link this MARC field to a list of authorised values (for example CCODE), you can use these values for system preference value.' Features: - - pref: opacuserlogin --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ a/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -1,6 +1,5 @@ @import url("/opac-tmpl/lib/yui/reset-fonts-grids.css"); @import url("/opac-tmpl/lib/yui/skin.css"); - a { font-weight : bold; } @@ -3080,3 +3079,7 @@ padding: 0.1em 0; .copiesrow { clear : both; } + +a.OpenURL img { + vertical-align: middle; +} --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -768,6 +768,28 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% END %] [% END %] + + [% IF (OPACShowOpenURL && OpenURLResolverURL && ocoins) %] + [%# Build OpenURL image location %] + [% IF (OpenURLImageLocation && !OpenURLImageLocation.match('^https?://')) %] + [% openurlimagelocation = "$interface/$theme/images/$OpenURLImageLocation" %] + [% ELSE %] + [% openurlimagelocation = "$OpenURLImageLocation" %] + [% END %] + + + + [% IF openurlimagelocation %] + + [% ELSIF OpenURLText %] + [% OpenURLText %] + [% ELSE %] + OpenURL + [% END %] + + + [% END %] + [% END %] [% IF ( AuthorisedValueImages ) %] [% IF ( authorised_value_images ) %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -485,6 +485,13 @@ $(document).ready(function(){ + [%# Build OpenURL image location %] + [% IF (OpenURLImageLocation && !OpenURLImageLocation.match('^https?://')) %] + [% openurlimagelocation = "$interface/$theme/images/$OpenURLImageLocation" %] + [% ELSE %] + [% openurlimagelocation = "$OpenURLImageLocation" %] + [% END %] + [% FOREACH SEARCH_RESULT IN SEARCH_RESULTS %] [% UNLESS ( loop.odd ) %] @@ -542,6 +549,17 @@ $(document).ready(function(){ [% IF ( SEARCH_RESULT.author ) %]by [% SEARCH_RESULT.author %] [% ELSE %]  [% END %] + [% IF (SEARCH_RESULT.ShowOpenURL && OpenURLResolverURL && SEARCH_RESULT.coins) %] + + [% IF openurlimagelocation %] + + [% ELSIF OpenURLText %] + [% OpenURLText %] + [% ELSE %] + OpenURL + [% END %] + + [% END %] Publication: [% IF ( SEARCH_RESULT.place ) %][% SEARCH_RESULT.place %] [% END %][% IF ( SEARCH_RESULT.publishercode ) %][% SEARCH_RESULT.publishercode|html %][% END %][% IF ( SEARCH_RESULT.publicationyear ) %] [% SEARCH_RESULT.publicationyear %] [% ELSE %][% IF ( SEARCH_RESULT.copyrightdate ) %] [% SEARCH_RESULT.copyrightdate %][% END %][% END %] --- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl +++ a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl @@ -981,6 +981,65 @@ + + + + + + + + + + + + + + + OpenURL + + + + + + + + + + + /opac-tmpl/prog/images/ + + + + + + + + + ? + + + + + + + OpenURL + + + + + + + + + + + + + + + + + --- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl +++ a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl @@ -438,8 +438,67 @@ -

+ + + + + + + + + + + + + + + OpenURL + + + + + + + + + + + /opac-tmpl/prog/images/ + + + + + +   + + + ? + + + + + + + OpenURL + + + + + + + + + + + + + + + + + +

--- a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACDetail.xsl +++ a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACDetail.xsl @@ -438,6 +438,66 @@ + + + + + + + + + + + + + + + + OpenURL + + + + + + + + + + + /opac-tmpl/prog/images/ + + + + + + + + + ? + + + + + + + OpenURL + + + + + + + + + + + + + + + + + --- a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl +++ a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl @@ -77,6 +77,65 @@ + + + + + + + + + + + + + + + OpenURL + + + + + + + + + + + /opac-tmpl/prog/images/ + + + + + +   + + + ? + + + + + + + OpenURL + + + + + + + + + + + + + + + + + 454 Translation of --- a/opac/opac-detail.pl +++ a/opac/opac-detail.pl @@ -1069,4 +1069,18 @@ if ( C4::Context->preference('UseCourseReserves') ) { } } +# OpenURL +if (C4::Context->preference('OPACShowOpenURL')) { + my ($biblio) = GetBiblioItemByBiblioNumber($biblionumber); + my @itypes = split( /\s/, C4::Context->preference('OPACHideOpenURLForItemTypes') ); + if (not grep /^$biblio->{itemtype}$/, @itypes) { + $template->param( + OPACShowOpenURL => 1, + OpenURLResolverURL => C4::Context->preference('OpenURLResolverURL'), + OpenURLText => C4::Context->preference('OpenURLText'), + OpenURLImageLocation => C4::Context->preference('OpenURLImageLocation') + ); + } +} + output_html_with_http_headers $query, $cookie, $template->output; --- a/opac/opac-search.pl +++ a/opac/opac-search.pl @@ -486,6 +486,18 @@ if (C4::Context->preference('OpacSuppression')) { } } +# OpenURL +my @OpenURL_itypes_to_hide; +if (C4::Context->preference('OPACShowOpenURL')) { + @OpenURL_itypes_to_hide = split( /\s/, C4::Context->preference('OPACHideOpenURLForItemTypes') ); + $template->param( + OPACShowOpenURL => 1, + OpenURLResolverURL => C4::Context->preference('OpenURLResolverURL'), + OpenURLText => C4::Context->preference('OpenURLText'), + OpenURLImageLocation => C4::Context->preference('OpenURLImageLocation') + ); +} + $template->param ( LIMIT_INPUTS => \@limit_inputs ); $template->param ( OPACResultsSidebar => C4::Context->preference('OPACResultsSidebar')); @@ -567,7 +579,11 @@ for (my $i=0;$i<@servers;$i++) { $res->{'incart'} = 1; } - if (C4::Context->preference('COinSinOPACResults')) { + if (C4::Context->preference('COinSinOPACResults') + or C4::Context->preference('OPACShowOpenURL')) { + if (not grep /^$res->{itemtype}$/, @OpenURL_itypes_to_hide) { + $res->{ShowOpenURL} = 1; + } my $record = GetMarcBiblio($res->{'biblionumber'}); $res->{coins} = GetCOinSBiblio($record); } --