diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 4bbbb8fd4..4a8a5c668 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -7,6 +7,7 @@ - fixed: loadAddConfigs loads hidden files - ensure proper XML encoding for ITransact messages - fixed: fatal error duplicate keywords added to a wiki page + - rfe: added the ability to choose whether assets should be added to the front or end of the first content position of the page (Dept of State) 7.5.5 - fixed: Several typos in the new Calendar help documentation. diff --git a/docs/upgrades/upgrade_7.5.5-7.5.6.pl b/docs/upgrades/upgrade_7.5.5-7.5.6.pl index aabd0de40..0cb31a533 100644 --- a/docs/upgrades/upgrade_7.5.5-7.5.6.pl +++ b/docs/upgrades/upgrade_7.5.5-7.5.6.pl @@ -23,6 +23,7 @@ my $quiet; # this line required my $session = start(); # this line required convertCacheToBinary($session); +addLayoutOrderSetting( $session ); finish($session); # this line required @@ -41,6 +42,22 @@ sub convertCacheToBinary { # # and here's our code #} +#---------------------------------------------------------------------------- +# Add a column to the Gallery +sub addLayoutOrderSetting { + my $session = shift; + print "\tAdding Layout Order Setting... " unless $quiet; + + $session->db->write( q{ + ALTER TABLE Layout ADD COLUMN assetOrder varchar(20) default 'asc'; + } ); + $session->db->write( q{ + UPDATE Layout SET assetOrder='asc'; + }); + + print "DONE!\n" unless $quiet; +} + # --------------- DO NOT EDIT BELOW THIS LINE -------------------------------- diff --git a/lib/WebGUI/Asset/Wobject/Layout.pm b/lib/WebGUI/Asset/Wobject/Layout.pm index e2a862a9e..be9157a3f 100644 --- a/lib/WebGUI/Asset/Wobject/Layout.pm +++ b/lib/WebGUI/Asset/Wobject/Layout.pm @@ -56,33 +56,38 @@ A hash reference passed in from a subclass definition. =cut sub definition { - my $class = shift; - my $session = shift; - my $definition = shift; - my $i18n = WebGUI::International->new($session,"Asset_Layout"); - push(@{$definition}, { - assetName=>$i18n->get("assetName"), - icon=>'layout.gif', - tableName=>'Layout', - className=>'WebGUI::Asset::Wobject::Layout', - properties=>{ - templateId =>{ - fieldType=>"template", - namespace => "Layout", - defaultValue=>'PBtmpl0000000000000054', - }, - contentPositions => { - noFormPost=>1, - defaultValue=>undef, - fieldType=>"hidden" - }, - assetsToHide => { - defaultValue=>undef, - fieldType=>"checkList" - } - } - }); - return $class->SUPER::definition($session, $definition); + my $class = shift; + my $session = shift; + my $definition = shift; + my $i18n = WebGUI::International->new($session,"Asset_Layout"); + + push(@{$definition}, { + assetName=>$i18n->get("assetName"), + icon=>'layout.gif', + tableName=>'Layout', + className=>'WebGUI::Asset::Wobject::Layout', + properties=>{ + templateId =>{ + fieldType =>"template", + namespace => "Layout", + defaultValue =>'PBtmpl0000000000000054', + }, + contentPositions => { + noFormPost =>1, + defaultValue =>undef, + fieldType =>"hidden" + }, + assetsToHide => { + defaultValue =>undef, + fieldType =>"checkList" + }, + assetOrder => { + defaultValue =>'asc', + fieldType =>'selectBox', + } + } + }); + return $class->SUPER::definition($session, $definition); } @@ -95,48 +100,61 @@ Returns the TabForm object that will be used in generating the edit page for thi =cut sub getEditForm { - my $self = shift; - my $tabform = $self->SUPER::getEditForm(); - my $i18n = WebGUI::International->new($self->session,"Asset_Layout"); + my $self = shift; + my $tabform = $self->SUPER::getEditForm(); + my $i18n = WebGUI::International->new($self->session,"Asset_Layout"); - my ($templateId); - if (($self->get("assetId") eq "new") && ($self->getParent->get('className') eq 'WebGUI::Asset::Wobject::Layout')) { - $templateId = $self->getParent->getValue('templateId'); - } else { - $templateId = $self->getValue('templateId'); - } - $tabform->getTab("display")->template( - -value=>$templateId, - -label=>$i18n->get('layout template title'), - -hoverHelp=>$i18n->get('template description'), - -namespace=>"Layout" - ); - if ($self->get("assetId") eq "new") { - $tabform->getTab("properties")->whatNext( - -options=>{ - view=>$i18n->get(823), - viewParent=>$i18n->get(847) - }, - -value=>"view" - ); - } else { - my @assetsToHide = split("\n",$self->getValue("assetsToHide")); - my $children = $self->getLineage(["children"],{"returnObjects"=>1, excludeClasses=>["WebGUI::Asset::Wobject::Layout"]}); - my %childIds; - foreach my $child (@{$children}) { - $childIds{$child->getId} = $child->getTitle; - } - $tabform->getTab("display")->checkList( - -name=>"assetsToHide", - -value=>\@assetsToHide, - -options=>\%childIds, - -label=>$i18n->get('assets to hide'), - -hoverHelp=>$i18n->get('assets to hide description'), - -vertical=>1, - -uiLevel=>9 - ); - } - return $tabform; + my ($templateId); + if (($self->get("assetId") eq "new") && ($self->getParent->get('className') eq 'WebGUI::Asset::Wobject::Layout')) { + $templateId = $self->getParent->getValue('templateId'); + } else { + $templateId = $self->getValue('templateId'); + } + $tabform->getTab("display")->template( + -value=>$templateId, + -label=>$i18n->get('layout template title'), + -hoverHelp=>$i18n->get('template description'), + -namespace=>"Layout" + ); + + tie my %assetOrder, "Tie::IxHash"; + %assetOrder = ( + "asc" =>$i18n->get("asset order asc"), + "desc" =>$i18n->get("asset order desc"), + ); + $tabform->getTab("display")->selectBox( + -name => 'assetOrder', + -label => $i18n->get('asset order label'), + -hoverHelp => $i18n->get('asset order hoverHelp'), + -value => $self->getValue('assetOrder'), + -options => \%assetOrder + ); + if ($self->get("assetId") eq "new") { + $tabform->getTab("properties")->whatNext( + -options=>{ + view=>$i18n->get(823), + viewParent=>$i18n->get(847) + }, + -value=>"view" + ); + } else { + my @assetsToHide = split("\n",$self->getValue("assetsToHide")); + my $children = $self->getLineage(["children"],{"returnObjects"=>1, excludeClasses=>["WebGUI::Asset::Wobject::Layout"]}); + my %childIds; + foreach my $child (@{$children}) { + $childIds{$child->getId} = $child->getTitle; + } + $tabform->getTab("display")->checkList( + -name=>"assetsToHide", + -value=>\@assetsToHide, + -options=>\%childIds, + -label=>$i18n->get('assets to hide'), + -hoverHelp=>$i18n->get('assets to hide description'), + -vertical=>1, + -uiLevel=>9 + ); + } + return $tabform; } @@ -147,182 +165,191 @@ sub getEditForm { #------------------------------------------------------------------- sub prepareView { - my $self = shift; - $self->SUPER::prepareView; - my $children = $self->getLineage( ["children"], { returnObjects=>1, excludeClasses=>["WebGUI::Asset::Wobject::Layout"] }); - my %vars; - # I'm sure there's a more efficient way to do this. We'll figure it out someday. - my @positions = split(/\./,$self->get("contentPositions")); - my @hidden = split("\n",$self->get("assetsToHide")); - my %placeHolder; - my $i = 1; - my $template = WebGUI::Asset->new($self->session,$self->get("templateId"),"WebGUI::Asset::Template"); - my $templateContent = $template->get("template"); - $self->{_viewTemplate} = $template; - my $numPositions = 1; - foreach my $j (2..15) { - $numPositions = $j if $templateContent =~ m/position${j}\_loop/; - } - my @found; - foreach my $position (@positions) { - my @assets = split(",",$position); - ASSET: foreach my $asset (@assets) { - my $childCount = 0; - CHILD: foreach my $child (@{$children}) { - if ($asset eq $child->getId) { - unless (isIn($asset,@hidden) || !($child->canView)) { - $child->prepareView; - if ($i > $numPositions || $i==1) { - $placeHolder{$child->getId} = $child; - push(@{$vars{"position1_loop"}},{ - id=>$child->getId, - isUncommitted=> $child->get('status') eq 'pending', - content=>"~~~".$child->getId."~~~~~" - }); - } else { - $placeHolder{$child->getId} = $child; - push(@{$vars{"position".$i."_loop"}},{ - id=>$child->getId, - isUncommitted=>$child->get('status') eq 'pending', - content=>"~~~".$child->getId."~~~~~" - }); - } - } - splice(@{$children},$childCount,1); + my $self = shift; + $self->SUPER::prepareView; + my $children = $self->getLineage( ["children"], { returnObjects=>1, excludeClasses=>["WebGUI::Asset::Wobject::Layout"] }); + my %vars; + # I'm sure there's a more efficient way to do this. We'll figure it out someday. + my @positions = split(/\./,$self->get("contentPositions")); + my @hidden = split("\n",$self->get("assetsToHide")); + my %placeHolder; + my $i = 1; + my $template = WebGUI::Asset->new($self->session,$self->get("templateId"),"WebGUI::Asset::Template"); + my $templateContent = $template->get("template"); + $self->{_viewTemplate} = $template; + my $numPositions = 1; + foreach my $j (2..15) { + $numPositions = $j if $templateContent =~ m/position${j}\_loop/; + } + my @found; + foreach my $position (@positions) { + my @assets = split(",",$position); + ASSET: foreach my $asset (@assets) { + my $childCount = 0; + CHILD: foreach my $child (@{$children}) { + if ($asset eq $child->getId) { + unless (isIn($asset,@hidden) || !($child->canView)) { + $child->prepareView; + if ($i > $numPositions || $i==1) { + $placeHolder{$child->getId} = $child; + push(@{$vars{"position1_loop"}},{ + id=>$child->getId, + isUncommitted=> $child->get('status') eq 'pending', + content=>"~~~".$child->getId."~~~~~" + }); + } else { + $placeHolder{$child->getId} = $child; + push(@{$vars{"position".$i."_loop"}},{ + id=>$child->getId, + isUncommitted=>$child->get('status') eq 'pending', + content=>"~~~".$child->getId."~~~~~" + }); + } + } + splice(@{$children},$childCount,1); next ASSET; }else{ $childCount++; - } - } - } - $i++; - } - # deal with unplaced children - foreach my $child (@{$children}) { - unless (isIn($child->getId,@hidden)) { - if ($child->canView) { - $child->prepareView; - $placeHolder{$child->getId} = $child; - push(@{$vars{"position1_loop"}},{ - id=>$child->getId, - content=>"~~~".$child->getId."~~~~~" - }); - } - } - } - $self->{_viewPlaceholder} = \%placeHolder; - $vars{showAdmin} = ($self->session->var->isAdminOn && $self->canEdit); - $self->{_viewVars} = \%vars; - if ($vars{showAdmin}) { - # under normal circumstances we don't put HTML stuff in our code, but this will make it much easier - # for end users to work with our templates - $self->session->style->setScript($self->session->url->extras("draggable.js"),{ type=>"text/javascript" }); - $self->session->style->setLink($self->session->url->extras("draggable.css"),{ type=>"text/css", rel=>"stylesheet", media=>"all" }); - $self->session->style->setRawHeadTags(' - - '); - } + } + } + } + $i++; + } + # deal with unplaced children + foreach my $child (@{$children}) { + unless (isIn($child->getId,@hidden)) { + if ($child->canView) { + $child->prepareView; + $placeHolder{$child->getId} = $child; + #Add children to the top or bottom of the first content position based on assetOrder setting + if($self->getValue("assetOrder") eq "asc"){ + push(@{$vars{"position1_loop"}},{ + id=>$child->getId, + content=>"~~~".$child->getId."~~~~~" + }); + } + else { + unshift(@{$vars{"position1_loop"}},{ + id=>$child->getId, + content=>"~~~".$child->getId."~~~~~" + }); + } + } + } + } + $self->{_viewPlaceholder} = \%placeHolder; + $vars{showAdmin} = ($self->session->var->isAdminOn && $self->canEdit); + $self->{_viewVars} = \%vars; + if ($vars{showAdmin}) { + # under normal circumstances we don't put HTML stuff in our code, but this will make it much easier + # for end users to work with our templates + $self->session->style->setScript($self->session->url->extras("draggable.js"),{ type=>"text/javascript" }); + $self->session->style->setLink($self->session->url->extras("draggable.css"),{ type=>"text/css", rel=>"stylesheet", media=>"all" }); + $self->session->style->setRawHeadTags(' + + '); + } } #------------------------------------------------------------------- sub view { - my $self = shift; - if ($self->{_viewVars}{showAdmin} && $self->canEditIfLocked) { - # under normal circumstances we don't put HTML stuff in our code, but this will make it much easier - # for end users to work with our templates - $self->{_viewVars}{"dragger.icon"} = '
'.$self->session->icon->drag('class="dragTrigger"').'
'; - $self->{_viewVars}{"dragger.init"} = ' - - - '; - } - my $showPerformance = $self->session->errorHandler->canShowPerformanceIndicators(); - my $out = $self->processTemplate($self->{_viewVars},undef,$self->{_viewTemplate}); - my @parts = split("~~~~~",$self->processTemplate($self->{_viewVars},undef,$self->{_viewTemplate})); - my $output = ""; - foreach my $part (@parts) { - my ($outputPart, $assetId) = split("~~~",$part,2); - if ($self->{_viewPrintOverride}) { - $self->session->output->print($outputPart); - } else { - $output .= $outputPart; - } - my $asset = $self->{_viewPlaceholder}{$assetId}; - if (defined $asset) { - my $t = [Time::HiRes::gettimeofday()] if ($showPerformance); - my $assetOutput = $asset->view; - $assetOutput .= "Asset:".Time::HiRes::tv_interval($t) if ($showPerformance); - if ($self->{_viewPrintOverride}) { - $self->session->output->print($assetOutput); - } else { - $output .= $assetOutput; - } - } - } - return $output; + my $self = shift; + if ($self->{_viewVars}{showAdmin} && $self->canEditIfLocked) { + # under normal circumstances we don't put HTML stuff in our code, but this will make it much easier + # for end users to work with our templates + $self->{_viewVars}{"dragger.icon"} = '
'.$self->session->icon->drag('class="dragTrigger"').'
'; + $self->{_viewVars}{"dragger.init"} = ' + + + '; + } + my $showPerformance = $self->session->errorHandler->canShowPerformanceIndicators(); + my $out = $self->processTemplate($self->{_viewVars},undef,$self->{_viewTemplate}); + my @parts = split("~~~~~",$self->processTemplate($self->{_viewVars},undef,$self->{_viewTemplate})); + my $output = ""; + foreach my $part (@parts) { + my ($outputPart, $assetId) = split("~~~",$part,2); + if ($self->{_viewPrintOverride}) { + $self->session->output->print($outputPart); + } else { + $output .= $outputPart; + } + my $asset = $self->{_viewPlaceholder}{$assetId}; + if (defined $asset) { + my $t = [Time::HiRes::gettimeofday()] if ($showPerformance); + my $assetOutput = $asset->view; + $assetOutput .= "Asset:".Time::HiRes::tv_interval($t) if ($showPerformance); + if ($self->{_viewPrintOverride}) { + $self->session->output->print($assetOutput); + } else { + $output .= $assetOutput; + } + } + } + return $output; } #------------------------------------------------------------------- sub www_setContentPositions { - my $self = shift; - return $self->session->privilege->insufficient() unless ($self->canEdit); - $self->addRevision({ - contentPositions=>$self->session->form->process("map") - }); - if ($self->session->setting->get("autoRequestCommit")) { + my $self = shift; + return $self->session->privilege->insufficient() unless ($self->canEdit); + $self->addRevision({ + contentPositions=>$self->session->form->process("map") + }); + if ($self->session->setting->get("autoRequestCommit")) { WebGUI::VersionTag->getWorking($self->session)->requestCommit; } - return "Map set: ".$self->session->form->process("map"); + return "Map set: ".$self->session->form->process("map"); } #------------------------------------------------------------------- sub getContentLastModified { # Buggo: this is a little too conservative. Children that are hidden maybe shouldn't count. Hm. - my $self = shift; - my $mtime = $self->get("revisionDate"); - foreach my $child (@{$self->getLineage(["children"],{returnObjects=>1, excludeClasses=>['WebGUI::Asset::Wobject::Layout']})}) { - my $child_mtime = $child->getContentLastModified; - $mtime = $child_mtime if ($child_mtime > $mtime); - } - return $mtime; + my $self = shift; + my $mtime = $self->get("revisionDate"); + foreach my $child (@{$self->getLineage(["children"],{returnObjects=>1, excludeClasses=>['WebGUI::Asset::Wobject::Layout']})}) { + my $child_mtime = $child->getContentLastModified; + $mtime = $child_mtime if ($child_mtime > $mtime); + } + return $mtime; } #------------------------------------------------------------------- sub www_view { - my $self = shift; - # slashdot / burst protection hack - if ($self->session->var->get("userId") eq "1" && $self->session->form->param() == 0) { - my $check = $self->checkView; - return $check if (defined $check); - my $cache = WebGUI::Cache->new($self->session, "view_".$self->getId); - my $out = $cache->get if defined $cache; - unless ($out) { - $self->prepareView; - $self->session->stow->set("cacheFixOverride", 1); - $out = $self->processStyle($self->view); - $cache->set($out, 60); - $self->session->stow->delete("cacheFixOverride"); - } - # keep those ads rotating - while ($out =~ /(\[AD\:([^\]]+)\])/gs) { - my $code = $1; - my $adSpace = WebGUI::AdSpace->newByName($self->session, $2); - my $ad = $adSpace->displayImpression if (defined $adSpace); - $out =~ s/\Q$code/$ad/ges; - } - $self->session->http->setLastModified($self->getContentLastModified); - $self->session->http->sendHeader; - $self->session->output->print($out, 1); - return "chunked"; - } - $self->{_viewPrintOverride} = 1; # we do this to make it output each asset as it goes, rather than waiting until the end - return $self->SUPER::www_view; + my $self = shift; + # slashdot / burst protection hack + if ($self->session->var->get("userId") eq "1" && $self->session->form->param() == 0) { + my $check = $self->checkView; + return $check if (defined $check); + my $cache = WebGUI::Cache->new($self->session, "view_".$self->getId); + my $out = $cache->get if defined $cache; + unless ($out) { + $self->prepareView; + $self->session->stow->set("cacheFixOverride", 1); + $out = $self->processStyle($self->view); + $cache->set($out, 60); + $self->session->stow->delete("cacheFixOverride"); + } + # keep those ads rotating + while ($out =~ /(\[AD\:([^\]]+)\])/gs) { + my $code = $1; + my $adSpace = WebGUI::AdSpace->newByName($self->session, $2); + my $ad = $adSpace->displayImpression if (defined $adSpace); + $out =~ s/\Q$code/$ad/ges; + } + $self->session->http->setLastModified($self->getContentLastModified); + $self->session->http->sendHeader; + $self->session->output->print($out, 1); + return "chunked"; + } + $self->{_viewPrintOverride} = 1; # we do this to make it output each asset as it goes, rather than waiting until the end + return $self->SUPER::www_view; } 1; diff --git a/lib/WebGUI/i18n/English/Asset_Layout.pm b/lib/WebGUI/i18n/English/Asset_Layout.pm index a2df97b2d..043019f08 100644 --- a/lib/WebGUI/i18n/English/Asset_Layout.pm +++ b/lib/WebGUI/i18n/English/Asset_Layout.pm @@ -112,6 +112,26 @@ be useful, others may not.|, message => q|The Id of the template used to display this Asset.|, lastUpdated => 1164841027 }, + + 'asset order asc' => { + message => q|To the Bottom|, + lastUpdated => 1164841027 + }, + + 'asset order desc' => { + message => q|To the Top|, + lastUpdated => 1164841027 + }, + + 'asset order label' => { + message => q|Add New Assets|, + lastUpdated => 1164841027 + }, + + 'asset order hoverhelp' => { + message => q|Choose whether you'd like new or unpositioned assets added to the top or bottom of the first content position on the page.|, + lastUpdated => 1164841027 + }, };