From a65088f942dd5275e935bac5bde6d08d80cea686 Mon Sep 17 00:00:00 2001 From: David Bourgault Date: Tue, 26 Sep 2017 10:17:06 -0400 Subject: [PATCH] Bug 17385 - Add custom export XSLT Patch was corrected and rebased after QA feedback. Previous patches where combined into this one. - Empty READMEs have been deleted - Whitespaces changes to unrelated code have been undone * CustomXSLTExportList now uses LibXML to figure out the title and output * The custom export XSLT's title should be an attribute to the root node, otherwise it will default to filename - Duplicate $xslFile param was removed from XSLTParse4Display * Improvment to code structure in XSLTParse4Display * Some fixes to calls to AddBiblio() Test case: - Apply patch - Visit an item's detail page in the OPAC or the staff interface - Click save and you found Simple Export. - Click Simple Export and you have a file.html, it contain informations returned by the xslt file. - It work correctly in basket and lists. The patch comes with sample XSLT files for Intranet the xsl file is : koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl for opac the xsl file is : koha-tmpl/opac-tmpl/bootstrap/en/xslt/biblioexport/MARC21_simple_export.xsl --- C4/XSLT.pm | 65 +++++++++++++++++++++- basket/basket.pl | 2 + basket/downloadcart.pl | 7 ++- catalogue/detail.pl | 3 + catalogue/export.pl | 15 +++++ .../intranet-tmpl/prog/en/includes/cat-toolbar.inc | 3 + .../prog/en/includes/virtualshelves-toolbar.inc | 3 + .../intranet-tmpl/prog/en/modules/basket/basket.tt | 3 + .../prog/en/modules/catalogue/detail.tt | 5 +- .../en/modules/virtualshelves/downloadshelf.tt | 3 + .../en/xslt/biblioexport/MARC21_simple_export.xsl | 62 +++++++++++++++++++++ .../bootstrap/en/includes/opac-detail-sidebar.inc | 3 + .../bootstrap/en/modules/opac-downloadcart.tt | 3 + .../bootstrap/en/modules/opac-downloadshelf.tt | 3 + .../en/xslt/biblioexport/MARC21_simple_export.xsl | 62 +++++++++++++++++++++ opac/opac-detail.pl | 3 + opac/opac-downloadcart.pl | 6 ++ opac/opac-export.pl | 10 ++++ virtualshelves/downloadshelf.pl | 6 +- virtualshelves/shelves.pl | 1 + 20 files changed, 263 insertions(+), 5 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/xslt/biblioexport/MARC21_simple_export.xsl diff --git a/C4/XSLT.pm b/C4/XSLT.pm index bf2647a..e6c102b 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -34,6 +34,8 @@ use Koha::ItemTypes; use Koha::XSLT_Handler; use Koha::Libraries; +use XML::LibXML; + use Encode; use vars qw(@ISA @EXPORT); @@ -48,6 +50,7 @@ BEGIN { @ISA = qw(Exporter); @EXPORT = qw( &XSLTParse4Display + &CustomXSLTExportList ); $engine=Koha::XSLT_Handler->new( { do_not_return_source => 1 } ); } @@ -188,13 +191,27 @@ sub get_xslt_sysprefs { } sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items, $sysxml, $xslfilename, $lang ) = @_; + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items, $sysxml, $xslfilename, $lang , $opac) = @_; $sysxml ||= C4::Context->preference($xslsyspref); $xslfilename ||= C4::Context->preference($xslsyspref); $lang ||= C4::Languages::getlanguage(); - if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { + if ($xslsyspref eq "XSLTCustomExport") { + my $dir; + if ($opac) { + $dir = C4::Context->config('opachtdocs') . + '/' . C4::Context->preference("opacthemes") . + '/' . C4::Languages::getlanguage() . + '/xslt/biblioexport'; + } else { + $dir = C4::Context->config('intrahtdocs') . + '/' . C4::Context->preference("template") . + '/' . C4::Languages::getlanguage() . + '/xslt/biblioexport'; + } + $xslfilename = $dir . "/" . $xslfilename; + } elsif( $xslfilename =~ /^\s*"?default"?\s*$/i ) { my $htdocs; my $theme; my $xslfile; @@ -352,6 +369,50 @@ sub engine { return $engine; } +=head2 CustomXSLTExportList + + Returns list of file for custom xslt conversion + +=cut + +sub CustomXSLTExportList { + my $opac = shift; # opac (1) vs intranet (0) + my @tabFiles; + + my $dir = C4::Context->config( $opac ? 'opachtdocs' : 'intrahtdocs') . + '/' . C4::Context->preference( $opac ? "opacthemes" : "template") . + '/' . C4::Languages::getlanguage() . + '/xslt/biblioexport'; + my @files = <$dir/*.xsl>; + foreach my $file (@files) { + if ( -f "$file" ) { + (my $text = $file) =~ s/.*\///g; + + ## Get title of the option + my $dom = XML::LibXML->load_xml( location => $file ); + my $node = $dom->documentElement(); + my $title = $node->{"title"}; + ($title = $text) =~ s/\.xsl// unless defined $title; + + # Get output format + # There should only be one xsl:output node, so taking the first one only is OK + $node = @{$node->findnodes("xsl:output")}[0]; + my $outputformat = $node->{"method"} if $node; + $outputformat = "txt" if ($outputformat eq "" || $outputformat eq "text"); + + my %row = ( + value => $text, + filename => $title, + format => $outputformat, + ); + + push @tabFiles, \%row; + } + } + return \@tabFiles; +} + + 1; __END__ diff --git a/basket/basket.pl b/basket/basket.pl index 76edc34..4553927 100755 --- a/basket/basket.pl +++ b/basket/basket.pl @@ -23,6 +23,7 @@ use C4::Biblio; use C4::Items; use C4::Auth; use C4::Output; +use C4::XSLT; use Koha::AuthorisedValues; use Koha::CsvProfiles; @@ -126,6 +127,7 @@ my $resultsarray = \@results; $template->param( BIBLIO_RESULTS => $resultsarray, csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ], + xsl_exports => CustomXSLTExportList(), bib_list => $bib_list, ); diff --git a/basket/downloadcart.pl b/basket/downloadcart.pl index 4653449..1e445ee 100755 --- a/basket/downloadcart.pl +++ b/basket/downloadcart.pl @@ -28,7 +28,7 @@ use C4::Items; use C4::Output; use C4::Record; use C4::Ris; - +use C4::XSLT; use Koha::CsvProfiles; use utf8; @@ -79,11 +79,15 @@ if ($bib_list && $format) { elsif ($format eq 'bibtex') { $output .= marc2bibtex($record, $biblio); } + elsif ($format =~ /^xsl\.(.*)$/) { + $output .= XSLTParse4Display($biblio, $record, 'XSLTCustomExport', 1, undef, , '', $1, ''); + } } } # If it was a CSV export we change the format after the export so the file extension is fine $format = "csv" if ($format =~ m/^\d+$/); + $format = "html" if ($format =~ /^xsl\./); print $query->header( -type => 'application/octet-stream', @@ -93,6 +97,7 @@ if ($bib_list && $format) { } else { $template->param(csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ]); + $template->param(xsl_exports => CustomXSLTExportList()); $template->param(bib_list => $bib_list); output_html_with_http_headers $query, $cookie, $template->output; } diff --git a/catalogue/detail.pl b/catalogue/detail.pl index 1e18a1d..cf42928 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -61,6 +61,9 @@ my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( } ); +##### ADD CUSTOM XSLT +$template->param(filesOptions => CustomXSLTExportList(0)); + my $biblionumber = $query->param('biblionumber'); $biblionumber = HTML::Entities::encode($biblionumber); my $record = GetMarcBiblio({ biblionumber => $biblionumber }); diff --git a/catalogue/export.pl b/catalogue/export.pl index c10686c..27831e2 100755 --- a/catalogue/export.pl +++ b/catalogue/export.pl @@ -8,6 +8,7 @@ use C4::Output; use C4::Biblio; use CGI qw ( -utf8 ); use C4::Ris; +use C4::XSLT; @@ -79,4 +80,18 @@ if ($op eq "export") { -attachment=>"bib-$biblionumber.$format"); print $marc; } +}elsif ($op eq "exportxsl"){ + my $biblionumber = $query->param("bib"); + if ($biblionumber){ + my $xslFile = $query->param("file"); + my $marc = GetMarcBiblio( { biblionumber => $biblionumber, embed_items => 1 } ); + my $format=$query->param("format")||'txt'; + my @hiddenitems; + + $marc = XSLTParse4Display($biblionumber, $marc, 'XSLTCustomExport', 1, \@hiddenitems, '', $xslFile,''); + print $query->header( + -type => 'application/octet-stream', + -attachment=>"bib-$biblionumber.$format"); + print $marc; + } } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc index 5833978..78a31fc 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc @@ -95,6 +95,9 @@ CAN_user_serials_create_subscription ) %]
  • MARC (Unicode/UTF-8, Standard)
  • MODS (XML)
  • RIS
  • + [% FOREACH filesOption IN filesOptions %] +
  • [% filesOption.filename %]
  • + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/virtualshelves-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/virtualshelves-toolbar.inc index 0f034dc..53e4304 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/virtualshelves-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/virtualshelves-toolbar.inc @@ -49,6 +49,9 @@ [% FOREACH csv_profile IN csv_profiles %]
  • CSV - [% csv_profile.profile %]
  • [% END %] + [% FOREACH xsl_export IN xsl_exports %] +
  • XSL - [% xsl_export.filename %]
  • + [% END %]
    Send list
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt index 30f276c..f1fc328 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt @@ -61,6 +61,9 @@ [% FOREACH csv_profile IN csv_profiles %]
  • CSV - [% csv_profile.profile %]
  • [% END %] + [% FOREACH xsl_export IN xsl_exports %] +
  • XSL - [% xsl_export.filename %]
  • + [% END %] Print diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index be5932b..905916d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -811,7 +811,10 @@ - + + [% FOREACH filesOption IN filesOptions %] + + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt index 96fa994..201df77 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt @@ -36,6 +36,9 @@ [% FOREACH csv_profile IN csv_profiles %] [% END %] + [% FOREACH xsl_export IN xsl_exports %] + + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl b/koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl new file mode 100644 index 0000000..5e518d3 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/xslt/biblioexport/MARC21_simple_export.xsl @@ -0,0 +1,62 @@ + + + + + + + + + +

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

    +
    + +
    diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc index 5e96b0f..8e350da 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc @@ -67,6 +67,9 @@ [% END %] [% END %] + [% FOREACH filesOption IN filesOptions %] +
  • [% filesOption.filename %]
  • + [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadcart.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadcart.tt index f7eebd8..e565b35 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadcart.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadcart.tt @@ -20,6 +20,9 @@ [% FOREACH csv_profile IN csv_profiles %] [% END %] + [% FOREACH xsl_export IN xsl_exports %] + + [% END %]
    diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadshelf.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadshelf.tt index 7824f31..290fd34 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadshelf.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-downloadshelf.tt @@ -59,6 +59,9 @@ [% FOREACH csv_profile IN csv_profiles %] [% END %] + [% FOREACH xsl_export IN xsl_exports %] + + [% END %] Required
    diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/biblioexport/MARC21_simple_export.xsl b/koha-tmpl/opac-tmpl/bootstrap/en/xslt/biblioexport/MARC21_simple_export.xsl new file mode 100644 index 0000000..5e518d3 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/en/xslt/biblioexport/MARC21_simple_export.xsl @@ -0,0 +1,62 @@ + + + + + + + + + +

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

    +
    + +
    diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 8252e50..87c3082 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -76,6 +76,9 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); +##### ADD CUSTOM XSLT +$template->param(filesOptions => CustomXSLTExportList(1)); + my $biblionumber = $query->param('biblionumber') || $query->param('bib') || 0; $biblionumber = int($biblionumber); diff --git a/opac/opac-downloadcart.pl b/opac/opac-downloadcart.pl index 76fa095..3b69cc6 100755 --- a/opac/opac-downloadcart.pl +++ b/opac/opac-downloadcart.pl @@ -28,6 +28,7 @@ use C4::Items; use C4::Output; use C4::Record; use C4::Ris; +use C4::XSLT; use Koha::CsvProfiles; use Koha::RecordProcessor; @@ -99,11 +100,15 @@ if ($bib_list && $format) { $extension = "txt"; $type = "text/plain"; } + elsif ($format =~ /^xsl\.(.*)$/) { + $output .= XSLTParse4Display($biblio, $record, 'XSLTCustomExport', 1, undef, undef, $1, '', 1); + } } } # If it was a CSV export we change the format after the export so the file extension is fine $format = "csv" if ($format =~ m/^\d+$/); + $format = "html" if ($format =~ /^xsl\./); print $query->header( -type => ($type) ? $type : 'application/octet-stream', @@ -114,6 +119,7 @@ if ($bib_list && $format) { } else { $template->param(csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ]); + $template->param(xsl_exports => CustomXSLTExportList()); $template->param(bib_list => $bib_list); output_html_with_http_headers $query, $cookie, $template->output; } diff --git a/opac/opac-export.pl b/opac/opac-export.pl index 6023d78..b2504de 100755 --- a/opac/opac-export.pl +++ b/opac/opac-export.pl @@ -26,6 +26,7 @@ use C4::Biblio; use CGI qw ( -utf8 ); use C4::Auth; use C4::Ris; +use C4::XSLT; use Koha::RecordProcessor; my $query = CGI->new; @@ -106,6 +107,15 @@ elsif ( $format =~ /isbd/ ) { }); $format = 'isbd'; } +elsif ($format =~ /html/ ) { + if ($biblionumber){ + my $xslFile = $query->param("file"); + $marc = C4::Biblio::GetMarcBiblio({biblionumber => $biblionumber}); + my @hiddenitems; + + $marc = XSLTParse4Display($biblionumber, $marc, 'XSLTCustomExport', 1, \@hiddenitems, undef, $xslFile, undef, 1); + } +} else { $error= "Format $format is not supported."; } diff --git a/virtualshelves/downloadshelf.pl b/virtualshelves/downloadshelf.pl index b8b37fb..80327c8 100755 --- a/virtualshelves/downloadshelf.pl +++ b/virtualshelves/downloadshelf.pl @@ -28,6 +28,7 @@ use C4::Items; use C4::Output; use C4::Record; use C4::Ris; +use C4::XSLT; use Koha::CsvProfiles; use Koha::Virtualshelves; @@ -83,12 +84,15 @@ if ($shelfid && $format) { elsif ($format eq 'bibtex') { $output .= marc2bibtex($record, $biblionumber); } + elsif ($format =~ /^xsl\.(.*)$/){ + $output .= XSLTParse4Display($biblionumber, $record, 'XSLTCustomExport', 1, undef, ,'',$1,''); + } } } # If it was a CSV export we change the format after the export so the file extension is fine $format = "csv" if ($format =~ m/^\d+$/); - + $format = "html" if ($format =~ /^xsl\./); print $query->header( -type => 'application/octet-stream', -'Content-Transfer-Encoding' => 'binary', diff --git a/virtualshelves/shelves.pl b/virtualshelves/shelves.pl index d3aea7e..0740773 100755 --- a/virtualshelves/shelves.pl +++ b/virtualshelves/shelves.pl @@ -327,6 +327,7 @@ $template->param( category => $category, print => scalar $query->param('print') || 0, csv_profiles => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ], + xsl_exports => CustomXSLTExportList() ); output_html_with_http_headers $query, $cookie, $template->output; -- 2.7.4