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

@ -26,6 +26,7 @@ sub addChild {
my $properties = shift;
my $id = WebGUI::Id::generate();
my $lineage = $self->get("lineage").$self->getNextChildRank;
$self->{_hasChildren} = 1;
WebGUI::SQL->beginTransaction;
WebGUI::SQL->write("insert into asset (assetId, parentId, lineage, state, className, url, startDate, endDate)
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 {
my $self = shift;
my $newAsset = $self->addChild($self->get);
@ -357,10 +366,13 @@ sub getEditForm {
}
sub getFirstDescendant {
sub getFirstChild {
my $self = shift;
$self->{_firstDescendant} = WebGUI::Asset->newByLineage($self->get("lineage").$self->formatRank(1)) unless (exists $self->{_firstDescendant});
return $self->{_firstDescendant};
unless (exists $self->{_firstChild}) {
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 {
@ -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 {
my $self = shift;
my $relatives = shift;
my $rules = shift;
my $lineage = $self->get("lineage");
# deal with exclusions
my $whereExclusion = " and state='published'";
if (exists $rules->{excludeClasses}) {
my @set;
@ -402,10 +424,12 @@ sub getLineage {
}
$whereExclusion .= 'and ('.join(" and ",@set).')';
}
# let's get those siblings
my $whereSiblings;
if (isIn("siblings",@{$relatives})) {
$whereSiblings = "(parentId=".quote($self->get("parentId"))." and assetId<>".quote($self->getId).")";
}
# ancestors too
my @specificFamilyMembers = ();
if (isIn("ancestors",@{$relatives})) {
my @familyTree = ($lineage =~ /(.{6})/g);
@ -413,6 +437,7 @@ sub getLineage {
push(@specificFamilyMembers,join("",@familyTree)) if (scalar(@familyTree));
}
}
# let's add ourself to the list
if (isIn("self",@{$relatives})) {
push(@specificFamilyMembers,$self->get("lineage"));
}
@ -425,6 +450,7 @@ sub getLineage {
$whereExact .= quoteAndJoin(\@specificFamilyMembers);
$whereExact .= ")";
}
# we need to include descendants
my $whereDescendants;
if (isIn("descendants",@{$relatives})) {
if ($whereSiblings ne "" || $whereExact ne "") {
@ -435,19 +461,32 @@ sub getLineage {
$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});
my $sql = "select $columns from asset where $whereSiblings $whereExact $whereDescendants $whereExclusion order by lineage";
my @lineage;
my %relativeCache;
my $sth = WebGUI::SQL->read($sql);
while (my $properties = $sth->hashRef) {
# create whatever type of object was requested
my $asset;
if ($rules->{returnObjects}) {
push(@lineage,WebGUI::Asset->newByDynamicClass($properties->{assetId}, $properties->{className}));
$asset = WebGUI::Asset->newByDynamicClass($properties->{assetId}, $properties->{className});
} elsif ($rules->{returnQuickReadObjects}) {
push(@lineage,WebGUI::Asset->newByPropertyHashRef($properties));
$asset = WebGUI::Asset->newByPropertyHashRef($properties);
} 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;
return \@lineage;
@ -525,8 +564,17 @@ sub getValue {
sub hasChildren {
my $self = shift;
my ($hasChildren) = WebGUI::SQL->read("select count(*) from asset where parentId=".quote($self->getId));
return $hasChildren;
unless (exists $self->{_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 {

View file

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

View file

@ -241,7 +241,7 @@ sub checkList {
sub codearea {
my $params = shift;
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);
return $output;
}

View file

@ -82,17 +82,15 @@ the Navigation Template to determine who can see them in the menu.</P>
},
'1097' => {
message => q|<STRONG>config.button</STRONG>&nbsp;<BR>A "Edit / Manage" button for this navigation item.<BR>
<P><STRONG>basepage.menuTitle</STRONG><BR>The pageId of the base page.</P>
<P><STRONG>basepage.title</STRONG><BR>The title of the base page.</P>
<P><STRONG>basepage.urlizedTitle</STRONG><BR>The URL of the base page.</P>
<P><STRONG>basepage.pageId</STRONG><BR>The pageId of the base page.</P>
<P><STRONG>basepage.parentId</STRONG><BR>The parentId of the base page.</P>
<P><STRONG>basepage.ownerId</STRONG><BR>The ownerId of the base page.</P>
<P><STRONG>basepage.synopsis</STRONG><BR>The synopsis of the base page.</P>
<P><STRONG>basepage.newWindow</STRONG><BR>A conditional indicating whether the base page should be opened in a new window.</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>
message => q| <P><STRONG>currentPage.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>currentPage.url</STRONG><BR>The URL of the base page.</P>
<P><STRONG>currentPage.assetId</STRONG><BR>The pageId of the base page.</P>
<P><STRONG>currentPage.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>currentPage.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>currentPage.hasChild</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>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
@ -100,14 +98,12 @@ loop variables:</p>
<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.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.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.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.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><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>
@ -117,27 +113,27 @@ loop variables:</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">
<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.isTop</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.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.isBasepage</STRONG><BR>A conditional indicating whether this page is the base 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.isTopOfBranch</STRONG><BR>A conditional indicating whether this page is a top page (daughter of root).</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.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.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.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.isMother</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.isChild</STRONG><BR>A conditional indicating whether this page is a daughter 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.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.mother.*</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.mother.urlizedTitle</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.mother.parentId</STRONG><BR>The parentId of the mother of this page.</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.parent.title</STRONG><BR>The 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.parent.assetId</STRONG><BR>The pageId 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>&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.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.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.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.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.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>