Gossamer Forum
Home : Products : Links 2.0 : Customization :

Yeehaw! A replacement for dysfunctional nonenglish mod!

Quote Reply
Yeehaw! A replacement for dysfunctional nonenglish mod!
I 've been fiddling around with the code, trying to make the detail pages do different things, and it hit me [like a brick] that there is an easy way to be able to use ANYTHING for the category name, and still get Links to build right, and actually to make the URLs simpler.

For a sample, look here: http://theonetruechurch.com/links3

These are the cat names used by the linked-title, as entered in the admin; no new fields required:

Gossamer Threads Links: Test Three! : 3 & down : Sub & level four?

And this is the URL for that page:

http://theonetruechurch.com/.../sub_and_level_four/

The spaces are replaced with underscores (_), all letters are converted to lowercase, the '&' is replaced with the word 'and', and other characters (!?) are removed!

I just did this, and it works so far. I still need to check how it affects things like search, etc. But I will post the code changes so others can experiment, too.

It's easy! The changes are in red, some stuff added, some removed (#commented out).

In nph-build.cgi:

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";

$path =~ tr/ /_/;
$path =~ tr/[A-Z]/[a-z]/;
$path =~ tr/\?\*\.!//d;
$path =~ s/\&/and/g;


&build_check_dir ($build_root_path, $path);
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";
}


sub build_check_dir {
# --------------------------------------------------------
# Checks the directory before we create it to make sure there
# are no funncy characters in it.
my ($root, $dir) = @_;
# my $chrs = quotemeta ("/_-");

if (! -e $root) {
&cgierr ("Root directory: $root does not exist!");
}

# if ($dir !~ m,^[\w\d$chrs]+$,) {
# &cgierr ("Invalid characters in category name: $dir. Must contain only letters, numbers, _, / and -.");
# }
return $input;
}


In db_utils.pl:

sub urlencode {
# --------------------------------------------------------
# Escapes a string to make it suitable for printing as a URL.
#
my($toencode) = shift;
# $toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
$toencode =~ s/\%2F/\//g;
$toencode =~ tr/ /_/;
$toencode =~ tr/[A-Z]/[a-z]/;
$toencode =~ tr/\?\*\.!//d;
$toencode =~ s/\&/and/g;
return $toencode;
}


In category.def:

# Database Definition: CATEGORIES
# --------------------------------------------------------
# Definition of your database file.
%db_def = (
ID => [0, 'numer', 5, 8, 1, '', ''],
# Name => [1, 'alpha', 40, 75, 1, '', '^[\w\d/_-]+$'],
Name => [1, 'alpha', 40, 75, 1, '', ''],
Description => [2, 'alpha', '40x3', 500, 0, '', ''],
Related => [3, 'alpha', 0, 255, 0, '', ''],
'Meta Description' => [4, 'alpha', 40, 75, 0, '', ''],
'Meta Keywords' => [5, 'alpha', 40, 75, 0, '', ''],
Header => [6, 'alpha', 40, 75, 0, '', ''],
Footer => [7, 'alpha', 40, 75, 0, '', '']
);


I might get the hang of this stuff yet! Tongue


=====

OK, first update already...

This mod makes the New, Cool , and Rate pages build with lowercase letters, so a few more changes are in order. All templates need to be changed so that they have lowercase letters. Here is the original code:

<a class="menulink" href="<%build_root_url%>/New">What's New</a> |
<a class="menulink" href="<%build_root_url%>/Cool">What's Cool</a> |
<a class="menulink" href="<%build_root_url%>/Ratings">Top Rated</a> |

and the updated code:

<a class="menulink" href="<%build_root_url%>/new">What's New</a> |
<a class="menulink" href="<%build_root_url%>/cool">What's Cool</a> |
<a class="menulink" href="<%build_root_url%>/ratings">Top Rated</a> |


Then, in links.cfg, change the uppercase N, C, and R to lowercase (the red is just for comparison):

# PATH and URL of What's New page. No Trailing slash.
# $build_new_path = "$build_root_path/New";
$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";


The search works fine, the dropdown on the add form looks fine...
I am very happy with this discovery!!! Cool Smile Wink Angelic

Note that if this mod is applied to an existing site, all your old links (bookmarks, search engine links, etc) will become invalid. Unsure


Leonard
aka PerlFlunkie

Last edited by:

PerlFlunkie: Dec 4, 2004, 11:18 PM
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Leonard, slightly off topic but, at the bottom of those pages it displays Pages Updated On: 5-Dec-2004 - 02:26:37. Is this a mod or does links already do this and if so how is it enabled?

Thanks.
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Great Job!!!!
Crazy
Quote Reply
Re: [MJB] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
MJB,

That is a standard feature. I used a new, un-modified install of Links2 to experiment with, and the only changes I made are outlined above. You may have removed the tag from your templates:

<small class="update">Pages Updated On: <%date%> - <%time%><br>


Leonard
aka PerlFlunkie
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
I don't use templates. Crazy
Quote Reply
Re: [MJB] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Okay, then in site_html.pl, near the top, there's this:

# You must keep a link back to Gossamer Threads unless you purchase a license. Please see the
# Readme for details.
$site_footer = qq~
<p><small class="update">Pages Updated On: $date - $time<br>
Links Engine Powered By: <a href="http://www.gossamer-threads.com/">Gossamer Threads Inc.</a></small></p>
~;


Leonard
aka PerlFlunkie
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Ah thanks. I must have removed that when I purchased the license.
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Another change to be made, in npg-build.cgi:

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 =~ tr/ /_/;
$path =~ tr/[A-Z]/[a-z]/;
$path =~ tr/\?\*\.!//d;
$path =~ s/\&/and/g;


$dir = &build_clean ($dir);
$output .= qq| <A HREF="$build_root_url$path/">$dir</A> :|;
}
$output .= " $last";

return $output;
}

This will make the linked-title work...

and two more, still in nph-build.cgi:

sub build_new_page {
# --------------------------------------------------------
# Creates a "What's New" page. Set $build_span_pages to 1 in links.cfg
# and it will create a seperate page for each date.

... edited for space ...

CATEGORY: foreach $category (sort keys %{$link_output{$date}}) {
$category_clean = &build_clean ($category);
##
$category2 = $category;
$category2 =~ tr/ /_/;
$category2 =~ tr/[A-Z]/[a-z]/;
$category2 =~ tr/\?\*\.!//d;
$category2 =~ s/\&/and/g;
##
$link_results .= qq|<P><A HREF="$build_root_url/$category2/$build_index">$category_clean</A>\n|;
$link_results .= ${$link_output{$date}}{$category};
}


sub build_cool_page {
# --------------------------------------------------------
# Creates a "What's Cool" page.
local ($total, $percent, $link_results, $title_linked);
my (%link_output, $category_clean);

if ($build_cool_path =~ m,^$build_root_path/(.*)$,) {
&build_dir ($1);
}

$total = 0;
CATEGORY: foreach $category (sort keys %cool_links) {
LINK: for ($i = 0; $i < ($#{$cool_links{$category}}+1) / ($#db_cols + 1); $i++) {
$total++;
%tmp = &array_to_hash ($i, @{$cool_links{$category}});
$link_output{$category} .= &site_html_link (%tmp) . "\n";
}
}
foreach $category (sort keys %cool_links) {
$category_clean = &build_clean ($category);
##
$category2 = $category;
$category2 =~ tr/ /_/;
$category2 =~ tr/[A-Z]/[a-z]/;
$category2 =~ tr/\?\*\.!//d;
$category2 =~ s/\&/and/g;
##

$link_results .= qq|<P><A HREF="$build_root_url/$category2/$build_index">$category_clean</A>\n|;
$link_results .= $link_output{$category};
}
$title_linked = &build_linked_title ("Cool");
open (COOL, ">$build_cool_path/$build_index") or cgierr ("unable to open what's cool page: $build_cool_path/$build_index. Reason: $!");
print "\tCool Links: $total\n";
($db_popular_cutoff < 1) ?
($percent = $db_popular_cutoff * 100 . "%") :
($percent = $db_popular_cutoff);
print COOL &site_html_cool(@cool_links);
close COOL;
}


And I was wrong about the search.cgi, it needs to be changed, too:

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 =~ tr/ /_/;
$path =~ tr/[A-Z]/[a-z]/;
$path =~ tr/\?\*\.!//d;
$path =~ s/\&/and/g;


$dir = &build_clean ($dir);
$output .= qq|<A HREF="$build_root_url$path/">$dir</A>:|;
}


I will have to look at what happens with page-spanning, too...


Leonard
aka PerlFlunkie
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
And now, back to what initiated this discovery: detailed pages. I have them set to build in each category directory, instead of all in one 'Detailed' directory, and only when I want them to. In other words, I can select which links are off-site and which ones are local (detailed).

Next is the code to go along with the non-nonenglish mod. All changes are in red. In nph-build.cgi:

sub build_detailed_view {
# --------------------------------------------------------
# This routine build a single page for every link.
#
my (@values, $id, %rec, $count);
if ($build_detail_path =~ m,^$build_root_path/(.*)$,) {
&build_dir ($1);
}
print "\t";
open (DB, "<$db_file_name") or &cgierr("unable to open database: $db_file_name. Reason: $!");
LINE: while (<DB>) {
/^#/ and next LINE; # Skip comment Lines.
/^\s*$/ and next LINE; # Skip blank lines.
chomp;
@values = &split_decode ($_);
$id = $values[$db_key_pos];
%rec = &array_to_hash (0, @values);

my $cat2;
$cat2 = ($rec{'Category'});
$cat2 =~ tr/ /_/;
$cat2 =~ tr/[A-Z]/[a-z]/;
$cat2 =~ tr/\?\*\.!//d;
$cat2 =~ s/\&/and/g;


my $d_title;
$d_title = ($rec{'Title'});
$d_title =~ tr/ /_/;
$d_title =~ tr/[A-Z]/[a-z]/;
$d_title =~ tr/\?\*\.!//d;

$title_linked = &build_linked_title ("$rec{'Category'}/$d_title");

open (DETAIL, ">$build_root_path/$cat2/$d_title$build_extension") or &cgierr ("Unable to build detail page: $build_root_path/$cat2/$d_title$build_extension. Reason: $!");
print DETAIL &site_html_detailed (%rec);
close DETAIL;
$use_html ?
print qq~<a href="$build_root_url/$cat2/$d_title$build_extension">$id</a> ~ :
print qq~$id ~;


(++$count % 10) or print "\n\t";
}
close DB;
print "\n";
}

In site_html_templates.pl:

sub site_html_link {
# --------------------------------------------------------
# This routine is used to display what a link should look
# like.
my %rec = @_;
my $cat2;
$cat2 = ($rec{'Category'});
$cat2 =~ tr/ /_/;
$cat2 =~ tr/[A-Z]/[a-z]/;
$cat2 =~ tr/\?\*\.!//d;
$cat2 =~ s/\&/and/g;


my $d_title;
$d_title = ($rec{'Title'});
$d_title =~ tr/ /_/;
$d_title =~ tr/[A-Z]/[a-z]/;
$d_title =~ tr/\?\*\.!//d;


# Set new and pop to either 1 or 0 for templates.
($rec{'isNew'} eq 'Yes') ? ($rec{'isNew'} = 1) : (delete $rec{'isNew'});
($rec{'isPopular'} eq 'Yes') ? ($rec{'isPopular'} = 1) : (delete $rec{'isPopular'});
($rec{'isDetailed'} eq 'Yes') ? ($rec{'isDetailed'} = 1) : (delete $rec{'isDetailed'});

return &load_template ('link.html', {
detailed_url => "$build_root_url/$cat2/$d_title$build_extension",
%rec,
%globals
});
}

Then in the template directory, in link.html add this:

<%if isDetailed%>
<a href="<%detailed_url%>">Details</a>
<%endif%>



Keep in mind that the changes made in links.def are required, as is updating the links.db file (as per the mod linked below). Only do steps 1-3 in the post by Snugglepuss:

http://www.gossamer-threads.com/...i?post=117388#117388

The basic info on building the detail pages under each category came from here:

http://www.gossamer-threads.com/...cgi?post=33481#33481


Leonard
aka PerlFlunkie
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Just thinking, this could be used on an existing site, just make sure the code does not change your current directory names. The main difference would be this:

$category2 =~ tr/[A-Z]/[a-z]/;

...which converts uppercase letters to lowercase. By removing that line fom the codes above, you should still be able to use spaces and amperstands in your category names.


Leonard
aka PerlFlunkie
Quote Reply
Re: [PerlFlunkie] Yeehaw! A replacement for dysfunctional nonenglish mod! In reply to
Further refinement. Now instead of having the changes made in each routine, they can be made in one spot: db_utils.pl.

In link.html, use this in place of the other two '$cat2' and '$d_title' blocks:
my $cat2 = & encode_kit_cat ($rec{'Category'});
my $d_title = &encode_d_title ($rec{'Title'});

[ - In other words, remove these:
my $cat2;
$cat2 = ($rec{'Category'});
$cat2 =~ tr/ /_/;
$cat2 =~ tr/[A-Z]/[a-z]/;
$cat2 =~ tr/?*.,'"!//d;
$cat2 =~ s/\&/and/g;


my $d_title;
my $d_title = ($rec{'Title'});
$d_title =~ tr/ /_/;
$d_title =~ tr/[A-Z]/[a-z]/;
$d_title =~ tr/?*.,'"!//d;

- ]

In nph-build.cgi, do similar...

sub build_detailed_view
my $d_title = &encode_d_title ($rec{'Title'});
my $cat2 = &encode_kit_cat ($rec{'Category'});


sub build_pick_page (if you added the Editor's Pick mod)
sub build_new_page
sub build_cool_page
my $category2 = &encode_kit_cat ($category);

sub build_dir
sub build_linked_title
$path = &encode_kit_cat ($path);

Then in db_utils.pl, add these two routines:

sub encode_kit_cat {
# clean up category name
#--------------------------------------------
my ($toencode) = shift;
$toencode =~ tr/ /_/; #replace space with underscore
$toencode =~ tr/[A-Z]/[a-z]/; #change all letters to lowercase
$toencode =~ tr/?*.,'"!//d; #remove misc charachters
$toencode =~ s/&/and/g; #change '&' to 'and'
return $toencode;
}

sub encode_d_title {
# clean up Detailed page title (when used as a link)
#--------------------------------------------
my ($toencode) = shift;
$toencode =~ tr/ /_/; #replace space with underscore
$toencode =~ tr/[A-Z]/[a-z]/; #change all letters to lowercase
$toencode =~ tr/?*.,'"!//d; #remove misc charachters
$toencode =~ s/\&/&#38;/g; #change '&' to '&#38;'
return $toencode;
}

And change

sub urlencode
# --------------------------------------------------------
# Escapes a string to make it suitable for printing as a URL.
#
my($toencode) = shift;
# my $chrs = quotemeta ("/_-");
# $toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
$toencode =~ s/\%2F/\//g;
$toencode = &encode_kit_cat ($toencode);
return $toencode;
}


Leonard
aka PerlFlunkie