Gossamer Forum
Home : Products : Links 2.0 : Customization :

Easy way to use anything for category name!

Quote Reply
Easy way to use anything for category name!
I think I have found a simpler way to enable folks to be able to use anything in the category name, and still have valid URLs. I call it the Cat Name mod. This is in the testing stage, so feedback is welcome. Also, be very careful about using this on existing databases; a new install is better to experiment with.

1. In db_utils.pl, edit this routine. I am aiming to convert non-word characters to XHTML-valid code, and the sequence of these elements is important. I had to convert the # symbol to something else (^) first, to get around the & being converted. I had tried doing this with a hash, but 1) it wouldn't work for question marks (why not?), and 2) hashes are hard to get to run in specified order.
Code:

sub build_clean {
# --------------------------------------------------------
# Formats a category name for displaying.
#
my ($input) = shift;
$input =~ s/_/ /g; # Change '_' to spaces.
$input =~ s|/|:|g; # Change '/' to ':'.
# > Cat Name mod
$input =~ s|#|\^|g; # Change '#' to '#' step 1

$input =~ s/&/&/g; # Change '&' to '&'
$input =~ s|\^|#|g; # Change '#' to '#' step 2

$input =~ s/\\/\/g; # Change '\' to '\'
$input =~ s/\?/?/g; # Change '?' to '?'
$input =~ s/!/!/g; # Change '!' to '!'

# < Cat Name mod
return $input;
}


2. Still in db_utils.pl, edit this routine. This removes the special characters from the category name, making a valid URL. For simplicity, all letters are switched to lowercase, and the & is changed to and.
Code:
sub urlencode {
# --------------------------------------------------------
# Escapes a string to make it suitable for printing as a URL.
#
my($toencode) = shift;
# > Cat Name mod
$toencode =~ s/\&/and/g; #change '&' to 'and'
$toencode =~ tr/ /_/; #replace space with underscore
$toencode =~ tr/[A-Z]/[a-z]/; #change all letters to lowercase
$toencode =~ s/([^a-z0-9_\-.\/])//g; #remove misc characters
# < Cat Name mod
$toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
$toencode =~ s/\%2F/\//g;
return $toencode;
}


3. In nph-build.cgi, sub build_category_pages, find this line and edit it as shown. This corrects the page title (top of browser window)
Code:
$category_name = &build_clean ($cat);


4. Next, edit this routine. I tried to get the check directory to work, but ended up commenting it out.

Code:
sub build_dir {
# --------------------------------------------------------
# Verifies that all neccessary directories have been created
# before we create the category file. Takes as input, the category
# to verify, and returns the full directory path. my $input = shift;
my ($dir, $path) = '';
my @dirs = split /\//, $input; foreach $dir (@dirs) {
$path .= "/$dir";
# > Cat Name mod
$path = &urlencode ($path);
# &build_check_dir ($build_root_path, $path);
# < Cat Name mod
if (! (-e "$build_root_path$path")) {
print "\tMaking Directory ($build_dir_per): '$build_root_path$path' ...";
if (mkdir ("$build_root_path$path", "$build_dir_per")) {;
print "Made. CHMOD ($build_dir_per) ...";
if (chmod ($build_dir_per, "$build_root_path$path")) {;
print "Done.";
}
else { print "CHMOD ($build_dir_per) failed! Reason: $!."; }
}
else { print "mkdir failed! Reason: $!."; }
print "\n";
}
}
return "$build_root_path$path";
}


5. Next, edit these two routines:

Code:

sub build_linked_title {
# --------------------------------------------------------
# Returns a string of the current category broken up
# by section, with each part linked to the respective section.
my $input = shift;
my (@dirs, $dir, $output, $path, $last);
@dirs = split (/\//, $input);
$last = &build_clean(pop @dirs);

$output = qq| <A HREF="$build_root_url/">Top</A> :|;
foreach $dir (@dirs) {
$path .= "/$dir";
$path = &urlencode ($path); # Cat Name mod
$dir = &build_clean ($dir);
$output .= qq| <A HREF="$build_root_url$path/">$dir</A> :|;
}
$output .= " $last";

return $output;
}
sub build_unlinked_title {
# --------------------------------------------------------
# Returns a string of the current category broken up by section.
# Useful for printing in the title.
my $input = shift;
my (@dirs, $dir, $output);
@dirs = split (/\//, $input);

foreach $dir (@dirs) {
$dir = &build_clean ($dir); # Cat Name mod
$output .= " $dir:";
}
chop ($output);
return $output;
}


6. In links.cfg, change these letters to lowercase. You will also have to edit the templates so that they point to the pages correctly.
Code:
# PATH and URL of What's New page. No Trailing slash.
$build_new_path = "$build_root_path/new";
$build_new_url = "$build_root_url/new";# PATH and URL of What's Cool page. No Trailing slash.
$build_cool_path = "$build_root_path/cool";
$build_cool_url = "$build_root_url/cool"; # PATH and URL of What's Rating page. No Trailing slash.
$build_ratings_path = "$build_root_path/ratings";
$build_ratings_url = "$build_root_url/ratings";


7. In category.def, remove the part in red:
Code:
Name => [1, 'alpha', 40, 75, 1, '', '^[\w\d/_-]+$'],



8. In search.cgi, edit this sub:
Code:

sub build_linked_title {
# --------------------------------------------------------
# A little different then the one found in nph-build.cgi as it also
# links up the last field as well.
my ($input) = shift;
my ($dir, $output, $path, $last);
foreach $dir ((split m!/!, $input)) {
$path .= "/$dir";
$path = &urlencode ($path); # Cat Name mod
$dir = &build_clean ($dir);
$output .= qq|<A HREF="$build_root_url$path/">$dir</A>:|;
}
chop ($output);

return $output;
}


Well, that's what I have for now. There may be other changes required, as I have not tested all functions yet. Let me know if it works for ya.


Leonard
aka PerlFlunkie