diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt
index cb1494b8d..d7ffeaac4 100644
--- a/docs/changelog/7.x.x.txt
+++ b/docs/changelog/7.x.x.txt
@@ -14,6 +14,7 @@
- fixed #10182: Matrix 2.0 - Comparison view broken in IE 6 & 7
- Added individual shipping requirements to the Sku.
- added #10145: Global Head Tags in Settings
+ - added packing to templates, snippets, and head tags.
7.7.4
- rfe: Extend DateTime for Week-Nrs (#9151)
diff --git a/docs/upgrades/upgrade_7.7.4-7.7.5.pl b/docs/upgrades/upgrade_7.7.4-7.7.5.pl
index ad92dd222..e79d703ec 100644
--- a/docs/upgrades/upgrade_7.7.4-7.7.5.pl
+++ b/docs/upgrades/upgrade_7.7.4-7.7.5.pl
@@ -43,6 +43,8 @@ correctEventTemplateVariables($session);
addGlobalHeadTags( $session );
addShipsSeparateToSku($session);
+addTemplatePacking( $session );
+
finish($session); # this line required
#----------------------------------------------------------------------------
@@ -189,6 +191,59 @@ EOSQL
print "DONE!\n" unless $quiet;
}
+#----------------------------------------------------------------------------
+# Add the template packer
+# Pre-pack all templates
+sub addTemplatePacking {
+ my $session = shift;
+ print "\tAdding template packing/minifying... " unless $quiet;
+ $session->db->write("ALTER TABLE template ADD templatePacked LONGTEXT");
+ $session->db->write("ALTER TABLE template ADD usePacked INT(1)");
+
+ print "\n\t\tPre-packing all templates, this may take a while..." unless $quiet;
+ my $sth = $session->db->read( "SELECT DISTINCT(assetId) FROM template" );
+ while ( my ($assetId) = $sth->array ) {
+ my $asset = WebGUI::Asset::Template->new( $session, $assetId );
+ next unless $asset;
+ $asset->update({
+ template => $asset->get('template'),
+ usePacked => 1,
+ });
+ }
+
+ print "\n\t\tAdding extra head tags packing..." unless $quiet;
+ $session->db->write("ALTER TABLE assetData ADD extraHeadTagsPacked LONGTEXT");
+ $session->db->write("ALTER TABLE assetData ADD usePackedHeadTags INT(1)");
+
+ print "\n\t\tPre-packing all head tags, this may take a while..." unless $quiet;
+ my $sth = $session->db->read( "SELECT assetId FROM asset" );
+ while ( my ($assetId) = $sth->array ) {
+ my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
+ next unless $asset;
+ $asset->update({
+ extraHeadTags => $asset->get('extraHeadTags'),
+ usePackedHeadTags => 1,
+ });
+ }
+
+ print "\n\t\tAdding snippet packing..." unless $quiet;
+ $session->db->write("ALTER TABLE Snippet ADD snippetPacked LONGTEXT");
+ $session->db->write("ALTER TABLE Snippet ADD usePacked INT(1)");
+
+ print "\n\t\tPre-packing all snippets, this may take a while..." unless $quiet;
+ my $sth = $session->db->read( "SELECT DISTINCT(assetId) FROM Snippet" );
+ while ( my ($assetId) = $sth->array ) {
+ my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
+ next unless $asset;
+ $asset->update({
+ snippet => $asset->get('snippet'),
+ usePacked => 1,
+ });
+ }
+
+ print "\n\t... DONE!\n" unless $quiet;
+}
+
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
#----------------------------------------------------------------------------
diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm
index 05fa1bd6c..177240403 100644
--- a/lib/WebGUI/Asset.pm
+++ b/lib/WebGUI/Asset.pm
@@ -18,6 +18,7 @@ use Carp qw( croak confess );
use Scalar::Util qw( blessed );
use Clone qw(clone);
use JSON;
+use HTML::Packer;
use WebGUI::AssetBranch;
use WebGUI::AssetClipboard;
@@ -446,6 +447,19 @@ sub definition {
fieldType=>'codearea',
defaultValue=>undef,
customDrawMethod => 'drawExtraHeadTags',
+ filter => 'packExtraHeadTags',
+ },
+ extraHeadTagsPacked => {
+ fieldType => 'hidden',
+ defaultValue => undef,
+ },
+ usePackedHeadTags => {
+ tab => "meta",
+ label => $i18n->get('usePackedHeadTags label'),
+ hoverHelp => $i18n->get('usePackedHeadTags description'),
+ uiLevel => 7,
+ fieldType => 'yesNo',
+ defaultValue => 1,
},
isPackage=>{
label=>$i18n->get("make package"),
@@ -1086,7 +1100,10 @@ Returns the extraHeadTags stored in the asset. Called in $self->session->style-
sub getExtraHeadTags {
my $self = shift;
- return $self->get("extraHeadTags");
+ return $self->get('usePackedHeadTags')
+ ? $self->get('extraHeadTagsPacked')
+ : $self->get("extraHeadTags")
+ ;
}
@@ -2000,6 +2017,29 @@ OUTPUT
#-------------------------------------------------------------------
+=head2 packExtraHeadTags ( unpacked )
+
+Pack the extra head tags. Return the unpacked head tags (as per
+filter guidelines).
+
+=cut
+
+sub packExtraHeadTags {
+ my ( $self, $unpacked ) = @_;
+ return $unpacked if !$unpacked;
+ my $packed = $unpacked;
+ HTML::Packer::minify( \$packed, {
+ remove_comments => 1,
+ remove_newlines => 1,
+ do_javascript => "shrink",
+ do_stylesheet => "minify",
+ } );
+ $self->update({ extraHeadTagsPacked => $packed });
+ return $unpacked;
+}
+
+#-------------------------------------------------------------------
+
=head2 prepareView ( )
Executes what is necessary to make the view() method work with content chunking.
diff --git a/lib/WebGUI/Asset/Snippet.pm b/lib/WebGUI/Asset/Snippet.pm
index 6f23e3805..867986de6 100644
--- a/lib/WebGUI/Asset/Snippet.pm
+++ b/lib/WebGUI/Asset/Snippet.pm
@@ -18,6 +18,9 @@ use strict;
use WebGUI::Asset;
use WebGUI::Asset::Template;
use WebGUI::Macro;
+use HTML::Packer;
+use JavaScript::Packer;
+use CSS::Packer;
our @ISA = qw(WebGUI::Asset);
@@ -68,8 +71,19 @@ sub definition {
tab=>"properties",
label=>$i18n->get('assetName'),
hoverHelp=>$i18n->get('snippet description'),
- defaultValue=>undef
+ defaultValue=>undef,
+ filter => "packSnippet",
},
+ snippetPacked => {
+ fieldType => "hidden",
+ defaultValue => undef,
+ },
+ usePacked => {
+ tab => 'properties',
+ fieldType => 'yesNo',
+ label => $i18n->get('usePacked label'),
+ hoverHelp => $i18n->get('usePacked description'),
+ },
cacheTimeout => {
tab => "display",
fieldType => "interval",
@@ -176,6 +190,43 @@ sub indexContent {
#-------------------------------------------------------------------
+=head2 packSnippet ( unpacked )
+
+Pack the snippet if possible. We can pack HTML, CSS, and JS snippets.
+
+=cut
+
+sub packSnippet {
+ my ( $self, $unpacked ) = @_;
+ return $unpacked if !$unpacked;
+ my $packed = $unpacked;
+
+ if ( $self->get('mimeType') eq "text/html" ) {
+ HTML::Packer::minify( \$packed, {
+ remove_comments => 1,
+ remove_newlines => 1,
+ do_javascript => "shrink",
+ do_stylesheet => "minify",
+ } );
+ }
+ elsif ( $self->get('mimeType') eq "text/css" ) {
+ CSS::Packer::minify( \$packed, {
+ compress => 'minify',
+ });
+ }
+ elsif ( $self->get('mimeType') eq 'text/javascript' ) {
+ JavaScript::Packer::minify( \$packed, {
+ compress => "shrink",
+ });
+ }
+
+ $self->update({ snippetPacked => $packed });
+
+ return $unpacked;
+}
+
+#-------------------------------------------------------------------
+
=head2 purgeCache ( )
Extending purgeCache to handle caching of the rendered snippet
@@ -216,7 +267,10 @@ sub view {
my $out = WebGUI::Cache->new($session,"view_".$calledAsWebMethod."_".$self->getId)->get;
return $out if $out;
}
- my $output = $self->get("snippet");
+ my $output = $self->get('usePacked')
+ ? $self->get("snippetPacked")
+ : $self->get('snippet')
+ ;
$output = $self->getToolbar.$output if ($session->var->isAdminOn && !$calledAsWebMethod);
if ($self->getValue("processAsTemplate")) {
$output = WebGUI::Asset::Template->processRaw($session, $output, $self->get);
diff --git a/lib/WebGUI/Asset/Template.pm b/lib/WebGUI/Asset/Template.pm
index 4374bd6bb..fc44a5516 100644
--- a/lib/WebGUI/Asset/Template.pm
+++ b/lib/WebGUI/Asset/Template.pm
@@ -20,7 +20,7 @@ use WebGUI::International;
use WebGUI::Asset::Template::HTMLTemplate;
use WebGUI::Utility;
use Clone qw/clone/;
-
+use HTML::Packer;
=head1 NAME
@@ -72,6 +72,7 @@ sub definition {
fieldType => 'codearea',
syntax => "html",
defaultValue => undef,
+ filter => 'packTemplate',
},
isEditable => {
noFormPost => 1,
@@ -95,6 +96,14 @@ sub definition {
fieldType => 'combo',
defaultValue => undef,
},
+ templatePacked => {
+ fieldType => 'hidden',
+ defaultValue => undef,
+ },
+ usePacked => {
+ fieldType => 'yesNo',
+ defaultValue => 1,
+ },
},
};
return $class->SUPER::definition($session,$definition);
@@ -137,6 +146,27 @@ sub duplicate {
#-------------------------------------------------------------------
+=head2 packTemplate ( template )
+
+Pack the template into a minified version for faster downloads.
+
+=cut
+
+sub packTemplate {
+ my ( $self, $template ) = @_;
+ my $packed = $template;
+ HTML::Packer::minify( \$packed, {
+ remove_comments => 1,
+ remove_newlines => 1,
+ do_javascript => "shrink",
+ do_stylesheet => "minify",
+ } );
+ $self->update({ templatePacked => $packed });
+ return $template;
+}
+
+#-------------------------------------------------------------------
+
sub processPropertiesFromFormPost {
my $self = shift;
$self->SUPER::processPropertiesFromFormPost;
@@ -207,6 +237,12 @@ sub getEditForm {
-syntax => "html",
-value=>$self->getValue("template")
);
+ $tabform->getTab('properties')->yesNo(
+ name => "usePacked",
+ label => $i18n->get('usePacked label'),
+ hoverHelp => $i18n->get('usePacked description'),
+ value => $self->getValue("usePacked"),
+ );
if($self->session->config->get("templateParsers")){
my @temparray = @{$self->session->config->get("templateParsers")};
tie my %parsers, 'Tie::IxHash';
@@ -365,7 +401,12 @@ sub process {
my $self = shift;
my $vars = shift;
$self->prepare unless ($self->{_prepared});
- return $self->getParser($self->session, $self->get("parser"))->process($self->get("template"), $vars);
+ my $parser = $self->getParser($self->session, $self->get("parser"));
+ my $template = $self->get('usePacked')
+ ? $self->get('templatePacked')
+ : $self->get('template')
+ ;
+ return $parser->process($template, $vars);
}
diff --git a/lib/WebGUI/Session/Style.pm b/lib/WebGUI/Session/Style.pm
index 81102d288..54b1bd3b5 100644
--- a/lib/WebGUI/Session/Style.pm
+++ b/lib/WebGUI/Session/Style.pm
@@ -196,6 +196,10 @@ if ($self->session->user->isRegistered || $self->session->setting->get("preventP
} else {
$var{'head.tags'} .= ''
}
+ # Removing the newlines will probably annoy people.
+ # Perhaps turn it off under debug mode?
+ $var{'head.tags'} =~ s/\n//g;
+
my $style = WebGUI::Asset::Template->new($self->session,$templateId);
my $output;
if (defined $style) {
diff --git a/lib/WebGUI/i18n/English/Asset.pm b/lib/WebGUI/i18n/English/Asset.pm
index 67683ae1c..b6193467e 100644
--- a/lib/WebGUI/i18n/English/Asset.pm
+++ b/lib/WebGUI/i18n/English/Asset.pm
@@ -1202,6 +1202,18 @@ Couldn't open %-s because %-s
context => q{Admin Console label. Shows the history of assets in this site.},
},
+ 'usePackedHeadTags label' => {
+ message => q{Use Packed Head Tags},
+ lastUpdated => 0,
+ context => q{Label for asset property},
+ },
+
+ 'usePackedHeadTags description' => {
+ message => q{Use the packed version of the head tags for faster downloads},
+ lastUpdated => 0,
+ context => q{Description of asset property},
+ },
+
};
1;
diff --git a/lib/WebGUI/i18n/English/Asset_Snippet.pm b/lib/WebGUI/i18n/English/Asset_Snippet.pm
index b57e67522..a5c88b7bc 100644
--- a/lib/WebGUI/i18n/English/Asset_Snippet.pm
+++ b/lib/WebGUI/i18n/English/Asset_Snippet.pm
@@ -44,7 +44,17 @@ our $I18N = {
message => q|Allows you to specify the MIME type of this asset when viewed via the web; useful if you'd like to serve CSS, plain text, javascript or other text files directly from the WebGUI asset system. Defaults to text/html.|,
lastUpdated => 1130880372,
},
+ 'usePacked label' => {
+ message => q{Use Packed},
+ lastUpdated => 0,
+ context => "Label for asset property",
+ },
+ 'usePacked description' => {
+ message => q{Use the packed version of this snippet for faster downloading.},
+ lastUpdated => 0,
+ context => 'Description of asset property',
+ },
};
1;
diff --git a/lib/WebGUI/i18n/English/Asset_Template.pm b/lib/WebGUI/i18n/English/Asset_Template.pm
index dca29af5c..7b17560ee 100644
--- a/lib/WebGUI/i18n/English/Asset_Template.pm
+++ b/lib/WebGUI/i18n/English/Asset_Template.pm
@@ -298,6 +298,17 @@ Any scratch variables will be available in the template with this syntax:
context => q{Label for URL to make a duplicate and open the duplicate's edit screen},
},
+ 'usePacked label' => {
+ message => q{Use Packed Template},
+ lastUpdated => 0,
+ context => q{Label for asset property},
+ },
+
+ 'usePacked description' => {
+ message => q{Use the packed version of this template for faster downloads},
+ lastUpdated => 0,
+ context => q{Description of asset property},
+ },
};
1;