template attachments now work with packages. head_attachments and body_attachments are now documented

This commit is contained in:
Doug Bell 2009-05-07 17:35:43 +00:00
parent 28311c08d4
commit 18460256df
5 changed files with 223 additions and 204 deletions

View file

@ -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 { '<th>' . $i18n->get("attachment header $_") . '</th>' }
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 id="attachmentDisplay">';
$table .= "<thead><tr>@headers</tr></thead><tbody id='addAnchor'>";
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<urls> is an arrayref of URLs to remove. If C<urls>
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};

View file

@ -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 => []
},

View file

@ -351,6 +351,24 @@ Any scratch variables will be available in the template with this syntax:<br/>
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 <head> block",
},
'js body label' => {
message => "JavaScript (body)",
lastUpdated => 0,
context => "Label for a JS file attachment that goes after all the content in the <body> block",
},
};
1;

View file

@ -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 &lt;head&gt; &lt;/head&gt; section of your style.
<br />
<br />NOTE: This is for backwards-compatibility only. You should use 'head_attachments' and 'body_attachments' now.
<br />
<br />We suggest using something like this in the &lt;title&gt; &lt;/title&gt; portion of your style:
<br />
<br />&#94;PageTitle(); - &#94;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 &lt;head&gt; 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 &lt;body&gt; 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

View file

@ -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 = '';
};
})();