From 18460256df554361c07c12e136a3d582d1117b20 Mon Sep 17 00:00:00 2001 From: Doug Bell Date: Thu, 7 May 2009 17:35:43 +0000 Subject: [PATCH] template attachments now work with packages. head_attachments and body_attachments are now documented --- lib/WebGUI/Asset/Template.pm | 345 +++++++++++----------- lib/WebGUI/Help/WebGUI.pm | 2 +- lib/WebGUI/i18n/English/Asset_Template.pm | 18 ++ lib/WebGUI/i18n/English/WebGUI.pm | 15 + www/extras/templateAttachments.js | 47 +-- 5 files changed, 223 insertions(+), 204 deletions(-) diff --git a/lib/WebGUI/Asset/Template.pm b/lib/WebGUI/Asset/Template.pm index 9f2d7ba42..588f2daf6 100644 --- a/lib/WebGUI/Asset/Template.pm +++ b/lib/WebGUI/Asset/Template.pm @@ -24,12 +24,6 @@ use Tie::IxHash; use Clone qw/clone/; use HTML::Packer; -tie my %attachmentTypeNames, 'Tie::IxHash' => ( - stylesheet => 'CSS Stylesheet', - headScript => 'Javascript (head)', - bodyScript => 'Javascript (body)', -); - =head1 NAME Package WebGUI::Asset::Template @@ -51,52 +45,6 @@ These methods are available from this class: #------------------------------------------------------------------- -=head2 addAttachments ( attachments ) - -Adds attachments to this template. Attachments is an arrayref of hashrefs, -where each hashref should have at least url, type, and sequence as keys. - -=cut - -sub addAttachments { - my ($self, $attachments) = @_; - my $db = $self->session->db; - - my $sql = q{ - INSERT INTO template_attachments - (templateId, revisionDate, url, type, sequence) - VALUES - (?, ?, ?, ?, ?) - }; - - foreach my $a (@$attachments) { - my @params = ( - $self->getId, - $self->get('revisionDate'), - @{$a}{qw(url type sequence)} - ); - $db->write($sql, \@params); - } -} - -#------------------------------------------------------------------- - -=head2 addRevision ( ) - -Override the master addRevision to copy attachments - -=cut - -sub addRevision { - my $self = shift; - my $object = $self->SUPER::addRevision(@_); - $object->addAttachments($self->getAttachments); - - return $object; -} - -#------------------------------------------------------------------- - =head2 definition ( session, definition ) Defines the properties of this asset. @@ -156,7 +104,7 @@ sub definition { }, usePacked => { fieldType => 'yesNo', - defaultValue => 1, + defaultValue => 0, }, }, }; @@ -165,6 +113,53 @@ sub definition { #------------------------------------------------------------------- +=head2 addAttachments ( attachments ) + +Adds attachments to this template. Attachments is an arrayref of hashrefs, +where each hashref should have at least url, type, and sequence as keys. + +=cut + +sub addAttachments { + my ($self, $attachments) = @_; + + my $db = $self->session->db; + + my $sql = q{ + INSERT INTO template_attachments + (templateId, revisionDate, url, type, sequence) + VALUES + (?, ?, ?, ?, ?) + }; + + foreach my $a (@$attachments) { + my @params = ( + $self->getId, + $self->get('revisionDate'), + @{$a}{qw(url type sequence)} + ); + $db->write($sql, \@params); + } +} + +#------------------------------------------------------------------- + +=head2 addRevision ( ) + +Override the master addRevision to copy attachments + +=cut + +sub addRevision { + my ( $self, $properties, @args ) = @_; + my $asset = $self->SUPER::addRevision($properties, @args); + delete $properties->{templatePacked}; + $asset->addAttachments($self->getAttachments); + return $asset; +} + +#------------------------------------------------------------------- + =head2 drawExtraHeadTags ( ) Override the master drawExtraHeadTags to prevent Style template from having @@ -200,105 +195,17 @@ sub duplicate { #------------------------------------------------------------------- -=head2 removeAttachments ( urls ) +=head2 exportAssetData ( ) -Removes the specified attachments (specified by their urls, NOT by hashrefs, -since urls are unique to a particular revision) from this template. urls -should be an arrayref of strings. +Override to add attachments to package data =cut -sub removeAttachments { - my ($self, $urls) = @_; - - return unless @$urls; - - my $db = $self->session->db; - my $dbh = $db->dbh; - my $in = join(',', map { $dbh->quote($_) } @$urls); - my $rmsql = qq{ - DELETE FROM - template_attachments - WHERE - templateId = ? - AND revisionDate = ? - AND url IN ($in) - }; - my @params = ( - $self->getId, - $self->get('revisionDate'), - ); - $db->write($rmsql, \@params); -} - -#------------------------------------------------------------------- - -=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; - # TODO: Perhaps add a way to check template syntax before it blows stuff up? - my %data; - my $needsUpdate = 0; - if ($self->getValue("parser") ne $self->session->form->process("parser","className") && ($self->session->form->process("parser","className") ne "")) { - $needsUpdate = 1; - if (isIn($self->session->form->process("parser","className"),@{$self->session->config->get("templateParsers")})) { - %data = ( parser => $self->session->form->process("parser","className") ); - } else { - %data = ( parser => $self->session->config->get("defaultTemplateParser") ); - } - } - if ($self->session->form->process("namespace") eq 'style') { - $needsUpdate = 1; - $data{extraHeadTags} = ''; - } - - my $f = $self->session->form; - my $p = $f->paramsHashRef; - my @nums = grep {$_} map { my ($i) = /^attachmentUrl(\d+)$/; $i } keys %$p; - my @add; - - foreach my $n (@nums) { - my ($index, $type, $url) = - map { $f->process('attachment' . $_ . $n) } - qw(Index Type Url); - - push( - @add, { - sequence => $index, - url => $url, - type => $type, - } - ); - } - - my @remove = $f->process('removeAttachment', 'list'); - $data{removeAttachments} = \@remove; - $data{attachments} = \@add; - - $needsUpdate = 1 if @remove || @add; - - $self->update(\%data) if $needsUpdate; +sub exportAssetData { + my ( $self ) = @_; + my $data = $self->SUPER::exportAssetData; + $data->{template_attachments} = $self->getAttachments; + return $data; } #------------------------------------------------------------------- @@ -412,10 +319,17 @@ sub getEditForm { ); } + ### Template attachments my $session = $self->session; my @headers = map { '' . $i18n->get("attachment header $_") . '' } qw(index type url remove); + tie my %attachmentTypeNames, 'Tie::IxHash' => ( + stylesheet => $i18n->get('css label'), + headScript => $i18n->get('js head label'), + bodyScript => $i18n->get('js body label'), + ); + my $table = ''; $table .= "@headers"; foreach my $a ( @{ $self->getAttachments } ) { @@ -550,7 +464,21 @@ sub getParser { } } +#------------------------------------------------------------------- +=head2 importAssetCollateralData ( data ) + +Override to import attachments + +=cut + +sub importAssetCollateralData { + my ( $self, $data, @args ) = @_; + $self->removeAttachments; + $self->addAttachments( $data->{template_attachments} ); + return $self->SUPER::importAssetCollateralData( $data, @args ); +} + #------------------------------------------------------------------- =head2 indexContent ( ) @@ -566,6 +494,26 @@ sub indexContent { $indexer->setIsPublic(0); } +#------------------------------------------------------------------- + +=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; +} #------------------------------------------------------------------- @@ -650,6 +598,54 @@ sub process { } +#------------------------------------------------------------------- + +sub processPropertiesFromFormPost { + my $self = shift; + $self->SUPER::processPropertiesFromFormPost; + # TODO: Perhaps add a way to check template syntax before it blows stuff up? + my %data; + my $needsUpdate = 0; + if ($self->getValue("parser") ne $self->session->form->process("parser","className") && ($self->session->form->process("parser","className") ne "")) { + $needsUpdate = 1; + if (isIn($self->session->form->process("parser","className"),@{$self->session->config->get("templateParsers")})) { + %data = ( parser => $self->session->form->process("parser","className") ); + } else { + %data = ( parser => $self->session->config->get("defaultTemplateParser") ); + } + } + if ($self->session->form->process("namespace") eq 'style') { + $needsUpdate = 1; + $data{extraHeadTags} = ''; + } + + ### Template attachments + my $f = $self->session->form; + my $p = $f->paramsHashRef; + my @nums = grep {$_} map { my ($i) = /^attachmentUrl(\d+)$/; $i } keys %$p; + my @add; + + # Remove all attachments first, then re-add whatever's left in the form + $self->removeAttachments; + + foreach my $n (@nums) { + my ($index, $type, $url) = + map { $f->process('attachment' . $_ . $n) } + qw(Index Type Url); + + push( + @add, { + sequence => $index, + url => $url, + type => $type, + } + ); + } + $self->addAttachments(\@add); + + return; +} + #------------------------------------------------------------------- =head2 processRaw ( session, template, vars [ , parser ] ) @@ -693,16 +689,44 @@ Override the master purgeRevision to purge attachments sub purgeRevision { my $self = shift; - my $db = $self->session->db; - my $sql = q{ + $self->removeAttachments; + return $self->SUPER::purgeRevision(@_); +} + +#------------------------------------------------------------------- + +=head2 removeAttachments ( urls ) + +Removes attachments. C is an arrayref of URLs to remove. If C +is not defined, will remove all attachments for this revision. + +=cut + +sub removeAttachments { + my ($self, $urls) = @_; + + my $db = $self->session->db; + my $dbh = $db->dbh; + my $rmsql = qq{ DELETE FROM - template_attachments - WHERE + template_attachments + WHERE templateId = ? AND revisionDate = ? }; - $db->write($sql, [$self->getId, $self->get('revisionDate')]); - return $self->SUPER::purgeRevision(@_); + + if ( $urls && @{$urls} ) { + my $in = join(',', map { $dbh->quote($_) } @{$urls}); + $rmsql .= qq{ + AND url IN ($in) + }; + } + + my @params = ( + $self->getId, + $self->get('revisionDate'), + ); + $db->write($rmsql, \@params); } #------------------------------------------------------------------- @@ -710,14 +734,9 @@ sub purgeRevision { =head2 update Override update from Asset.pm to handle backwards compatibility with the old -packages that contain headBlocks. - -This method is deprecated and will be removed in the future. Don't plan +packages that contain headBlocks. This will be removed in the future. Don't plan on this being here. -Note, we are also using this now to update template attachments. So maybe it -will stay. - =cut sub update { @@ -725,12 +744,6 @@ sub update { my $requestedProperties = shift; my $properties = clone($requestedProperties); - my $attachments = delete $properties->{attachments} || []; - my $removeAttachments = delete $properties->{removeAttachments} || []; - - $self->removeAttachments($removeAttachments); - $self->addAttachments($attachments); - if (exists $properties->{headBlock}) { $properties->{extraHeadTags} .= $properties->{headBlock}; delete $properties->{headBlock}; diff --git a/lib/WebGUI/Help/WebGUI.pm b/lib/WebGUI/Help/WebGUI.pm index 757a6c8ca..ffe4e5572 100644 --- a/lib/WebGUI/Help/WebGUI.pm +++ b/lib/WebGUI/Help/WebGUI.pm @@ -6,7 +6,7 @@ our $HELP = { 'style template' => { title => '1073', body => '', - variables => [ { 'name' => 'body.content' }, { 'name' => 'head.tags' } ], + variables => [ { 'name' => 'body.content' }, { 'name' => 'head.tags' }, { 'name' => 'head_attachments' }, { 'name' => 'body_attachments' } ], fields => [], related => [] }, diff --git a/lib/WebGUI/i18n/English/Asset_Template.pm b/lib/WebGUI/i18n/English/Asset_Template.pm index cde93e6d9..6ca15e990 100644 --- a/lib/WebGUI/i18n/English/Asset_Template.pm +++ b/lib/WebGUI/i18n/English/Asset_Template.pm @@ -351,6 +351,24 @@ Any scratch variables will be available in the template with this syntax:
lastUpdated => 0, context => q{Description of asset property}, }, + + 'css label' => { + message => "Stylesheet (CSS)", + lastUpdated => 0, + context => 'Label for a CSS file attachment', + }, + + 'js head label' => { + message => "JavaScript (head)", + lastUpdated => 0, + context => "Label for a JS file attachment that goes in the block", + }, + + 'js body label' => { + message => "JavaScript (body)", + lastUpdated => 0, + context => "Label for a JS file attachment that goes after all the content in the block", + }, }; 1; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 710534b2b..42ea8bab8 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -995,6 +995,8 @@ to add or remove users from their groups. 'head.tags' => { message => q|Tags that WebGUI automatically generates for you so that caching works the way it should, search engines can find you better, and other useful automated functionality. This should go in the <head> </head> section of your style.
+
NOTE: This is for backwards-compatibility only. You should use 'head_attachments' and 'body_attachments' now. +

We suggest using something like this in the <title> </title> portion of your style:

^PageTitle(); - ^c(); @@ -1003,6 +1005,19 @@ to add or remove users from their groups. lastUpdated => 1225222473, }, + 'head_attachments' => { + message => q{Tags that belong only in the <head> of the document. If you use this, you must use body_attachments and must not use head.tags.}, + lastUpdated => 0, + context => 'description of template variable', + }, + + 'body_attachments' => { + message => q{Tags that can be placed right before the end of the <body> to speed up page load times. If you use this, you must use head_attachments and must not use head.tags.}, + lastUpdated => 0, + context => 'description of template variable', + }, + + '860' => { message => q|Make email address public?|, lastUpdated => 1043879942 diff --git a/www/extras/templateAttachments.js b/www/extras/templateAttachments.js index 442712029..7c94014ee 100644 --- a/www/extras/templateAttachments.js +++ b/www/extras/templateAttachments.js @@ -6,7 +6,6 @@ var addClick = (function() { var count = 0; var urls = {}; var types = {}; - var originals = {}; var addAnchor = document.getElementById('addAnchor'); var displayTable = document.getElementById('attachmentDisplay'); @@ -40,20 +39,15 @@ var addClick = (function() { type: query('type', 'td', node)[0].innerHTML, url: query('url', 'td', node)[0].innerHTML }; - originals[d.url] = true; add(d); node.parentNode.removeChild(node); } } - // When an original box gets changed, we should insert a removal node and - // name the fields so that we remove the old and insert the new. + // When an original box gets changed function updater(u) { return function() { obj = urls[u]; - obj.index.onchange = null; - obj.type.onchange = null; - insertHidden(u); nameFields(u); }; } @@ -63,21 +57,12 @@ var addClick = (function() { function nameFields(u) { var id = uniqueId++; var obj = urls[u]; - obj.index.name = 'attachmentIndex' + id; - obj.type.name = 'attachmentType' + id; - obj.url.name = 'attachmentUrl' + id; - } - - // Insert a hidden input field in the form so that the backend knows to - // remove one of the original attachments - function insertHidden(u) { - var tr = urls[u].tr; - var hid = document.createElement('input'); - hid.type = 'hidden'; - hid.name = 'removeAttachment'; - hid.value = u; - tr.parentNode.appendChild(hid); - delete originals[u]; + if (!obj.index.name) + obj.index.name = 'attachmentIndex' + id; + if (!obj.type.name) + obj.type.name = 'attachmentType' + id; + if (!obj.url.name) + obj.url.name = 'attachmentUrl' + id; } // Make a function which will remove an attachment (remove the table row @@ -86,10 +71,6 @@ var addClick = (function() { return function() { var tr = urls[u].tr; - if (originals[u]) { - insertHidden(u); - } - tr.parentNode.removeChild(tr); delete urls[u]; @@ -144,9 +125,7 @@ var addClick = (function() { else { url.oldValue = newValue; var d = urls[oldValue]; - if (originals[oldValue]) { - update(); - } + update(); delete urls[oldValue]; urls[newValue] = d; @@ -173,14 +152,7 @@ var addClick = (function() { url : url, }; - if (originals[d.url]) { - // url's is already taken care of above - index.onchange = update; - type.onchange = update; - } - else { - nameFields(d.url); - } + nameFields(d.url); addAnchor.appendChild(tr); } @@ -199,5 +171,6 @@ var addClick = (function() { return; } add(d); + nodes.url.value = ''; }; })();