Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Category Tree

Quote Reply
Category Tree
on nph-build.cgi...
Code:
sub build_category_tree {
# --------------------------------------------------------
# Creates the home page.
#
my ($s, $e, $f, $ids, $sth, $tmp, $cat_r, $cat, $category);

$USE_HTML ?
print "Building <a href='$LINKS{build_tree_url}/$LINKS{build_index}' target='_blank'>Tree</a> ... \n" :
print "Building Tree ... \n";
$s = time();

($LINKS{build_tree_path} =~ m,^$LINKS{build_root_path}/(.*)$,) and &build_dir ($1);

# Get the list of root categories and build the home page.
$sth = $CATDB->prepare (qq!select * FROM Category ORDER BY Name!);
$sth->execute();
if ($sth->rows) {
while ($tmp = $sth->fetchrow_hashref) {
$cat_r->{$tmp->{Name}} = $tmp;
}
}
else { $cat_r = undef; }

print "\tSubcategories: ", ($sth->rows &#0124; &#0124; 0), "\n";
print "\tOpening page: $LINKS{build_tree_path}/$LINKS{build_index}\n";

open (HOME, ">$LINKS{build_tree_path}/$LINKS{build_index}") or die "unable to open home page: $LINKS{build_tree_path}/$LINKS{build_index}. Reason: $!";
$category = &site_html_print_tree ($cat_r) if ($cat_r);
print HOME &site_html_tree ( { category => $category } );
close HOME;
print "\tClosing page.\n";

$f = time();
$e = $f - $s;
print "Done ($e s)\n\n";
}

on HTML_Template.pm
Code:
sub site_html_tree {
# --------------------------------------------------------
# This routine will build a home page. It is not meant to have any
# links on it, only subcategories.
#
my ($tags, $dynamic) = @_;
my $template = defined $dynamic ? $dynamic->param('t') : undef;
(ref $tags eq 'HASH') or croak "HTML_TEMPLATES: Argument '$tags' must be hash reference";

defined $dynamic and &load_user ($dynamic, $tags);
my $output = &load_template ('tree.html', {
%$tags,
%GLOBALS
}, undef, $template);
defined $dynamic and &clean_output($dynamic, \$output);
return $output;
}

sub site_html_print_tree {
# --------------------------------------------------------
# This routine determines how the list of categories will look.
# We now use a table to split the category name up into two columns.
# For each category you can use the following variables:
#
# $url : The URL to go to that category
# $category_name : The category name with _ and / removed.
# $category_descriptions{$subcat}: The category description (if any).
# $numlinks : The number of links inside that category (and subcategories).
# $mod : The newest link inside of that category.
#
my ($subcat, $dynamic) = @_;
my $template = defined $dynamic ? $dynamic->param('t') : undef;
my @names = keys %{$subcat};

my ($output, $category_name, $category_url, $i, $j, $cat, $cat_r, @subnames, @categorylist,
$depth_new, $depth_old, $links, $size, $last, $invisible);

foreach $cat (sort @names) {
$cat_r = $subcat->{$cat};

# Get the URL and the Category name.
$category_url = $LINKS{build_root_url} . "/" . &build_clean_name ($cat_r->{Name}) . "/";
($cat_r->{Name} =~ m,.*/([^/]+)$,) ? ($category_name = $1) : ($category_name = $cat_r->{Name});
$cat_r->{Short_Name} = $category_name;
$cat_r->{URL} = $category_url;
@categorylist = split (/\//, $cat);
defined $dynamic and &load_user ($dynamic, $cat_r);

$depth_new = $#categorylist;
$last = pop @categorylist;
$links = "";

$invisible = undef if ($invisible >= $depth_new);
$invisible = $depth_new if ($cat_r->{Hidden} eq "Yes"); # if the main category is invisible, we must consider that
# all other suvcategories must be the same also if they are not.

for ($j=0; $j < $depth_new; $j++)
{ $links .= qq~ ~; }

SWITCH: {
($depth_new == 0) and $size = 4;
($depth_new == 1) and $size = 3;
($depth_new == 2) and $size = 2;
($depth_new >= 3) and $size = 1;
}

$links .= &load_template ('categorytree.html', {
%$cat_r,
size => $size,
}, undef, $template);

$output .= $links if (!$invisible); # an hidden category??? skip!
$depth_old = $depth_new;
}
return $output;
}

finally, create a template named tree.html and another named categorytree.html as this...
Code:
<strong><a class="link" href="<%URL%>"><font size="<%size%>"><%Short_Name%></font></a></strong> <small><class="numlinks">(<%Number_of_Links%> )</small>
<%if Has_New_Links eq 'Yes'%><small><sup class="new">new</sup></small><%endif%>
<%if Has_Changed_Links eq 'Yes'%><small><sup class="new">update</sup></small><%endif%>
<br>

also on Links.pm must add..
Code:
# The map tree name.
$LINKS{build_tree_path} = "$LINKS{build_root_path}/Mappa";
$LINKS{build_tree_url} = "$LINKS{build_root_url}/Mappa";

this mod don't support dynamic system. You sould do some minor implementation, not so hard to do. If some of you needs help about it just write me a note.

hope that helps


cheers

lepo
Quote Reply
Re: Category Tree In reply to
Pretty good Lepo! You might also want to look at the CategoryHeiarchy table which looks like:

CREATE TABLE CategoryHierarchy (
CategoryID INT UNSIGNED NOT NULL,
SubCategoryID INT UNSIGNED NOT NULL,
Depth TINYINT UNSIGNED NOT NULL DEFAULT 1,

INDEX catndx (CategoryID, Depth)
)

To grab the root level categories you do:

SELECT Category.*
FROM Category, CategoryHierarchy as Tree
WHERE Tree.CategoryID = 0 AND Tree.SubCategoryID = Category.ID

Then to find a list of subcategories underneath a given category id:

SELECT Category.*
FROM Category, CategoryHierarchy as Tree
WHERE Tree.CategoryID = ? AND
Tree.Depth < ? AND
Tree.SubCategoryID = Category.ID

You set the first quetsion mark to the category id you are interested in, and the second to how many levels deep you want (so if you only want to see three levels down, set depth < 4. Remove that condition to see all the levels.

Cheers,

Alex