@@ -, +, @@ the OPAC targets screen. Note that not all targets support keyword search, but here are some that do: * Library of Congress: lx2.loc.gov, 210, LCDB, none, none, MARC21, UTF-8 * BNF2: z3950.bnf.fr, 2211, TOUT, Z3950, Z3950_BNF, UNIMARC, UTF-8 notice pops up at the top. should be clickable to bring up a detailed view of the record. --- C4/Search.pm | 30 + C4/XSLT.pm | 24 +- Makefile.PL | 2 +- admin/external_targets.pl | 125 +++ etc/koha-conf.xml | 13 - etc/koha-httpd.conf | 15 +- etc/pazpar2/generic-settings.xml | 21 + etc/pazpar2/pazpar2.xml | 2 +- etc/pazpar2/unimarc-work-groups.xsl | 98 ++ installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 33 + .../intranet-tmpl/prog/en/css/staff-global.css | 14 + .../intranet-tmpl/prog/en/includes/admin-menu.inc | 1 + .../prog/en/modules/admin/admin-home.tt | 2 + .../prog/en/modules/admin/external-targets.tt | 180 ++++ .../prog/en/modules/admin/preferences/opac.pref | 7 + koha-tmpl/opac-tmpl/bootstrap/css/opac.css | 21 +- .../opac-tmpl/bootstrap/en/modules/opac-results.tt | 59 +- .../bootstrap/en/xslt/MARC21slim2OPACResults.xsl | 7 +- .../bootstrap/en/xslt/MARC21slimUtils.xsl | 2 +- .../bootstrap/en/xslt/UNIMARCslim2OPACResults.xsl | 4 + koha-tmpl/opac-tmpl/ccsr/en/css/opac.css | 16 + koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ koha-tmpl/opac-tmpl/lib/pz2.js | 1124 ++++++++++++++++++++ koha-tmpl/opac-tmpl/prog/en/css/opac.css | 27 +- koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ .../prog/en/modules/opac-external-search.tt | 240 +++++ .../opac-tmpl/prog/en/modules/opac-results.tt | 59 +- .../prog/en/xslt/MARC21slim2OPACResults.xsl | 6 +- .../opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl | 2 +- .../prog/en/xslt/UNIMARCslim2OPACResults.xsl | 4 + opac/opac-external-search.pl | 62 ++ opac/opac-search.pl | 12 +- opac/svc/pazpar2_init | 100 ++ rewrite-config.PL | 8 +- t/XSLT.t | 94 +- 38 files changed, 3063 insertions(+), 72 deletions(-) create mode 100755 admin/external_targets.pl create mode 100644 etc/pazpar2/generic-settings.xml create mode 100644 etc/pazpar2/unimarc-work-groups.xsl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/lib/pz2.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt create mode 100755 opac/opac-external-search.pl create mode 100755 opac/svc/pazpar2_init --- a/C4/Search.pm +++ a/C4/Search.pm @@ -72,6 +72,7 @@ This module provides searching functions for Koha's bibliographic databases &GetDistinctValues &enabled_staff_search_views &PurgeSearchHistory + &GetExternalSearchTargets ); # make all your functions, whether exported or not; @@ -2379,6 +2380,35 @@ sub _ZOOM_event_loop { } } +=head2 GetExternalSearchTargets + +Returns the list of Z39.50 servers that are marked for search in the OPAC using +Pazpar2. + +=cut + +sub GetExternalSearchTargets { + my ( $branchcode ) = @_; + + if ( $branchcode ) { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr + ON (etr.target_id = et.target_id and etr.branchcode = ?) + WHERE etr.target_id IS NULL + ORDER BY et.name + }, { Slice => {} }, $branchcode ); + } else { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr USING (target_id) + GROUP by et.target_id + HAVING branchcode IS NULL + ORDER BY et.name + }, { Slice => {} } ); + } +} + END { } # module clean-up code here (global destructor) --- a/C4/XSLT.pm +++ a/C4/XSLT.pm @@ -42,6 +42,7 @@ BEGIN { $VERSION = 3.07.00.049; @ISA = qw(Exporter); @EXPORT = qw( + &XSLTGetFilename &XSLTParse4Display &GetURI ); @@ -156,9 +157,10 @@ sub _get_best_default_xslt_filename { return $xslfilename; } -sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; - my $xslfilename = C4::Context->preference($xslsyspref); +sub XSLTGetFilename { + my ( $marcflavour, $xslsyspref ) = @_; + + my $xslfilename = $marcflavour eq C4::Context->preference('marcflavour') ? C4::Context->preference($xslsyspref) : 'default'; if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { my $htdocs; my $theme; @@ -167,22 +169,22 @@ sub XSLTParse4Display { if ($xslsyspref eq "XSLTDetailsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetDetail.xsl"; } elsif ($xslsyspref eq "XSLTResultsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetResults.xsl"; } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACDetail.xsl"; } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACResults.xsl"; } $xslfilename = _get_best_default_xslt_filename($htdocs, $theme, $lang, $xslfile); @@ -193,6 +195,14 @@ sub XSLTParse4Display { $xslfilename =~ s/\{langcode\}/$lang/; } + return $xslfilename; +} + +sub XSLTParse4Display { + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; + + my $xslfilename = XSLTGetFilename( C4::Context->preference( 'marcflavour' ), $xslsyspref ); + # grab the XML, run it through our stylesheet, push it out to the browser my $record = transformMARCXML4XSLT($biblionumber, $orig_record); #return $record->as_formatted(); --- a/Makefile.PL +++ a/Makefile.PL @@ -536,7 +536,7 @@ if ($config{'INSTALL_ZEBRA'} eq "yes") { ); if ($config{'INSTALL_PAZPAR2'} eq 'yes') { push @{ $pl_files->{'rewrite-config.PL'} }, ( - 'blib/PAZPAR2_CONF_DIR/koha-biblios.xml', + 'blib/PAZPAR2_CONF_DIR/generic-settings.xml', 'blib/PAZPAR2_CONF_DIR/pazpar2.xml' ); } --- a/admin/external_targets.pl +++ a/admin/external_targets.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl +# +# Copyright 2013 Jesse Weaver +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +use Modern::Perl '2010'; + +use CGI; + +use C4::Auth; +use C4::Context; +use C4::Branch; +use C4::Output; +use URI::Escape; + +our $dbh = C4::Context->dbh; +our $input = new CGI; + +our ( $template, $loggedinuser, $cookie ) = get_template_and_user( { + template_name => "admin/external-targets.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {parameters => 'parameters_remaining_permissions'}, + debug => 1, +} ); + +our $op = $input->param( 'op' ) // 'show'; +$template->{VARS}->{op} = $op; + +given ( $op ) { + when ( 'show' ) { show_external_targets(); } + when ( 'add' ) { show_edit_form(); } + when ( 'edit' ) { show_edit_form(); } + when ( 'save' ) { save_target(); } + when ( 'delete' ) { delete_target(); } +} + +output_html_with_http_headers $input, $cookie, $template->output; + +sub show_external_targets { + $template->{VARS}->{saved_id} = $input->param( 'saved_id' ); + $template->{VARS}->{deleted_name} = $input->param( 'deleted_name' ); + $template->{VARS}->{targets} = $dbh->selectall_arrayref( q{ + SELECT * + FROM external_targets + }, { Slice => {} } ); +} + +sub show_edit_form { + $template->{VARS}->{branches} = GetBranchesLoop( undef, 0 ); + $template->{VARS}->{syntaxes} = [ 'MARC21', 'UNIMARC', 'NORMARC' ]; + $template->{VARS}->{encodings} = { 'utf8' => 'UTF-8', 'marc8' => 'MARC-8' }; + + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $template->{VARS}->{target} = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + my $available_branches = $dbh->selectall_hashref( q{ SELECT * FROM external_target_restrictions WHERE target_id = ? }, 'branchcode', {}, $target_id ); + + foreach my $branch ( @{ $template->{VARS}->{branches} } ) { + $branch->{selected} = 1 if ( $available_branches->{$branch->{branchcode}} ); + } + } +} + +sub save_target { + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $dbh->do( q{ + UPDATE external_targets + SET name = ?, host = ?, port = ?, db = ?, userid = ?, password = ?, syntax = ?, encoding = ? + WHERE target_id = ? + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding target_id ) ); + } else { + $dbh->do( q{ + INSERT + INTO external_targets(name, host, port, db, userid, password, syntax, encoding) + VALUES(?, ?, ?, ?, ?, ?, ?, ?) + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding ) ); + $target_id = $dbh->last_insert_id( undef, undef, undef, undef ); + } + + $dbh->do( q{ + DELETE + FROM external_target_restrictions + WHERE target_id = ? + }, {}, $target_id ); + + foreach my $branchcode ( $input->param( 'branch' ) ) { + $dbh->do( q{ + INSERT + INTO external_target_restrictions(branchcode, target_id) + VALUES(?, ?) + }, {}, $branchcode, $target_id ); + } + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?saved_id=' . $target_id ); + exit; +} + +sub delete_target { + my ($target_id, $target); + + return unless ( $target_id = $input->param( 'target_id' ) and $target = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ) ); + + $dbh->do( q{ DELETE FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?deleted_name=' . uri_escape( $target->{'name'} ) ); +} --- a/etc/koha-conf.xml +++ a/etc/koha-conf.xml @@ -19,19 +19,6 @@ tcp:@:__ZEBRA_SRU_BIBLIOS_PORT__ --> - -__PAZPAR2_TOGGLE_XML_PRE__ -tcp:@:__MERGE_SERVER_PORT__ - - __ZEBRA_DATA_DIR__/biblios - __ZEBRA_CONF_DIR__/__ZEBRA_BIB_CFG__ - __ZEBRA_CONF_DIR__/pqf.properties - -__PAZPAR2_TOGGLE_XML_POST__ - __ZEBRA_DATA_DIR__/biblios --- a/etc/koha-httpd.conf +++ a/etc/koha-httpd.conf @@ -32,7 +32,7 @@ # Secure internal stuff - + Order deny,allow Deny from all @@ -113,6 +113,17 @@ RewriteRule ^/isbn/([^\/]*)/?$ /search?q=isbn:$1 [PT] RewriteRule ^/issn/([^\/]*)/?$ /search?q=issn:$1 [PT] + + __PAZPAR2_TOGGLE_HTTPD_PRE__ + + AddDefaultCharset off + Order deny,allow + Allow from all + + + ProxyRequests off + ProxyPass /pazpar2/search.pz2 http://__PAZPAR2_HOST__:__PAZPAR2_PORT__/search.pz2 + __PAZPAR2_TOGGLE_HTTPD_POST__ ## Intranet @@ -149,7 +160,7 @@ # Secure internal stuff - + Order deny,allow Deny from all --- a/etc/pazpar2/generic-settings.xml +++ a/etc/pazpar2/generic-settings.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + --- a/etc/pazpar2/pazpar2.xml +++ a/etc/pazpar2/pazpar2.xml @@ -4,7 +4,7 @@ - + --- a/etc/pazpar2/unimarc-work-groups.xsl +++ a/etc/pazpar2/unimarc-work-groups.xsl @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -257,6 +257,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('OpacRenewalAllowed','0',NULL,'If ON, users can renew their issues directly from their OPAC account','YesNo'), ('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|null','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'), ('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'), +('OPACSearchExternalTargets','0',NULL,'Whether to search external targets in the OPAC','YesNo'), ('OPACSearchForTitleIn','
  • Other Libraries (WorldCat)
  • \n
  • Other Databases (Google Scholar)
  • \n
  • Online Stores (Bookfinder.com)
  • \n
  • Open Library (openlibrary.org)
  • ','70|10','Enter the HTML that will appear in the \'Search for this title in\' box on the detail page in the OPAC. Enter {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the URL. Leave blank to disable \'More Searches\' menu.','Textarea'), ('OpacSeparateHoldings','0',NULL,'Separate current branch holdings from other holdings (OPAC)','YesNo'), ('OpacSeparateHoldingsBranch','homebranch','homebranch|holdingbranch','Branch used to separate holdings (OPAC)','Choice'), --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -7953,6 +7953,39 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.13.00.XXX"; +if(CheckVersion($DBversion)) { + $dbh->do( +"INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACSearchExternalTargets','0','Whether to search external targets in the OPAC','','YesNo')" + ); + $dbh->do( q{ +CREATE TABLE `external_targets` ( + `target_id` int(11) NOT NULL AUTO_INCREMENT, + `host` varchar(128) NOT NULL, + `port` int(11) NOT NULL, + `db` varchar(64) NOT NULL, + `userid` varchar(64) DEFAULT '', + `password` varchar(64) DEFAULT '', + `name` varchar(64) NOT NULL, + `syntax` varchar(64) NOT NULL, + `encoding` varchar(16) DEFAULT 'MARC-8', + PRIMARY KEY (`target_id`) +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 + } ); + $dbh->do( q{ +CREATE TABLE `external_target_restrictions` ( + `branchcode` varchar(10) NOT NULL, + `target_id` int(11) NOT NULL, + KEY `branchcode` (`branchcode`), + KEY `target_id` (`target_id`), + CONSTRAINT `external_target_restrictions_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE, + CONSTRAINT `external_target_restrictions_ibfk_2` FOREIGN KEY (`target_id`) REFERENCES `external_targets` (`target_id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 + } ); + print "Upgrade to $DBversion done (Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -270,6 +270,16 @@ tr.even td, tr.even.highlight td { border-right : 1px solid #BCBCBC; } +tr.highlight td { + background-color : #F6F6F6; + border-color : #BCBCBC; +} + +tr.highlight th[scope=row] { + background-color : #DDDDDD; + border-color : #BCBCBC; +} + td.od { color : #cc0000; font-weight : bold; @@ -287,6 +297,10 @@ tr.odd.onissue td { background-color: #FFFFE1; } +tr.updated td { + background-color: #FFFFBB; +} + tfoot td { background-color : #f3f3f3; font-weight : bold; --- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc @@ -46,6 +46,7 @@
  • Classification sources
  • Record matching rules
  • OAI sets configuration
  • +
  • External search targets
  • Acquisition parameters
    --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -84,6 +84,8 @@
    Search engine configuration
    Manage indexes, facets, and their mappings to MARC fields and subfields.
    [% END %] +
    External search targets
    +
    Define external search targets that can be searched from the OPAC.

    Acquisition parameters

    --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt @@ -0,0 +1,180 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% IF op == 'show' %] +Koha › Administration › External targets +[% ELSIF op == 'add' %] +Koha › Administration › External targets › Create an external target +[% ELSIF op == 'edit' %] +Koha › Administration › External targets › Editing '[% target.name %]' +[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'datatables-strings.inc' %] + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + +[% IF op == 'show' %] + + + +[% ELSIF op == 'add' %] + + + +[% ELSIF op == 'edit' %] + + + +[% END %] + +
    +
    + +
    + +[% IF op == 'show' %] + +[% IF deleted_name %] +
    +

    Deleted target '[% deleted_name %]'

    +
    +[% END %] + + + +

    These Z39.50 targets are searched in the OPAC using the "external targets" feature. Note that Pazpar2 must be installed and configured for this to work.

    + +[% IF targets.size %] + + + + [% FOREACH target = targets %] + + + + + + + + + + [% END %] + +
    NameConnectionLoginSyntaxEncoding  
    [% target.name %][% target.host %]:[% target.port %]/[% target.db %][% IF target.userid %][% target.userid %] / [% IF target.password %]********[% ELSE %]none[% END %][% ELSE %]none[% END %][% target.syntax %] + [% IF target.encoding == 'marc8' %] + MARC-8 + [% ELSIF target.encoding == 'utf8' %] + UTF-8 + [% END %] + EditDelete
    +[% ELSE %] +

    No external targets have been defined yet.

    +[% END %] + +[% ELSIF op == 'add' || op == 'edit' %] + +
    + [% IF op == 'add' %] +

    Create an external target

    + [% ELSIF op == 'edit' %] +

    Editing '[% target.name %]'

    + [% END %] + + + + +
    +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    7. + + +
    8. +
    9. + + +
    10. +
    11. + +
      + Not available to patrons from: +

      Only targets with no restrictions will be shown to anonymous (not logged in) users.

      +
        + [% FOREACH branch = branches %] +
      1. + + [% IF branch.selected %] + + [% ELSE %] + + [% END %] +
      2. + [% END %] +
      +
      +
    12. +
    +
    + +
    +
    + +[% END %] + +
    +
    +[% INCLUDE 'admin-menu.inc' %] +
    + +
    +[% INCLUDE 'intranet-bottom.inc' %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -430,6 +430,13 @@ OPAC: yes: Allow no: Do not allow - users to add a note when placing a hold. + - + - pref: OPACSearchExternalTargets + default: 0 + choices: + yes: Search + no: "Don't search" + - external targets from the OPAC. Policy: - --- a/koha-tmpl/opac-tmpl/bootstrap/css/opac.css +++ a/koha-tmpl/opac-tmpl/bootstrap/css/opac.css @@ -2142,7 +2142,7 @@ td img { margin: 0; padding: 0; } -#overdrive-results { +#overdrive-results, #pazpar2-results { font-weight: bold; padding-left: 1em; } @@ -2278,6 +2278,25 @@ a.reviewlink:visited { -moz-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); } +.sourcecol { + vertical-align: top; + width: 100px; +} +.notesrow label { + font-weight: bold; +} +.notesrow span { + display: block; +} +.notesrow textarea { + width: 100%; +} +#modal-overlay { + background-color: white; + border-radius: 5px; + max-width: 75%; + padding: 15px; +} @media only screen and (min-width: 0px) and (max-width: 304px) { /* Screens bewteen 0 and 304 pixels wide */ #oh:after { --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt @@ -552,7 +552,12 @@ [% IF ( OverDriveEnabled ) %][% END %] [% IF ( OpacHighlightedWords ) %] -[% END %] + +[% END %] + + + + + + + +
    + +
    + [% INCLUDE 'masthead.inc' %] + +

    External search for '[% q | html %]'

    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + +
    +
    + +

    Refine your search

    + +
      +
    • + Targets +
        + [% FOREACH target = external_search_targets %] +
      • + +
      • + [% END %] +
      +
    • +
    +
    +
    +
    + +
    + + +[% INCLUDE 'opac-bottom.inc' %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -16,7 +16,11 @@ [% END %] - +[% IF ( OverDriveEnabled ) %][% END %] +[% IF ( Koha.Preference('OPACSearchExternalTargets') ) %] + + +[% END %] [% IF ( OpacHighlightedWords ) %] [% END %]