all sorts of navigation and asset manager fixes

This commit is contained in:
JT Smith 2004-12-28 21:00:33 +00:00
parent f1806d943c
commit 87aef8eaac
7 changed files with 239 additions and 247 deletions

View file

@ -1,7 +1,7 @@
6.3.0 6.3.0
- Migrated all wobjects to assets. - Migrated all wobjects to assets.
- Migrated pages to the layout and redirect assets. - Migrated pages to the layout and redirect assets.
- Converted site maps to navigation macros. - Converted site maps to navigation assets.
- Converted file managers to layout assets with file and image assets - Converted file managers to layout assets with file and image assets
attached. attached.
- Converted page templates to use CSS-based layouts instead of tables. - Converted page templates to use CSS-based layouts instead of tables.

View file

@ -22,14 +22,15 @@ save you many hours of grief.
need to download and upgrade to 5.5.x before you can upgrade need to download and upgrade to 5.5.x before you can upgrade
to 6.3 or higher. to 6.3 or higher.
* All Site Map wobjects will be migrated to Navigation macros in * All Site Map wobjects will be migrated to Navigation assets
Articles during the upgrade. All the site map templates will during the upgrade. All the site map templates will
be lost. If you want them, save them before the upgrade. Also be lost. If you want them, save them before the upgrade. Also
check your site after the upgrade for all site maps to make check your site after the upgrade for all site maps to make
sure that they look the way you want them to look. sure that they look the way you want them to look.
* All File Manager wobjects have been migrated to File Folder Layout * All File Manager wobjects have been migrated to File Folder Layout
assets. assets. The File Manager templates will be deleted during the
upgrade, so if you want to keep yours, get them before upgrading.
* If you have any SQL reports querying internal WebGUI database tables, * If you have any SQL reports querying internal WebGUI database tables,
you'll need to update them after the upgrade. Most of WebGUI's you'll need to update them after the upgrade. Most of WebGUI's

View file

@ -92,17 +92,17 @@ while (my ($namespace) = $sth->array) {
$sth->finish; $sth->finish;
walkTree('0','PBasset000000000000001','000001','1'); walkTree('0','PBasset000000000000001','000001','1');
print "\t\tMaking second round of table structure changes\n" unless ($quiet); print "\t\tMaking second round of table structure changes\n" unless ($quiet);
WebGUI::SQL->write("drop table SiteMap");
WebGUI::SQL->write("delete from template where namespace in ('SiteMap')");
my $sth = WebGUI::SQL->read("select distinct(namespace) from wobject where namespace is not null"); my $sth = WebGUI::SQL->read("select distinct(namespace) from wobject where namespace is not null");
while (my ($namespace) = $sth->array) { while (my ($namespace) = $sth->array) {
if (isIn($namespace, qw(Article DataForm EventsCalendar HttpProxy IndexedSearch MessageBoard Poll Product SQLReport Survey SyndicatedContent USS WobjectProxy WSClient))) { if (isIn($namespace, qw(Article DataForm EventsCalendar HttpProxy IndexedSearch MessageBoard Poll Product SQLReport Survey SyndicatedContent USS WobjectProxy WSClient))) {
WebGUI::SQL->write("alter table ".$namespace." drop column wobjectId"); WebGUI::SQL->write("alter table ".$namespace." drop column wobjectId");
WebGUI::SQL->write("alter table ".$namespace." add primary key (assetId)");
} elsif (isIn($namespace, qw(Navigation Layout))) {
# do nothing
} else { } else {
WebGUI::SQL->write("alter table ".$namespace." drop primary key"); WebGUI::SQL->write("alter table ".$namespace." drop primary key");
WebGUI::SQL->write("alter table ".$namespace." add primary key (assetId)");
} }
WebGUI::SQL->write("alter table ".$namespace." add primary key (assetId)");
} }
$sth->finish; $sth->finish;
WebGUI::SQL->write("alter table wobject drop column wobjectId"); WebGUI::SQL->write("alter table wobject drop column wobjectId");
@ -132,10 +132,14 @@ WebGUI::SQL->write("alter table wobject drop column editedBy");
WebGUI::SQL->write("alter table wobject drop column lastEdited"); WebGUI::SQL->write("alter table wobject drop column lastEdited");
WebGUI::SQL->write("alter table wobject drop column allowDiscussion"); WebGUI::SQL->write("alter table wobject drop column allowDiscussion");
WebGUI::SQL->write("drop table page"); WebGUI::SQL->write("drop table page");
WebGUI::SQL->write("drop table FileManager");
WebGUI::SQL->write("drop table FileManager_file");
WebGUI::SQL->write("delete from template where namespace in ('FileManager')");
WebGUI::SQL->write("drop table SiteMap");
WebGUI::SQL->write("delete from template where namespace in ('SiteMap')");
WebGUI::SQL->write("alter table Article drop column image"); WebGUI::SQL->write("alter table Article drop column image");
WebGUI::SQL->write("alter table Article drop column attachment"); WebGUI::SQL->write("alter table Article drop column attachment");
my %migration; my %migration;
print "\tConverting navigation system to asset tree\n" unless ($quiet); print "\tConverting navigation system to asset tree\n" unless ($quiet);
@ -259,6 +263,39 @@ WebGUI::SQL->write("update Navigation set startPoint='root' where startPoint='na
WebGUI::SQL->write("drop table tempoldnav"); WebGUI::SQL->write("drop table tempoldnav");
print "\tConverting navigation templates\n" unless ($quiet);
my $sth = WebGUI::SQL->read("select templateId, template from template where namespace='Navigation'");
while (my ($id, $template) = $sth->array) {
$template =~ s/isBasePage/isCurrent/isg;
$template =~ s/basePage/currentPage/isg;
$template =~ s/isRoot/isBranchRoot/isg;
$template =~ s/inRoot/inBranchRoot/isg;
$template =~ s/urlizedTitle/url/isg;
$template =~ s/ownerId/ownerUserId/isg;
$template =~ s/isTop/isTopOfBranch/isg;
$template =~ s/isDaughter/isChild/isg;
$template =~ s/isMother/isParent/isg;
$template =~ s/isSister/isSibling/isg;
$template =~ s/isLeftMost/isRankedFirst/isg;
$template =~ s/isRightMost/isRankedLast/isg;
$template =~ s/hasDaughter/hasChild/isg;
$template =~ s/mother/parent/isg;
$template =~ s/config\.button/controls/isg;
$template =~ s/pageId/assetId/isg;
$template = '
<tmpl_if displayTitle>
<h1><tmpl_var title></h1>
</tmpl_if>
<tmpl_if description>
<p><tmpl_var description></p>
</tmpl_if>
'.$template;
WebGUI::SQL->write("update template set template=".quote($template)." where templateId=".quote($id)." and namespace='Navigation'");
}
$sth->finish;
print "\tDeleting files which are no longer used.\n" unless ($quiet); print "\tDeleting files which are no longer used.\n" unless ($quiet);
#unlink("../../lib/WebGUI/Page.pm"); #unlink("../../lib/WebGUI/Page.pm");
#unlink("../../lib/WebGUI/Operation/Page.pm"); #unlink("../../lib/WebGUI/Operation/Page.pm");
@ -310,10 +347,10 @@ sub walkTree {
WebGUI::SQL->write("insert into redirect (assetId, redirectUrl) values (".quote($pageId).",".quote($page->{redirectURL}).")"); WebGUI::SQL->write("insert into redirect (assetId, redirectUrl) values (".quote($pageId).",".quote($page->{redirectURL}).")");
} else { } else {
WebGUI::SQL->write("insert into wobject (assetId, styleTemplateId, templateId, printableStyleTemplateId, WebGUI::SQL->write("insert into wobject (assetId, styleTemplateId, templateId, printableStyleTemplateId,
cacheTimeout, cacheTimeoutVisitor, displayTitle) values ( cacheTimeout, cacheTimeoutVisitor, displayTitle, namespace) values (
".quote($pageId).", ".quote($page->{styleId}).", ".quote($page->{templateId}).", ".quote($pageId).", ".quote($page->{styleId}).", ".quote($page->{templateId}).",
".quote($page->{printableStyleId}).", ".quote($page->{cacheTimeout}).",".quote($page->{cacheTimeoutVisitor}).", ".quote($page->{printableStyleId}).", ".quote($page->{cacheTimeout}).",".quote($page->{cacheTimeoutVisitor}).",
0)"); 0,'Layout')");
WebGUI::SQL->write("insert into layout (assetId) values (".quote($pageId).")"); WebGUI::SQL->write("insert into layout (assetId) values (".quote($pageId).")");
} }
my $rank = 1; my $rank = 1;
@ -399,7 +436,7 @@ sub walkTree {
print "\t\t\tConverting File Manager ".$wobject->{wobjectId}." into File Folder Layout\n" unless ($quiet); print "\t\t\tConverting File Manager ".$wobject->{wobjectId}." into File Folder Layout\n" unless ($quiet);
WebGUI::SQL->write("update asset set className='WebGUI::Asset::Layout' where assetId=".quote($wobjectId)); WebGUI::SQL->write("update asset set className='WebGUI::Asset::Layout' where assetId=".quote($wobjectId));
WebGUI::SQL->write("insert into layout (assetId) values (".quote($wobjectId).")"); WebGUI::SQL->write("insert into layout (assetId) values (".quote($wobjectId).")");
WebGUI::SQL->write("update wobject set templateId='15' where wobjectId=".quote($wobjectId)); WebGUI::SQL->write("update wobject set templateId='15', namespace='Layout' where wobjectId=".quote($wobjectId));
print "\t\t\tMigrating attachments for File Manager ".$wobject->{wobjectId}."\n" unless ($quiet); print "\t\t\tMigrating attachments for File Manager ".$wobject->{wobjectId}."\n" unless ($quiet);
my $sth = WebGUI::SQL->read("select * from FileManager_file where wobjectId=".quote($wobjectId)." order by sequenceNumber"); my $sth = WebGUI::SQL->read("select * from FileManager_file where wobjectId=".quote($wobjectId)." order by sequenceNumber");
my $rank = 1; my $rank = 1;
@ -556,10 +593,6 @@ sub getNewId {
'MessageBoard' => { 'MessageBoard' => {
'1' => 'PBtmpl0000000000000047' '1' => 'PBtmpl0000000000000047'
}, },
'FileManager' => {
'1' => 'PBtmpl0000000000000025',
'2' => 'PBtmpl0000000000000087'
},
'Operation/Profile/View' => { 'Operation/Profile/View' => {
'1' => 'PBtmpl0000000000000052' '1' => 'PBtmpl0000000000000052'
}, },
@ -820,7 +853,6 @@ sub getNewId {
} }
}, },
'nav' => { 'nav' => {
'1002' => 'PBnav00000000000000005',
'11' => 'PBnav00000000000000006', '11' => 'PBnav00000000000000006',
'7' => 'PBnav00000000000000019', '7' => 'PBnav00000000000000019',
'2' => 'PBnav00000000000000014', '2' => 'PBnav00000000000000014',
@ -829,18 +861,14 @@ sub getNewId {
'18' => 'PBnav00000000000000013', '18' => 'PBnav00000000000000013',
'16' => 'PBnav00000000000000011', '16' => 'PBnav00000000000000011',
'13' => 'PBnav00000000000000008', '13' => 'PBnav00000000000000008',
'iBkcoHUb-z4vzYPyX0oS5A' => 'PBnav00000000000000023',
'6' => 'PBnav00000000000000018', '6' => 'PBnav00000000000000018',
'b3XBaWXeMXS39HPDfV2y5Q' => 'PBnav00000000000000022',
'3' => 'PBnav00000000000000015', '3' => 'PBnav00000000000000015',
'9' => 'PBnav00000000000000021', '9' => 'PBnav00000000000000021',
'12' => 'PBnav00000000000000007', '12' => 'PBnav00000000000000007',
'14' => 'PBnav00000000000000009', '14' => 'PBnav00000000000000009',
'15' => 'PBnav00000000000000010', '15' => 'PBnav00000000000000010',
'8' => 'PBnav00000000000000020', '8' => 'PBnav00000000000000020',
'1001' => 'PBnav00000000000000004',
'4' => 'PBnav00000000000000016', '4' => 'PBnav00000000000000016',
'1000' => 'PBnav00000000000000003',
'10' => 'PBnav00000000000000002', '10' => 'PBnav00000000000000002',
'5' => 'PBnav00000000000000017' '5' => 'PBnav00000000000000017'
} }

View file

@ -26,6 +26,7 @@ sub addChild {
my $properties = shift; my $properties = shift;
my $id = WebGUI::Id::generate(); my $id = WebGUI::Id::generate();
my $lineage = $self->get("lineage").$self->getNextChildRank; my $lineage = $self->get("lineage").$self->getNextChildRank;
$self->{_hasChildren} = 1;
WebGUI::SQL->beginTransaction; WebGUI::SQL->beginTransaction;
WebGUI::SQL->write("insert into asset (assetId, parentId, lineage, state, className, url, startDate, endDate) WebGUI::SQL->write("insert into asset (assetId, parentId, lineage, state, className, url, startDate, endDate)
values (".quote($id).",".quote($self->getId).", ".quote($lineage).", values (".quote($id).",".quote($self->getId).", ".quote($lineage).",
@ -148,6 +149,14 @@ sub demote {
} }
} }
sub DESTROY {
my $self = shift;
$self->{_parent}->DESTROY if (exists $self->{_parent});
$self->{_firstChild}->DESTROY if (exists $self->{_firstChild});
$self->{_lastChild}->DESTROY if (exists $self->{_lastChild});
$self = undef;
}
sub duplicate { sub duplicate {
my $self = shift; my $self = shift;
my $newAsset = $self->addChild($self->get); my $newAsset = $self->addChild($self->get);
@ -357,10 +366,13 @@ sub getEditForm {
} }
sub getFirstDescendant { sub getFirstChild {
my $self = shift; my $self = shift;
$self->{_firstDescendant} = WebGUI::Asset->newByLineage($self->get("lineage").$self->formatRank(1)) unless (exists $self->{_firstDescendant}); unless (exists $self->{_firstChild}) {
return $self->{_firstDescendant}; my ($lineage) = WebGUI::SQL->quickArray("select min(lineage) from asset where parentId=".quote($self->getId));
$self->{_firstChild} = WebGUI::Asset->newByLineage($lineage);
}
return $self->{_firstChild};
} }
sub getIcon { sub getIcon {
@ -389,11 +401,21 @@ sub getIndexerParams {
} }
sub getLastChild {
my $self = shift;
unless (exists $self->{_lastChild}) {
my ($lineage) = WebGUI::SQL->quickArray("select max(lineage) from asset where parentId=".quote($self->getId));
$self->{_lastChild} = WebGUI::Asset->newByLineage($lineage);
}
return $self->{_lastChild};
}
sub getLineage { sub getLineage {
my $self = shift; my $self = shift;
my $relatives = shift; my $relatives = shift;
my $rules = shift; my $rules = shift;
my $lineage = $self->get("lineage"); my $lineage = $self->get("lineage");
# deal with exclusions
my $whereExclusion = " and state='published'"; my $whereExclusion = " and state='published'";
if (exists $rules->{excludeClasses}) { if (exists $rules->{excludeClasses}) {
my @set; my @set;
@ -402,10 +424,12 @@ sub getLineage {
} }
$whereExclusion .= 'and ('.join(" and ",@set).')'; $whereExclusion .= 'and ('.join(" and ",@set).')';
} }
# let's get those siblings
my $whereSiblings; my $whereSiblings;
if (isIn("siblings",@{$relatives})) { if (isIn("siblings",@{$relatives})) {
$whereSiblings = "(parentId=".quote($self->get("parentId"))." and assetId<>".quote($self->getId).")"; $whereSiblings = "(parentId=".quote($self->get("parentId"))." and assetId<>".quote($self->getId).")";
} }
# ancestors too
my @specificFamilyMembers = (); my @specificFamilyMembers = ();
if (isIn("ancestors",@{$relatives})) { if (isIn("ancestors",@{$relatives})) {
my @familyTree = ($lineage =~ /(.{6})/g); my @familyTree = ($lineage =~ /(.{6})/g);
@ -413,6 +437,7 @@ sub getLineage {
push(@specificFamilyMembers,join("",@familyTree)) if (scalar(@familyTree)); push(@specificFamilyMembers,join("",@familyTree)) if (scalar(@familyTree));
} }
} }
# let's add ourself to the list
if (isIn("self",@{$relatives})) { if (isIn("self",@{$relatives})) {
push(@specificFamilyMembers,$self->get("lineage")); push(@specificFamilyMembers,$self->get("lineage"));
} }
@ -425,6 +450,7 @@ sub getLineage {
$whereExact .= quoteAndJoin(\@specificFamilyMembers); $whereExact .= quoteAndJoin(\@specificFamilyMembers);
$whereExact .= ")"; $whereExact .= ")";
} }
# we need to include descendants
my $whereDescendants; my $whereDescendants;
if (isIn("descendants",@{$relatives})) { if (isIn("descendants",@{$relatives})) {
if ($whereSiblings ne "" || $whereExact ne "") { if ($whereSiblings ne "" || $whereExact ne "") {
@ -435,19 +461,32 @@ sub getLineage {
$whereDescendants .= " and length(lineage) <= ".($rules->{endingLineageLength}*6); $whereDescendants .= " and length(lineage) <= ".($rules->{endingLineageLength}*6);
} }
} }
my $columns = "assetId, className"; # based upon all available criteria, let's get some assets
my $columns = "assetId, className, parentId";
$columns = "*" if ($rules->{returnQuickReadObjects}); $columns = "*" if ($rules->{returnQuickReadObjects});
my $sql = "select $columns from asset where $whereSiblings $whereExact $whereDescendants $whereExclusion order by lineage"; my $sql = "select $columns from asset where $whereSiblings $whereExact $whereDescendants $whereExclusion order by lineage";
my @lineage; my @lineage;
my %relativeCache;
my $sth = WebGUI::SQL->read($sql); my $sth = WebGUI::SQL->read($sql);
while (my $properties = $sth->hashRef) { while (my $properties = $sth->hashRef) {
# create whatever type of object was requested
my $asset;
if ($rules->{returnObjects}) { if ($rules->{returnObjects}) {
push(@lineage,WebGUI::Asset->newByDynamicClass($properties->{assetId}, $properties->{className})); $asset = WebGUI::Asset->newByDynamicClass($properties->{assetId}, $properties->{className});
} elsif ($rules->{returnQuickReadObjects}) { } elsif ($rules->{returnQuickReadObjects}) {
push(@lineage,WebGUI::Asset->newByPropertyHashRef($properties)); $asset = WebGUI::Asset->newByPropertyHashRef($properties);
} else { } else {
push(@lineage,$properties->{assetId}); $asset = $properties->{assetId};
} }
# since we have the relatives info now, why not cache it
if ($rules->{returnObjects} || $rules->{returnQuickReadObjects}) {
my $parent = $relativeCache{$properties->{parentId}};
$relativeCache{$properties->{assetId}} = $asset;
$asset->{_parent} = $parent;
$parent->{_firstChild} = $asset unless(exists $parent->{_firstChild});
$parent->{_lastChild} = $asset;
}
push(@lineage,$asset);
} }
$sth->finish; $sth->finish;
return \@lineage; return \@lineage;
@ -525,8 +564,17 @@ sub getValue {
sub hasChildren { sub hasChildren {
my $self = shift; my $self = shift;
my ($hasChildren) = WebGUI::SQL->read("select count(*) from asset where parentId=".quote($self->getId)); unless (exists $self->{_hasChildren}) {
return $hasChildren; if (exists $self->{_firstChild}) {
$self->{_hasChildren} = 1;
} elsif (exists $self->{_lastChild}) {
$self->{_hasChildren} = 1;
} else {
my ($hasChildren) = WebGUI::SQL->read("select count(*) from asset where parentId=".quote($self->getId));
$self->{_hasChildren} = $hasChildren;
}
}
return $self->{_hasChildren};
} }
sub new { sub new {

View file

@ -101,7 +101,7 @@ sub getEditForm {
-value=>'<div id="navStartPoint"></div>' -value=>'<div id="navStartPoint"></div>'
); );
$tabform->getTab("properties")->readOnly( $tabform->getTab("properties")->readOnly(
-label=>"Assets to Include", -label=>"Relatives to Include",
-value=>WebGUI::Form::checkbox({ -value=>WebGUI::Form::checkbox({
checked=>$selfChecked, checked=>$selfChecked,
name=>"assetsToInclude", name=>"assetsToInclude",
@ -124,7 +124,6 @@ sub getEditForm {
value=>"pedigree" value=>"pedigree"
}).'Pedigree<br />' }).'Pedigree<br />'
); );
WebGUI::ErrorHandler::warn($self->getValue("startType"));
my %options; my %options;
tie %options, 'Tie::IxHash'; tie %options, 'Tie::IxHash';
%options = ( %options = (
@ -182,13 +181,13 @@ WebGUI::ErrorHandler::warn($self->getValue("startType"));
changeStartPoint(); changeStartPoint();
toggleEndPoint(); toggleEndPoint();
</script>"); </script>");
my $previewButton = qq{ my $previewButton;# = qq{
<INPUT TYPE="button" VALUE="Preview" NAME="preview" # <INPUT TYPE="button" VALUE="Preview" NAME="preview"
OnClick=" # OnClick="
window.open('', 'navPreview', 'toolbar=no,status=no,location=no,scrollbars=yes,resizable=yes'); # window.open('', 'navPreview', 'toolbar=no,status=no,location=no,scrollbars=yes,resizable=yes');
this.form.func.value='preview'; # this.form.func.value='preview';
this.form.target = 'navPreview'; # this.form.target = 'navPreview';
this.form.submit()">}; # this.form.submit()">};
my $saveButton = ' <input type="button" value="'.WebGUI::International::get(62).'" onClick=" my $saveButton = ' <input type="button" value="'.WebGUI::International::get(62).'" onClick="
this.value=\''.WebGUI::International::get(452).'\'; this.value=\''.WebGUI::International::get(452).'\';
this.form.func.value=\'editSave\'; this.form.func.value=\'editSave\';
@ -207,9 +206,10 @@ sub getName {
sub view { sub view {
my $self = shift; my $self = shift;
# we've got to determine what our start point is based upon user conditions # we've got to determine what our start point is based upon user conditions
my $start; my ($start,$current);
if (!exists $session{asset}) { if (!exists $session{asset}) {
$start = $self; $start = $self;
$current = $self;
} elsif ($self->get("startType") eq "specificUrl") { } elsif ($self->get("startType") eq "specificUrl") {
$start = WebGUI::Asset->getByUrl($self->get("startPoint")); $start = WebGUI::Asset->getByUrl($self->get("startPoint"));
} elsif ($self->get("startType") eq "relativeToRoot") { } elsif ($self->get("startType") eq "relativeToRoot") {
@ -229,190 +229,108 @@ sub view {
$start = WebGUI::Asset->newByLineage($lineage); $start = WebGUI::Asset->newByLineage($lineage);
} }
} }
$current = $session{asset} unless (defined $current);
$start = $session{asset} unless (defined $start); # if none of the above results in a start point, then the current page must be it $start = $session{asset} unless (defined $start); # if none of the above results in a start point, then the current page must be it
my @assets = $start->getLineage(); my @includedRelationships = split("\n",$self->get("assetsToInclude"));
my %rules;
my $config;
my $base;
my (@relatives, %rules);
foreach my $relative ("ancestors","self","siblings","descendants") {
push(@relatives,$relative) if ($config->{relative});
}
$rules{returnQuickReadObjects} = 1; $rules{returnQuickReadObjects} = 1;
$base->getLineage(\@relatives,\%rules); $rules{endingLineageLength} = $start->getLineageLength+$self->get("endPoint");
my @assets = $start->getLineage(\@includedRelationships,\%rules);
my @interestingPageProperties = ('pageId', 'parentId', 'title', 'ownerId', 'urlizedTitle',
'synopsis', 'newWindow', 'menuTitle', 'encryptLogin');
my $var = {'page_loop' => []}; my $var = {'page_loop' => []};
my $p = $self->_getStartPageObject(); my @interestingProperties = ('assetId', 'parentId', 'title', 'ownerUserId', 'synopsis', 'newWindow', 'menuTitle');
my $method = $self->_methods()->{$self->{_method}}{method}; foreach my $property (@interestingProperties) {
$var->{'currentPage.'.$property} = $current->get($property);
my $cache = WebGUI::Cache->new($self->{_identifier}.'-'.$session{page}{pageId}, "Navigation-".$session{config}{configFile}); }
my $cacheContent = $cache->get unless $session{var}{adminOn}; $var->{'currentPage.isHome'} = ($current->getId eq $session{setting}{defaultPage});
my (@page_loop, $lastPage, %unfolded); $var->{'currentPage.url'} = $current->getUrl;
tie %unfolded, "Tie::IxHash"; $var->{'currentPage.hasChild'} = $current->hasChildren;
my $currentLineage = $current->get("lineage");
# Store current page properties in template var my @linesToSkip;
my $currentPage = WebGUI::Page->getPage(); my $absoluteDepthOfLastPage;
my $currentRoot = $currentPage->getWebGUIRoot(); foreach my $asset (@assets) {
foreach my $property (@interestingPageProperties) { # skip pages we shouldn't see
$var->{'basepage.'.$property} = $currentPage->get($property); my $skip = 0;
} my $pageLineage = $asset->get("lineage");
unless (defined $cacheContent && foreach my $lineage (@linesToSkip) {
! $session{url}{siteURL}) { # Never use cache if an alternate site url is specified. $skip = 1 if ($lineage =~ m/^$pageLineage/);
# The loop was not cached
my @pages = eval $method;
if ($@) {
WebGUI::ErrorHandler::warn("Error in WebGUI::Navigation::build while trying to execute $method".$@);
} }
if (@pages) { next if ($skip);
my $startPageDepth = $p->get("depth")+1; if ($asset->get("isHidden") && !$self->get("showHiddenPages")) {
my $maxDepth = $startPageDepth + $self->{_depth}; push (@linesToSkip,$asset->getId);
my $minDepth = $startPageDepth - $self->{_depth}; next;
}
foreach my $page (@pages) { if ($asset->get("isSystem") && !$self->get("showSystemPages")) {
my $pageData = {}; push (@linesToSkip,$asset->getId);
$pageData->{"page.absDepth"} = $page->{'depth'} + 1; next;
$pageData->{"page.isSystem"} = $page->{isSystem}; }
unless ($self->get("showUnprivilegedPages") || $asset->canView) {
# Check if in depth range push (@linesToSkip,$asset->getId);
next if ($pageData->{"page.absDepth"} > $maxDepth || $pageData->{"page.absDepth"} < $minDepth); next;
}
# Check stopAtLevel my $pageData = {};
next if ($pageData->{"page.absDepth"} < $self->{_stopAtLevel}); foreach my $property (@interestingProperties) {
$pageData->{"page.".$property} = $asset->get($property);
# Check showSystemPages }
next if (! $self->{_showSystemPages} && $pageData->{"page.isSystem"}); # build nav variables
$pageData->{"page.absDepth"} = $asset->getLineageLength;
# Deal with hidden pages, don't ever hide pages if admin mode is on $pageData->{"page.relDepth"} = $asset->getLineageLength - $start->getLineageLength;
next if(($page->{'hideFromNavigation'} && ! $self->{_showHiddenPages}) && (! $session{var}{adminOn})); $pageData->{"page.isSystem"} = $asset->get("isSystem");
$pageData->{"page.isHidden"} = $asset->get("isHidden");
# Initial page info $pageData->{"page.isViewable"} = $asset->canView;
$pageData->{"page.url"} = WebGUI::URL::gateway($page->{'urlizedTitle'}); $pageData->{"page.url"} = $asset->getUrl;
if ($page->{'encryptPage'}) { my $indent = $pageData->{"page.relDepth"};
$pageData->{"page.url"} =~ s/http:/https:/; $pageData->{"page.indent_loop"} = [];
} push(@{$pageData->{"page.indent_loop"}},{'indent'=>$_}) for(1..$indent);
$pageData->{"page.relDepth"} = $pageData->{"page.absDepth"} - $startPageDepth; $pageData->{"page.indent"} = "&nbsp;&nbsp;&nbsp;" x $indent;
$pageData->{"page.isBasepage"} = ($page->{'pageId'} eq $session{page}{pageId}); $pageData->{"page.isBranchRoot"} = ($pageData->{"page.absDepth"} == 1);
$pageData->{"page.isHidden"} = $page->{'hideFromNavigation'}; $pageData->{"page.isTopOfBranch"} = ($pageData->{"page.absDepth"} == 2);
$pageData->{"page.isChild"} = ($asset->get("parentId") eq $current->getId);
# indent $pageData->{"page.isParent"} = ($asset->getId eq $current->get("parentId"));
my $indent = 0; $pageData->{"page.isCurrent"} = ($asset->getId eq $current->getId);
if ($self->{_method} eq 'pedigree' # reverse traversing $pageData->{"page.isDescendant"} = ( $currentLineage =~ m/^$pageLineage/ && !$pageData->{"page.isCurrent"});
|| $self->{_method} eq 'ancestors' # needs another way to calculate $pageData->{"page.isAnscestor"} = ( $pageLineage =~ m/^$currentLineage/ && !$pageData->{"page.isCurrent"});
|| $self->{_method} eq 'self_and_ancestors') { # the indent $pageData->{"page.isSibling"} = (
if ($self->{_stopAtLevel} <= $startPageDepth && $self->{_stopAtLevel} > 0) { $pageData->{"page.inBranchRoot"} &&
$indent = $pageData->{"page.absDepth"} - ($self->{_stopAtLevel} - 1) - 1; $asset->getLineageLength == $current->getLineageLength &&
} elsif ($self->{_stopAtLevel} > $startPageDepth && $self->{_stopAtLevel} > 0) { !$pageData->{"page.isCurrent"}
$indent = 0; );
} else { my $currentBranchLineage = substr($currentLineage,0,12);
$indent = $pageData->{"page.absDepth"} - 1; $pageData->{"page.inBranchRoot"} = ($currentBranchLineage =~ m/^$pageLineage/);
} $pageData->{"page.inBranch"} = (
} else { $pageData->{"page.isCurrent"} ||
$indent = $pageData->{"page.absDepth"} - $startPageDepth - 1; $pageData->{"page.isAncestor"} ||
} $pageData->{"page.isSibling"} ||
$pageData->{"page.indent_loop"} = []; $pageData->{"page.isDescendant"}
push(@{$pageData->{"page.indent_loop"}},{'indent'=>$_}) for(1..$indent); );
$pageData->{"page.indent"} = "&nbsp;&nbsp;&nbsp;" x $indent; $pageData->{"page.depthIs".$pageData->{"page.absDepth"}} = 1;
$pageData->{"page.relativeDepthIs".$pageData->{"page.relDepth"}} = 1;
# Put page properties in $pageData hashref my $depthDiff = ($absoluteDepthOfLastPage) ? ($absoluteDepthOfLastPage - $pageData->{'page.absDepth'}) : 0;
foreach my $property (@interestingPageProperties) { if ($depthDiff > 0) {
$pageData->{"page.".$property} = $page->{$property}; $pageData->{"page.depthDiff"} = $depthDiff if ($depthDiff > 0);
} $pageData->{"page.depthDiffIs".$depthDiff} = 1;
$pageData->{"page.isRoot"} = (! $page->{'parentId'}); push(@{$pageData->{"page.depthDiff_loop"}},{}) for(1..$depthDiff);
$pageData->{"page.isTop"} = ($pageData->{"page.absDepth"} == 2); }
$pageData->{"page.hasDaughter"} = ($page->{'nestedSetRight'} - $page->{'nestedSetLeft'} > 1); $absoluteDepthOfLastPage = $pageData->{"page.absDepth"};
$pageData->{"page.isDaughter"} = ($page->{'parentId'} eq $currentPage->get('pageId')); my $parent = $self->getParent;
$pageData->{"page.isMother"} = ($page->{'pageId'} eq $currentPage->get('parentId')); if (defined $parent) {
foreach my $property (@interestingProperties) {
$pageData->{"page.isAncestor"} $pageData->{"page.parent.".$property} = $parent->get($property);
= (($page->{'nestedSetLeft'} < $currentPage->get('nestedSetLeft'))
&& ($page->{'nestedSetRight'} > $currentPage->get('nestedSetRight')));
$pageData->{"page.isDescendent"}
= (($page->{'nestedSetLeft'} > $currentPage->get('nestedSetLeft'))
&& ($page->{'nestedSetRight'} < $currentPage->get('nestedSetRight')));
$pageData->{"page.inRoot"}
= (($page->{'nestedSetLeft'} > $currentRoot->get('nestedSetLeft'))
&& ($page->{'nestedSetRight'} < $currentRoot->get('nestedSetRight')));
# Some information about my mother
my $mother = WebGUI::Page->getPage($page->{parentId});
if ($page->{parentId} ne "0") {
foreach (qw(title urlizedTitle parentId pageId)) {
$pageData->{"page.mother.$_"} = $mother->get($_);
}
$pageData->{"page.isSister"}
= (($mother->get("pageId") eq $currentPage->get("parentId"))
&& !$pageData->{"page.isBasepage"});
}
$pageData->{"page.inBranch"}
= ($pageData->{"page.isAncestor"}
|| $pageData->{"page.isDescendent"}
|| $pageData->{"page.isSister"}
|| $pageData->{"page.isBasepage"});
$pageData->{"page.isLeftMost"} = (($page->{'nestedSetLeft'} - 1) == $mother->get('nestedSetLeft'));
$pageData->{"page.isRightMost"} = (($page->{'nestedSetRight'} + 1) == $mother->get('nestedSetRight'));
my $depthDiff = ($lastPage) ? ($lastPage->{'page.absDepth'} - $pageData->{'page.absDepth'}) : 0;
if ($depthDiff > 0) {
$pageData->{"page.depthDiff"} = $depthDiff if ($depthDiff > 0);
$pageData->{"page.depthDiffIs".$depthDiff} = 1;
push(@{$pageData->{"page.depthDiff_loop"}},{}) for(1..$depthDiff);
}
# Some information about my depth
$pageData->{"page.depthIs".$pageData->{"page.absDepth"}} = 1;
$pageData->{"page.relativeDepthIs".$pageData->{"page.relDepth"}} = 1;
# We need a copy of the last page for the depthDiffLoop
$lastPage = $pageData;
# Store $pageData in page_loop. Mind the order.
if ($self->{_reverse}) {
unshift(@page_loop, $pageData);
} else {
push(@page_loop, $pageData);
}
} }
$pageData->{"page.parent.url"} = $parent->getUrl;
} }
$pageData->{"page.hasChild"} = $asset->hasChildren;
# We had a cache miss, so let's put the data in cache # these next two variables can be very inefficient, consider getting rid of them
$cache->set(\@page_loop, 3600*24) unless $session{var}{adminOn}; my $parentsFirstChild = $parent->getFirstChild;
} else { if (defined $parentsFirstChild) {
# We had a cache hit $pageData->{"page.isRankedFirst"} = ($asset->getId == $parentsFirstChild->getId);
@page_loop = @{$cacheContent};
}
# Do the user-dependent checks (which cannot be cached globally)
foreach my $pageData (@page_loop) {
$pageData->{"page.isViewable"} = WebGUI::Page::canView($pageData->{'page.pageId'});
# Check privileges
if ($pageData->{"page.isViewable"} || $self->{_showUnprivilegedPages}) {
push (@{$var->{page_loop}}, $pageData);
push (@{$unfolded{$pageData->{"page.parentId"}}}, $pageData);
} }
my $parentsLastChild = $parent->getLastChild;
if (defined $parentsLastChild) {
$pageData->{"page.isRankedLast"} = ($asset->getId == $parentsLastChild->getId);
}
push(@{$var->{page_loop}}, $pageData);
} }
return $self->processTemplate($var,"Navigation",$self->get("templateId"));
foreach (values %unfolded) {
push(@{$var->{unfolded_page_loop}}, @{$_});
}
# Configure button
$var->{'config.button'} = $self->_getEditButton();
# Some properties of the page the user's viewing.
$var->{'basepage.hasDaughter'} = $currentPage->hasDaughter();
$var->{"basepage.isHome"} = ($currentPage->get('pageId') eq '1');
if ($self->{_template}) {
return WebGUI::Template::processRaw($self->{_template}, $var);
} else {
return WebGUI::Template::process($self->{_templateId}, "Navigation", $var);
}
} }
@ -425,6 +343,7 @@ sub www_edit {
#------------------------------------------------------------------- #-------------------------------------------------------------------
# we eventually should reaadd this
sub www_preview { sub www_preview {
my $self = shift; my $self = shift;
$session{var}{adminOn} = 0; $session{var}{adminOn} = 0;

View file

@ -241,7 +241,7 @@ sub checkList {
sub codearea { sub codearea {
my $params = shift; my $params = shift;
WebGUI::Style::setScript($session{config}{extrasURL}.'/TabFix.js',{type=>"text/javascript"}); WebGUI::Style::setScript($session{config}{extrasURL}.'/TabFix.js',{type=>"text/javascript"});
$params->{extras} = 'style="width: 99%; min-width: 440px; height: 400px" onkeypress="TabFix_keyPress(event.type)" onkeydown="TabFix_keyDown(event.type)"'; $params->{extras} = 'style="width: 99%; min-width: 440px; height: 400px" onkeypress="return TabFix_keyPress(event)" onkeydown="return TabFix_keyDown(event)"';
my $output = textarea($params); my $output = textarea($params);
return $output; return $output;
} }

View file

@ -82,17 +82,15 @@ the Navigation Template to determine who can see them in the menu.</P>
}, },
'1097' => { '1097' => {
message => q|<STRONG>config.button</STRONG>&nbsp;<BR>A "Edit / Manage" button for this navigation item.<BR> message => q| <P><STRONG>currentPage.menuTitle</STRONG><BR>The pageId of the base page.</P>
<P><STRONG>basepage.menuTitle</STRONG><BR>The pageId of the base page.</P> <P><STRONG>currentPage.title</STRONG><BR>The title of the base page.</P>
<P><STRONG>basepage.title</STRONG><BR>The title of the base page.</P> <P><STRONG>currentPage.url</STRONG><BR>The URL of the base page.</P>
<P><STRONG>basepage.urlizedTitle</STRONG><BR>The URL of the base page.</P> <P><STRONG>currentPage.assetId</STRONG><BR>The pageId of the base page.</P>
<P><STRONG>basepage.pageId</STRONG><BR>The pageId of the base page.</P> <P><STRONG>currentPage.parentId</STRONG><BR>The parentId of the base page.</P>
<P><STRONG>basepage.parentId</STRONG><BR>The parentId of the base page.</P> <P><STRONG>currentPage.ownerUserId</STRONG><BR>The ownerId of the base page.</P>
<P><STRONG>basepage.ownerId</STRONG><BR>The ownerId of the base page.</P> <P><STRONG>currentPage.synopsis</STRONG><BR>The synopsis of the base page.</P>
<P><STRONG>basepage.synopsis</STRONG><BR>The synopsis of the base page.</P> <P><STRONG>currentPage.newWindow</STRONG><BR>A conditional indicating whether the base page should be opened in a new window.</P>
<P><STRONG>basepage.newWindow</STRONG><BR>A conditional indicating whether the base page should be opened in a new window.</P> <P><STRONG>currentPage.hasChild</STRONG><BR>A conditional indicating whether the base page has daughters.</P>
<P><STRONG>basepage.encryptLogin</STRONG><BR>A conditional indicating whether the base page should be served over SSL.</P>
<P><STRONG>basepage.hasDaughter</STRONG><BR>A conditional indicating whether the base page has daughters.</P>
<P><STRONG>page_loop</STRONG><BR>A loop containing page information in nested, hierarchical order.</P> <P><STRONG>page_loop</STRONG><BR>A loop containing page information in nested, hierarchical order.</P>
<P><STRONG>unfolded_page_loop</STRONG><BR>This loop contains the same data as <STRONG>page_loop</STRONG> but the order is different. <STRONG>unfolded_page_loop</STRONG> returns it's pages in an unfolded manner; grouped by parent id. You'll probably need <STRONG>page_loop</STRONG>, but there are (CSS) menus that need <STRONG>unfolded_page_loop</STRONG> to work properly.</P> <P><STRONG>unfolded_page_loop</STRONG><BR>This loop contains the same data as <STRONG>page_loop</STRONG> but the order is different. <STRONG>unfolded_page_loop</STRONG> returns it's pages in an unfolded manner; grouped by parent id. You'll probably need <STRONG>page_loop</STRONG>, but there are (CSS) menus that need <STRONG>unfolded_page_loop</STRONG> to work properly.</P>
<p>Both <STRONG>page_loop</STRONG> and <STRONG>unfolded_page_loop</STRONG> have the following <p>Both <STRONG>page_loop</STRONG> and <STRONG>unfolded_page_loop</STRONG> have the following
@ -100,14 +98,12 @@ loop variables:</p>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"> <BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P dir=ltr><STRONG>page.menuTitle</STRONG><BR>The menu title of this page.</P> <P dir=ltr><STRONG>page.menuTitle</STRONG><BR>The menu title of this page.</P>
<P dir=ltr><STRONG>page.title</STRONG><BR>The title of this page.</P> <P dir=ltr><STRONG>page.title</STRONG><BR>The title of this page.</P>
<P dir=ltr><STRONG>page.urlizedTitle</STRONG><BR>The urlizedTitle of this page.</P>
<P dir=ltr><STRONG>page.url</STRONG><BR>The complete URL to this page.</P> <P dir=ltr><STRONG>page.url</STRONG><BR>The complete URL to this page.</P>
<P dir=ltr><STRONG>page.pageId</STRONG><BR>The pageId of this page.</P> <P dir=ltr><STRONG>page.assetId</STRONG><BR>The pageId of this page.</P>
<P dir=ltr><STRONG>page.parentId</STRONG><BR>The parentId of this page.</P> <P dir=ltr><STRONG>page.parentId</STRONG><BR>The parentId of this page.</P>
<P dir=ltr><STRONG>page.ownerId</STRONG><BR>The ownerId of this page.</P> <P dir=ltr><STRONG>page.ownerUserId</STRONG><BR>The ownerId of this page.</P>
<P dir=ltr><STRONG>page.synopsis</STRONG><BR>The synopsis of this page.</P> <P dir=ltr><STRONG>page.synopsis</STRONG><BR>The synopsis of this page.</P>
<P dir=ltr><STRONG>page.newWindow</STRONG><BR>A conditional indicating whether this page should be opened in a new window.</P> <P dir=ltr><STRONG>page.newWindow</STRONG><BR>A conditional indicating whether this page should be opened in a new window.</P>
<P dir=ltr><STRONG>page.encryptLogin</STRONG><BR>A conditional indicating whether this page should be served over SSL.</P>
<P dir=ltr><STRONG>page.absDepth</STRONG><BR>The absolute depth of this page&nbsp;(relative to nameless root).</P> <P dir=ltr><STRONG>page.absDepth</STRONG><BR>The absolute depth of this page&nbsp;(relative to nameless root).</P>
<P><STRONG>page.relDepth</STRONG><BR>The relative depth of this page (relative to starting point).</P> <P><STRONG>page.relDepth</STRONG><BR>The relative depth of this page (relative to starting point).</P>
<P><STRONG>page.isHidden</STRONG><BR>A conditional indicating whether this page is a hidden page.<BR><EM>(Note: This variable is only visible if "Show hidden pages" is switched on.)</EM></P> <P><STRONG>page.isHidden</STRONG><BR>A conditional indicating whether this page is a hidden page.<BR><EM>(Note: This variable is only visible if "Show hidden pages" is switched on.)</EM></P>
@ -117,27 +113,27 @@ loop variables:</p>
<P><STRONG>page.indent_loop</STRONG><BR>A loop that runs <STRONG>page.relDepth</STRONG> times.</P> <P><STRONG>page.indent_loop</STRONG><BR>A loop that runs <STRONG>page.relDepth</STRONG> times.</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"> <BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P><STRONG>indent</STRONG><BR>A number representing the loop count. </P></BLOCKQUOTE> <P><STRONG>indent</STRONG><BR>A number representing the loop count. </P></BLOCKQUOTE>
<P dir=ltr><STRONG>page.isRoot</STRONG><BR>A conditional indicating whether this page is a root page.</P> <P dir=ltr><STRONG>page.isBranchRoot</STRONG><BR>A conditional indicating whether this page is a root page.</P>
<P dir=ltr><STRONG>page.isTop</STRONG><BR>A conditional indicating whether this page is a top page (daughter of root).</P> <P dir=ltr><STRONG>page.isTopOfBranch</STRONG><BR>A conditional indicating whether this page is a top page (daughter of root).</P>
<P dir=ltr><STRONG>page.inRoot</STRONG><BR>This conditional is true if this page is a descendant of the root page of the base page.</P> <P dir=ltr><STRONG>page.inBranchRoot</STRONG><BR>This conditional is true if this page is a descendant of the root page of the base page.</P>
<P dir=ltr><STRONG>page.hasDaughter</STRONG><BR>A conditional indicating whether this page has a daughter. In other words: It evaluates to true if this page is a mother.</P> <P dir=ltr><STRONG>page.hasChild</STRONG><BR>A conditional indicating whether this page has a daughter. In other words: It evaluates to true if this page is a mother.</P>
<P dir=ltr><STRONG>page.isBasepage</STRONG><BR>A conditional indicating whether this page is the base page.</P> <P dir=ltr><STRONG>page.isCurrent</STRONG><BR>A conditional indicating whether this page is the base page.</P>
<P dir=ltr><STRONG>page.isAncestor</STRONG><BR>A conditional indicating whether this page is an ancestor of the base page.</P> <P dir=ltr><STRONG>page.isAncestor</STRONG><BR>A conditional indicating whether this page is an ancestor of the base page.</P>
<P dir=ltr><STRONG>page.isDescendent</STRONG><BR>A conditional indicating whether this page is a descendant of the base page.</P> <P dir=ltr><STRONG>page.isDescendent</STRONG><BR>A conditional indicating whether this page is a descendant of the base page.</P>
<P dir=ltr><STRONG>page.isDaughter</STRONG><BR>A conditional indicating whether this page is a daughter of the base page.</P> <P dir=ltr><STRONG>page.isChild</STRONG><BR>A conditional indicating whether this page is a daughter of the base page.</P>
<P dir=ltr><STRONG>page.isMother</STRONG><BR>A conditional indicating whether this page is the mother of the base page.</P> <P dir=ltr><STRONG>page.isParent</STRONG><BR>A conditional indicating whether this page is the mother of the base page.</P>
<P dir=ltr><STRONG>page.isSister</STRONG><BR>A conditional indicating whether this page is the sister of the base page.</P> <P dir=ltr><STRONG>page.isSibling</STRONG><BR>A conditional indicating whether this page is the sister of the base page.</P>
<P dir=ltr><STRONG>page.inBranch</STRONG><BR>A conditional that is the logical OR of <STRONG>isAncestor</STRONG>, <STRONG>isSister</STRONG>, <STRONG>isBasepage</STRONG> and <STRONG>isDescendent</STRONG>.</P> <P dir=ltr><STRONG>page.inBranch</STRONG><BR>A conditional that is the logical OR of <STRONG>isAncestor</STRONG>, <STRONG>isSister</STRONG>, <STRONG>isBasepage</STRONG> and <STRONG>isDescendent</STRONG>.</P>
<P dir=ltr><STRONG>page.mother.*</STRONG><BR>These variables will be undefined if the page is a root.</P> <P dir=ltr><STRONG>page.parent.*</STRONG><BR>These variables will be undefined if the page is a root.</P>
<P dir=ltr><STRONG>page.mother.title</STRONG><BR>The title of the mother of this page.</P> <P dir=ltr><STRONG>page.parent.title</STRONG><BR>The title of the mother of this page.</P>
<P dir=ltr><STRONG>page.mother.urlizedTitle</STRONG><BR>The urlized title of the mother of this page.</P> <P dir=ltr><STRONG>page.parent.url</STRONG><BR>The urlized title of the mother of this page.</P>
<P dir=ltr><STRONG>page.mother.pageId</STRONG><BR>The pageId of the mother of this page.</P> <P dir=ltr><STRONG>page.parent.assetId</STRONG><BR>The pageId of the mother of this page.</P>
<P dir=ltr><STRONG>page.mother.parentId</STRONG><BR>The parentId of the mother of this page.</P> <P dir=ltr><STRONG>page.parent.parentId</STRONG><BR>The parentId of the mother of this page.</P>
<P dir=ltr><STRONG>page.depthIs1 , page.depthIs2 , page.depthIs3 , page.depthIs4 , page.depthIsN<BR></STRONG>A conditional indicating whether the depth of this page is N. This variable is useful if you want to style a certain level.</P> <P dir=ltr><STRONG>page.depthIs1 , page.depthIs2 , page.depthIs3 , page.depthIs4 , page.depthIsN<BR></STRONG>A conditional indicating whether the depth of this page is N. This variable is useful if you want to style a certain level.</P>
<P dir=ltr>&lt;tmpl_if page.depthIs1&gt;<BR>&nbsp;&nbsp; &lt;img src="level1.gif"&gt;<BR>&lt;tmpl_else&gt;<BR>&nbsp;&nbsp; &lt;img src="defaultBullet.gif"&gt;<BR>&lt;/tmpl_if&gt;</P> <P dir=ltr>&lt;tmpl_if page.depthIs1&gt;<BR>&nbsp;&nbsp; &lt;img src="level1.gif"&gt;<BR>&lt;tmpl_else&gt;<BR>&nbsp;&nbsp; &lt;img src="defaultBullet.gif"&gt;<BR>&lt;/tmpl_if&gt;</P>
<P dir=ltr><STRONG>page.relativeDepthIs1 , page.relativeDepthIs2 , page.relativeDepthIs3 , page.relativeDepthIsN</STRONG><BR>A conditional indicating whether the relative depth of this page is N.</P> <P dir=ltr><STRONG>page.relativeDepthIs1 , page.relativeDepthIs2 , page.relativeDepthIs3 , page.relativeDepthIsN</STRONG><BR>A conditional indicating whether the relative depth of this page is N.</P>
<P dir=ltr><STRONG>page.isLeftMost</STRONG><BR>This property is true if this page is the first within this level. Ie. has no left sister.</P> <P dir=ltr><STRONG>page.isRankedFirst</STRONG><BR>This property is true if this page is the first within this level. Ie. has no left sister.</P>
<P dir=ltr><STRONG>page.isRightMost</STRONG><BR>This property is true if this page is the last within this level. Ie. has no right sister.</P> <P dir=ltr><STRONG>page.isRankedLast</STRONG><BR>This property is true if this page is the last within this level. Ie. has no right sister.</P>
<P dir=ltr><STRONG>page.depthDiff</STRONG><BR>The difference in depth of this page and the page processed before it. This only has a value when you go up in depth. If you go down, this would be always 1 and going down a level can be detected with <STRONG>page.isLeftMost</STRONG>.</P> <P dir=ltr><STRONG>page.depthDiff</STRONG><BR>The difference in depth of this page and the page processed before it. This only has a value when you go up in depth. If you go down, this would be always 1 and going down a level can be detected with <STRONG>page.isLeftMost</STRONG>.</P>
<P dir=ltr><STRONG>page.depthDiffIs1, page.depthDiffIs2, page.depthDiffIs3, page.depthDiffIsN</STRONG><BR>True if the <STRONG>page.depthDiff</STRONG> variable is N.</P> <P dir=ltr><STRONG>page.depthDiffIs1, page.depthDiffIs2, page.depthDiffIs3, page.depthDiffIsN</STRONG><BR>True if the <STRONG>page.depthDiff</STRONG> variable is N.</P>
<P dir=ltr><STRONG>page.depthDiff_loop</STRONG><BR>A loop that runs <STRONG>page.depthDiff</STRONG> times. This loop contains no loop variables.</P></BLOCKQUOTE> <P dir=ltr><STRONG>page.depthDiff_loop</STRONG><BR>A loop that runs <STRONG>page.depthDiff</STRONG> times. This loop contains no loop variables.</P></BLOCKQUOTE>