@@ -, +, @@
---
Koha/Template/Plugin/Combine.pm | 141 +++++++++++++++++++
.../intranet-tmpl/prog/en/css/staff-global.css | 3 +-
.../prog/en/includes/doc-head-close.inc | 50 ++++---
koha-tmpl/opac-tmpl/prog/en/css/opac.css | 3 -
.../opac-tmpl/prog/en/includes/doc-head-close.inc | 143 +++++++++++++-------
koha-tmpl/opac-tmpl/prog/en/js/script.js | 1 -
6 files changed, 261 insertions(+), 80 deletions(-)
create mode 100644 Koha/Template/Plugin/Combine.pm
--- a/Koha/Template/Plugin/Combine.pm
+++ a/Koha/Template/Plugin/Combine.pm
@@ -0,0 +1,141 @@
+package Koha::Template::Plugin::Combine;
+use Template::Plugin;
+use base qw( Template::Plugin );
+use warnings;
+use strict;
+
+# PLACK_DEBUG=1 always re-create files but report correct hit/miss ration
+
+use File::Slurp;
+use Digest::MD5;
+use Data::Dump qw(dump);
+
+use CSS::Minifier::XS;
+use JavaScript::Minifier::XS;
+
+sub new {
+ my ($class, $context, @params) = @_;
+#warn "## context ",dump( $context );
+ bless {
+ _CONTEXT => $context,
+ js => [], # same as extension!
+ css => [],
+ inline => 1,
+ minify => 1,
+ }, $class;
+}
+
+sub _html_params {
+ my $params = shift;
+ return join(' ', map { $_ . '="' . $params->{$_} . '"' } keys %$params );
+}
+
+sub javascript {
+ my ( $self, $params ) = @_;
+ warn "## combine.javascript ", dump( $params );
+ $params->{type} ||= 'text/javascript';
+ push @{ $self->{js} }, $params;
+ my $html = _html_params( $params );
+ if ( $self->{inline} ) {
+ return "\n";
+ } elsif ( my $cdata = $params->{cdata} ) {
+ return qq|\n|;
+ } else {
+ return "\n";
+ }
+}
+
+sub css {
+ my ( $self, $params ) = @_;
+ warn "## combine.css ",dump( $params );
+ $params->{rel} ||= 'stylesheet';
+ $params->{type} ||= 'text/css';
+ die "no href in ",dump($params) unless exists $params->{href};
+ my $html = _html_params( $params );
+
+ if ( exists $params->{media} ) { # FIXME not combined!
+ push @{ $self->{css_media} }, "";
+ return "";
+ }
+
+ push @{ $self->{css} }, $params;
+ if ( $self->{inline}) {
+ return "\n";
+ } else {
+ return "\n";
+ }
+}
+
+sub combined_files {
+ my ( $self, $what, $attr, $params ) = @_;
+warn "## combined_files $what $attr ",dump($params);
+ my $key = join(' ', map { $_->{$attr} || $_->{cdata} } @{ $self->{$what} } );
+ $key = Digest::MD5::md5_hex( $key ); # shorten filenames
+ warn "# $what $attr key = $key\n";
+ my $htdocs = C4::Context->config('intrahtdocs');
+ $htdocs =~ s{/intranet-tmpl/?$}{}; # FIXME DocumentRoot even for OPAC
+
+ my ( $path, $url );
+ if ( my $prefix = $params->{prefix} ) {
+ $path = "$htdocs/$prefix/combined/$key.$what";
+ $url = "$prefix/combined/$key.$what";
+ } else {
+ $path = "$htdocs/intranet-tmpl/combined/$key.$what";
+ $url = "/intranet-tmpl/combined/$key.$what";
+ }
+ $path =~ s{//+}{/}; # plack is picky about paths
+ if ( -e $path ) {
+ $Koha::Persistant::stats->{combine_files}->[0]++; # hit
+ return $url if ! $ENV{PLACK_DEBUG}; # FIXME no caching with debug
+ }
+ $Koha::Persistant::stats->{combine_files}->[1]++ if ! $ENV{PLACK_DEBUG}; # miss
+
+ my $mix;
+ foreach my $include ( @{ $self->{$what} } ) {
+ if ( my $path = $include->{$attr} ) {
+ warn "combine_files $what $attr - $path";
+ my $chunk = read_file("$htdocs/$path");
+ die "$htdocs/$path found \@import" if $what eq 'css' && $chunk =~ m'@import';
+ $mix .= "\n/* BEGIN $path */\n$chunk\n/* END $path */\n";
+ } elsif ( my $cdata = $include->{cdata} ) {
+ warn "combine_files CDATA $cdata";
+ $mix .= "\n/* BEGIN CDATA */\n$cdata\n/* END CDATA */\n";
+ }
+ }
+ my $combined_size = length($mix);
+ if ( $self->{minify} ) {
+ if ( $what eq 'js' ) {
+ $mix = JavaScript::Minifier::XS::minify( $mix );
+ } elsif ( $what eq 'css' ) {
+ $mix = CSS::Minifier::XS::minify( $mix );
+ } else {
+ die "can't minify $what";
+ }
+ my $size = length($mix);
+ warn sprintf "minify %s %d -> %d %.2f%%\n", $what, $combined_size, $size, $size * 100 / $combined_size;
+ }
+ write_file $path, $mix;
+ warn "## $path ", -s $path, "/$combined_size bytes\n";
+ return $url;
+}
+
+sub html {
+ my ( $self, $params ) = @_;
+
+ if ( $self->{inline} ) {
+ warn "## css ",dump( $self->{css} );
+ warn "## javascript ",dump( $self->{js} );
+ my $mix;
+ my $js = $self->combined_files( 'js' => 'src', $params );
+ my $css = $self->combined_files( 'css' => 'href', $params );
+ return qq{
+
+
+
+ };
+ } else {
+ return "";
+ }
+}
+
+1;
--- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
+++ a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
@@ -1,5 +1,4 @@
-@import url("../lib/yui/reset-fonts-grids.css");
-@import url("../lib/yui/skin.css");
+/* import moved to koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc */
input:focus, textarea:focus {
border-color:#538200;
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
@@ -1,44 +1,47 @@
+[% USE combine = Combine %]
-
-
-
+[% combine.css( href => themelang _ "/lib/jquery/jquery-ui.css" ) %]
+[% combine.css( href => themelang _ "/lib/jquery/plugins/ui.tabs.css" ) %]
+[% combine.css( media => "print" href => themelang _ "/css/print.css" ) %]
[% IF ( intranetstylesheet ) %]
-
+ [% combine.css( href => intranetstylesheet ) %]
[% ELSE %]
-
+ [% combine.css( href => yuipath _ "/reset-fonts-grids.css" ) %]
+ [% combine.css( href => yuipath _ "/skin.css" ) %]
+ [% combine.css( href => themelang _ "/css/staff-global.css" ) %]
[% END %]
[% IF ( IntranetUserCSS ) %][% END %]
-
-
-
-
-
-
+[% combine.javascript( src => themelang _ "/lib/jquery/jquery.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/ui.tabs.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/jquery-ui.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/jquery.hotkeys.min.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/jquery.cookie.min.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/jquery.highlight-3.js" ) %]
[% IF ( login ) %]
-
+ [% combine.css( href => themelang _ "/css/login.css" ) %]
[% END %]
[% IF ( wizard ) %]
-
+ [% combine.css( href => themelang _ "/css/wizard.css" ) %]
[% END %]
[% IF ( intranetcolorstylesheet ) %]
-
+ [% combine.css( href => themelang _ "/css/" _ intranetcolorstylesheet ) %]
[% END %]
-
-
+[% combine.javascript( src => yuipath _ "/utilities/utilities.js" ) %]
+[% combine.javascript( src => yuipath _ "/datasource/datasource-min.js" ) %]
[% IF ( CircAutocompl ) %]
-
+ [% combine.javascript( src => yuipath _ "/autocomplete/autocomplete-min.js" ) %]
[% END %]
-
-
-
+[% combine.javascript( src => yuipath _ "/button/button-min.js" ) %]
+[% combine.javascript( src => yuipath _ "/container/container_core-min.js" ) %]
+[% combine.javascript( src => yuipath _ "/menu/menu-min.js" ) %]
-
+[% combine.javascript( src => themelang _ "/js/staff-global.js" ) %]
[% IF ( intranetuserjs ) %]
[% IF ( virtualshelves || intranetbookbag ) %]
-
+ [% combine.javascript( src => themelang _ "/js/basket.js" ) %]
[% END %]
[% IF LocalCoverImages %]
-
+[% combine.javascript( src => themelang _ "/js/localcovers.js" ) %]
[% END %]
+[% combine.html( prefix => themelang ) %]
--- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css
+++ a/koha-tmpl/opac-tmpl/prog/en/css/opac.css
@@ -1,6 +1,3 @@
-@import url("../lib/yui/reset-fonts-grids.css");
-@import url("../lib/yui/skin.css");
-
a {
font-weight : bold;
}
--- a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc
+++ a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc
@@ -2,50 +2,62 @@
-[% IF ( opacstylesheet ) %][% ELSE %]
-[% IF ( opaclayoutstylesheet ) %][% ELSE %][% END %][% END %]
+[% USE combine = Combine %]
+[% IF ( opacstylesheet ) %]
+ [% combine.css( href => opacstylesheet ) %]
+[% ELSE %]
+ [% IF ( opaclayoutstylesheet ) %]
+ [% combine.css( href => themelang _ "/css/" _ opaclayoutstylesheet ) %]
+ [% ELSE %]
+ [% combine.css( href => themelang _ "/css/opac.css" ) %]
+ [% END %]
+[% END %]
[% IF ( opaccolorstylesheet ) %]
-
+ [% combine.css( href => themelang _ "/css/" _ opaccolorstylesheet ) %]
[% END %]
[% IF ( opacexternalsheet ) %]
-
+ [% combine.css( href => opacexternalsheet ) %]
[% END %]
[% IF ( opac_css_override ) %]
-
+ [% combine.css( href => therelang _ "/css/" _ opac_css_override ) %]
[% END %]
-
+[% combine.css( href => themelang _ "/lib/jquery/plugins/ui.tabs.css" ) %]
[% IF ( OPACUserCSS ) %][% END %]
-
-
-
-
-
-
-
+[% combine.css( href => yuipath _ "/reset-fonts-grids.css" ) %]
+[% combine.css( href => yuipath _ "/skin.css" ) %]
+[% combine.javascript( src => yuipath _ "/utilities/utilities.js" ) %]
+[% combine.javascript( src => yuipath _ "/container/container-min.js" ) %]
+[% combine.javascript( src => yuipath _ "/menu/menu-min.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/jquery.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/ui.tabs.js" ) %]
+[% combine.javascript( src => themelang _ "/lib/jquery/plugins/jquery.hoverIntent.minified.js" ) %]
+[% combine.javascript( src => themelang _ "/js/script.js" ) %]
+
[% IF ( OPACAmazonCoverImages ) %]
-
-
+[% combine.javascript( cdata => "var NO_AMAZON_IMAGE = _(\"No cover image available\");" ) %]
+[% combine.javascript( src => themelang _ "/js/amazonimages.js" ) %]
[% END %]
[% IF ( SyndeticsCoverImages ) %]
-
- [% END %]
+[% combine.javascript( cdata => "var NO_AMAZON_IMAGE = _(\"No cover image available\");" ) %]
+[% combine.javascript( src => themelang _ "/js/amazonimages.js" ) %]
+[% END %]
-[% IF ( opacbookbag ) %]
+[% IF ( opacbookbag ) %]
+ [% combine.javascript( src => themelang _ "/js/basket.js" ) %]
+[% ELSIF ( virtualshelves ) %]
+ [% combine.javascript( src => themelang _ "/js/basket.js" ) %]
+[% ELSE %]
+ [% combine.javascript( cdata => "var readCookie;" ) %]
+[% END %]
+[% combine.javascript( cdata => "var cdata_test;" ) %]
-[% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %][% END %][% ELSE %][% END %]
+
+[% IF ( opacbookbag ) %]
+[% compose.javascript( src => themelang _ "/js/basket.js" ) %]
+[% ELSIF ( virtualshelves ) %]
+[% compose.javascript( src => themelang _ "/js/basket.js" ) %]
+[% ELSE %]
+
+[% END %]
+
+[% IF ( opacuserlogin ) %]
+ [% IF ( TagsEnabled ) %]
+ [% combine.javascript( src => themelang _ "/js/tags.js" ) %]
+ [% END %]
+[% END %]
+
[% IF ( GoogleJackets ) %]
-
+[% combine.javascript( src => themelang _ "/js/google-jackets.js" ) %]
[% END %]
[% IF OpenLibraryCovers %]
-
+[% combine.javascript( src => themelang _ "/js/openlibrary.js" ) %]
+[% combine.javascript( src => themelang _ "/js/localcovers.js" ) %]
[% END %]
-[% IF ( BakerTaylorEnabled ) %]
+[% IF ( BakerTaylorEnabled ) %]
+[% combine.javascript( src => themelang _ "/js/bakertaylorimages.js" ) %]
[% END %]
+
+[% END %]
+
[% IF ( GoogleIndicTransliteration ) %]
-
-
+
+ [% combine.javascript( src => themelang _ "/js/googleindictransliteration.js" ) %]
[% END %]
-
+[% combine.html( prefix => themelang ) %]
--- a/koha-tmpl/opac-tmpl/prog/en/js/script.js
+++ a/koha-tmpl/opac-tmpl/prog/en/js/script.js
@@ -1,4 +1,3 @@
-function _(s) { return s } // dummy function for gettext
function confirmDelete(message) {
return (confirm(message) ? true : false);
}
--