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

mod - Top-level categories in <%include%> file

Quote Reply
mod - Top-level categories in <%include%> file
This is a mod to place the TOP LEVEL categories on any page you want, using an <%include%> file. The file is built during the nph-build process, and is then available to all the templates during the build, and to any of the .cgi scripts later on.

This came out of a thread that asked about category names in the links, then I wanted to see if I could join the CategoryHierarchy and Category tables, then do something useful with it. This is the result.

If someone wants to generalize this to make an include for each level of the site, feel free <G> That was _not_ my goal, and I am _not_ of the mind to do it. Really.

Feel free to use this, rewrite this, modify it, or whatever you want.

It works on my site, and other sites, uses no "new" or "site-specific" variables, and modifies no existing routines (it just adds one to each of the HTML_Templates.pm and nph-build.cgi files).

If this mod has already been done, well, I did it again <G>


Make sure to add -- &build_category_sidebar(); to the top of the nph-build.cgi file, _BEFORE_ any of the other "build" routines are called. This will write out the file so it can be included.

Add this to the bottom of nph-build.cgi, just above the 1;

sub build_category_sidebar {

# Creates an include file for the sidebar on all the pages.
my ($s, $e, $f, $sth, $link, $category, $category_clean, %link_output);
my ($total, $link_results, $title_linked, $percent);
my $cat_name;
my $category_sidebar;

# Get all the top level links
$sth = $LINKDB->prepare (qq!
select Category.Name
from CategoryHierarchy, Category
where Depth=0 and CategoryHierarchy.SubCategoryID=Category.ID
ORDER BY Category.Name ASC
($sth->rows > 20) and print "\tWarning: Max number of top level categories -- 20 exceeded!\n";

# Create the HTML for the individual entries
$category_sidebar ='';

while ($cat_name = $sth->fetchrow_hashref) {
$category_clean = &build_clean_name ($cat_name->{Name});
$category_sidebar .= qq|<font size="-1"> <a class="link"

# Write it out to the file.
open (SIDEBAR, ">$LINKS{admin_root_path}/templates/category_sidebar.inc")
or die (qq~ unable to open Category Sidebar include:
Reason: $!
print SIDEBAR &site_html_category_sidebar ( { category_sidebar => $category_sidebar } );
close SIDEBAR;
Add this to the HTML_Templates.pm file:

sub site_html_category_sidebar {
# --------------------------------------------------------
# This routine is used to display the category sidebar
my ($rec, $dynamic) = @_;
my $template = defined $dynamic ? $dynamic->param('t') : undef;
(ref $rec eq 'HASH') or croak "HTML_TEMPLATES: Argument '$rec' must be hash reference";

my $output = &load_template ('category_sidebar.html', {
}, undef, $template);

return $output;
Make sure to add &site_html_category_sidebar to your list of @EXPORT routines at the top of the file.

Next, you need to make a file 'category_sidebar.inc' in the templates directory. It can be a 0 byte file, but it has to have read/write permissions:

touch category_sidebar.inc
chmod 777 category_sidebar.inc

Then, you need to create a 'category_sidebar.html' that is the "include" file TEMPLATE. The most basic file is just a file that contains <%category_sidebar%>. How ever you modify this to fit your site is up to you.



The error reporting is bad. I didn't take the time to pretty this up, if someone wants to, _PLEASE_ do. You need to make sure the file permissions are set, and the template files exist, etc.

I only used ONE template, rather than two.

Because this is only returning the "Category.Name" field, it seems really, really pointless to have another template for one line of HTML.

I know this violates my rule of putting all the HTML in a template, but this is a _really_ valid exception.

If someone wants to create a "category_sidebar_link" template and subroutine, feel free, but for one line of HTML code (_really_ one line of code, nothing fancy) the overhead of all the function calls and file loads seems really, really unnecessary.

Of course, this can be extended (it's really an extension of the Top 5 mods I did), and in that case, you might want to make that line a template also, but in this case, for this, the performance hit would be unacceptable IMHO.

Also, I chose to put this in the nph-build.cgi file for a number of reasons. That means it's only updated when you re-build the site. Dynamic calls such as from search.cgi or add.cgi will only see the include file as of the date of the last build. This is not a short coming, IMHO, since you really want all the pages -- static or dynamic -- to show the same results.

For those wondering at this time, why I didn't just make it a function call, or something, I did this for performance reasons. Unlike the Top 5, which you'd really want to be dynamic, updated each time a person makes a search, the layout of your site _SHOULD_NOT_CHANGE_ between builds. If it does, you're way beyond needing _this_ mod <G>. By writing out the include file ONCE per build, you are just including it, a very fast process.

Oh... and I cloned the subroutines, so there _are_ extra variable definitions floating around, for no reason other than I'm too lazy to clean them up. Feel free.

Hope that answers any and all questions.

(NOTE: The qq~ ... ~ in the error message above was just so the lines didn't format funky here. It should work, but if it doesn't, change them to " ... " and put them on one line. )

FAQ: http://www.postcards.com/FAQ/LinkSQL/