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

Suggest a 'New' Category feature?

Quote Reply
Suggest a 'New' Category feature?
Hi All,

I'd like to add a new form field to allow people to suggest a new category if they can't find a suitable one, and have it displayed on the 'validate' screen.

If I add the field to the Validate table, but NOT the Links table will I be able to see the suggested new category field, and then have links 'drop' it when I validate the record and it transfers the data to the links table?

If YES, will this have any effect on adding future fields to either the validate or links tables, i.e.; the validate table's fields will be 1 field ahead of the links table? (or does it match on field 'Name'?)

All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Two suggestions....

1) Add the Suggested Category as an "email field" that is sent to the administrator. Simply add the following codes in the send email codes at the end of the add.cgi file:

Code:

Suggested Category: $in->param('Suggested')


2) You could create another table called Validate_Category that would store the suggested category. You would then need to add more codes in the add.cgi that adds the suggested category into the Validate_Category table. You would have to call the Category.def file first to see if that Category already exists...then you would have to use different record hash values like $rec2 for adding the record into the Validate_Category table.

Then you would have to edit the Admin_HTML.pm file to add additional links and also create another html_validate_form routine that would reference the Validate_Category and Category tables rather than the Validate and Links tables.

Good luck!

Regards,

Eliot Lee

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Eliot,

Thanks for the suggestions:

Sug. 1) I have the admin-email notification OFF because of the number of links that get suggested to Qango!

Sug. 2) A bit too complicated, I want something simple to use and manage for me and my visitors.

Although it won't be difficult to add a separate 'Suggest a Category' form and have it emailed, I already get too much email and this would only add to my time management problems :)))

I'd rather hoped that I could get the suggested category along with the link details so it applies more specifically to the category someone is suggesting a site from. That way I could use the <%category%> value in the form field so people can just 'tack on' the new sub-cat they want on the end of it!

I suppose the best way to find out is to try it ... Smile ... I just wondered if someone could confirm the expected behavior of links if I added the extra field to the Validate table without adding it to the Links table.

All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Well, you could also experiment with hacking the sub validate_records in the admin.cgi script and see if you can't just INSERT into the Category table with the field added in the Validate table.

Regards,

Eliot Lee

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Eliot,

Sorry, I might not have explained correctly, I want to 'View' the new category suggestion field when I validate records, but not actually ADD it when I add the link (sort of like a 'holding' field that gets discarded when I validate/delete a record).

I'm planning on using it as a system of improving my category structure by getting suggestions from people who are more familiar with the subject matter than I am (with 7000+ cats I can't be an expert in everything Smile).

I still want to manually add categories, but I'd like people to be able to make 'suggestions' as to the ones they'd like adding so I can use those suggestions as a guide. The reason I want it in the validate table is that if I'm inclined to add the suggested new category I can do it before I validate the record, that way the link can go in the 'new' category.

I just wanted to make sure it wouldn't screw-up my tables before I tried it Smile!

All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
I understand your request completely...and I am trying to provide the best logic that will accomplish your goal.

If you want to be able to add the category before validating the link, then my earlier suggestion of adding the category into a "Validate_Category" or directly in the Category table would allow you to do this without messing around with the "Validate" table.

Let me give you some general hints:

1) Add a conditional statement in the sub process_form routine in the add.cgi:

Code:

if ($in->param('Suggested') ne "") {
}


2) In-between these codes, define the DBSQL object of $VALCAT. Look at how the $val object is defined.

3) Then you will have to define a second record hash, like $rec2.

4) Then use add_record with the $rec2 hash values to add the suggested category into the Validate_Category.

Of course, you will have to create a definition file called Validate_Category.def and create a table called Validate_Category that should contain the same fields as Category but add Mode row in the Validate_Category table.

Really...this is the best method since you have turned off the email to administrator option.

Good luck!

Regards,

Eliot Lee

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Eliot,

Thanks again. I really appreciate your efforts, and I can see how such a system would ease addition of suggested new categories, but I don't want to automate the process I just want to have somewhere to 'hold' the suggestion without screwing up either the validate or links tables.

Only a few of the validate records will have a suggested new category, not all of the suggested new categories will be appropriate, and some will require a slight change of wording to be useful so I want to 'pick-out' the ones I want and add them manually using my own judgement with their suggestion as a guide.

I really just want to know if the data will be 'dumped' if I don't add the "New Cat Suggestion" field to the links table, since it won't be needed after I've validated a link?


All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Why don't you try adding the field to the Validate table and then edit the add.cgi file to add this field and also edit your add template files and see if it adversely affects the validation process???

"Experimentation is the key to success!"
- Albert Einstein

Regards,

Eliot Lee

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Why not take a cue from the "bad links" report.

Rather than mail a suggestion, have them fill a form that inserts the suggestion into a database.

The database could contain as many fields as you want -- username, email, etc. Or just the basics-- the suggested category, and the category from which it was suggested.

You could then use simple SQL statements to pull the data, see the stuff, or you could write an interface to present it to you.

You could also make the form display the suggested categories, and allow people to vote on the suggestions.

You could then get more complicated, and allow commets to be tagged to the suggested category.

None of this is hard, but each new features would need a new table.

You could also provide a 'warning' system, such that if any category got more than 10 votes, and a rating of 8 or higher, you'd get an email message/reminder to check the suggestion box.

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

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Thanks for the suggestions (I'd love to do all the funky stuff but I don't know how yet! Smile)

I think I'll take your queue Eliot - give it a whirl and see what happens :)

All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
For kicks today, just to take a break for a little while, I took a look at this problem.

I stripped down 'add.cgi' and created a new_cat.cgi, and added 3 new template routines (just modified versions of the add_* subs in HTML_Templates.pm).

I've got a suggest new categories script working in a bare bones format. I'm going to see if I can add a few bells, such as a count field, and vote field, before I release the code. It was easier than I thought -- so easy, I've got to be missing something as yet <G>

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

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
I was bugged, so here is the script as it stands today. No fancy features,
and the "error" reporting is skipped, the user is just re-presented with the
new_cat.html file. It should be easy enough to add the <%error%> tag if you
want it.

Code:
You need to create a new table, using MySQLMan:

#
# Table structure for table 'New_Cat'
#
CREATE TABLE New_Cat (
ID int(11) DEFAULT '0' NOT NULL auto_increment,
Parent_Category varchar(150) DEFAULT '' NOT NULL ,
New_Category varchar(25) DEFAULT '' NOT NULL ,
Suggest_Date date DEFAULT '0000-00-00' NOT NULL ,
PRIMARY KEY (ID),
KEY ID(ID),
UNIQUE ID_2 (ID)
);


Then, you need to make the .def file. Start with the template below, but ***REMEMBER*** to
copy the header from one of your other DEF files, but change the 'package' and $db_table lines
to "New_Cat" from whatever tablename you used. Copy this to your .defs directory.

###########
# Auto Generated Config File.
# Created on: Tue Oct 3 20:37:51 2000
#

package Links::DBSQL::New_Cat;

$db_name = '';
$db_host = '';
$db_driver = 'mysql';
$db_user = '';
$db_pass = '';
$db_key = 'ID';
$db_table = 'New_Cat';
$db_track = '1';
$attach_dir = '';

%db_def = (
ID => ['1', 'INT', '10', '20', '1', '0', '^\d*\.?\d*$'],
Parent_Category => ['2', 'CHAR', '40', '150', '1', '', ''],
New_Category => ['3', 'CHAR', '25', '25', '1', '', ''],
Suggest_Date => ['4', 'DATE', '20', '20', '1', 'NOW', '^\d{4}\-\d{2}\-\d{2}$']
);

%db_select_fields = (

);
%db_checkbox_fields = (

);
%db_radio_fields = (

);

1;
========

Now, you need to create the forms: new_cat.html, new_cat_success.html (I use new_cat.html for the error
report at this time, without any report of an 'error')

This is the new_cat.html form. (basically the same for the new_cat_error.html as well!)

<form action="<%db_cgi_url%>/new_cat.cgi" method="POST">
<table border ="0" cellspacing="5" cellpadding="0">
<tr><td align="right" valign="top"><font face="Arial" size="2"><B>Category:</B></font></td>
<td><%Category%></td></tr>
<tr><td align="right" valign="top"><font face="Arial" size="2"><B>New Category to add:</B></font></td>
<td><input name="New_Category" value="" size="40"></td></tr>
<tr><td></td><td><input type="SUBMIT" name="New_Cat" value="submit"></td></tr>
</table>
</form>

This is the ADD CATEGORY SUCCESS page: (new_cat_success.html)

<p><font face="Arial" size="2">We have received the following suggestion:</font></p>
<TABLE>
<TR>
<TD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=3><B> ID:</B></FONT></TD><TD ALIGN=LEFT> <%ID%></TD>
</TR><TR>
<TD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=3><B> Parent:</B></FONT></TD><TD ALIGN=LEFT> <%Parent_Category%></TD>
</TR><TR>
<TD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=3><B>New Category:</B></FONT></TD><TD ALIGN=LEFT> <%New_Category%></TD>
</TR><TR>
<TD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=3><B> Date:</B></FONT></TD><TD ALIGN=LEFT> <%Suggest_Date%></TD>
</TR><TR>
</TABLE>

This is the routine you need to add to the EXPORT list in DB_UTILS.pm, and at the end of the file before the 1;

sub get_category_list_top {
# --------------------------------------------------------
# Builds a <select> list of category name to category id.
# It includes a choice '0' for "Top Level" additions.
#
my $value = shift;
my $fname = shift || 'CategoryID';
my $mult = shift || '';
$mult and ($mult = "MULTIPLE SIZE=4");
my ($query, $sth, $id, $name, $output, $time);

$output = $CATEGORY_LIST{$value,$fname};
$time = time();

if (!$output) {
if (! $CATDB) {
$CATDB = new Links::DBSQL $LINKS{admin_root_path} . "/defs/Category.def";
}
$query = qq|
SELECT ID, Name
FROM Category
ORDER BY Name
|;
$sth = $CATDB->prepare ($query);
$sth->execute() or die "Can't Execute: $DBI::errstr";
$output = "<select $mult name='$fname'><option value=''>----";
$output .= "<option value='0'>Top Level";
while (($id, $name) = $sth->fetchrow_array) {
($id == $value) ? ($output .= "<option value='$id' SELECTED>$name") : ($output .= "<option value='$id'>$name");
}
$output .= "</select>";
$sth->finish;
$CATEGORY_LIST{$value,$fname} = $output;
}
return $output;
}


The three routines to add to the EXPORT list in HTML_Templates.pm and to the end of that file before the 1;

&site_html_new_cat_form &site_html_new_cat_success &site_html_new_cat_failure


sub site_html_new_cat_form {
# --------------------------------------------------------
# This routine determines how the add form page will look like.
#
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 ('new_cat.html', {
%$tags,
%GLOBALS
}, undef, $template);
defined $dynamic and &clean_output($dynamic, \$output);
print $output;
}

sub site_html_new_cat_success {
# --------------------------------------------------------
# This routine determines how the add success page will look like.
#
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 ('new_cat_success.html', {
%$tags,
%GLOBALS
}, undef, $template);
defined $dynamic and &clean_output($dynamic, \$output);
print $output;
}

sub site_html_new_cat_failure {
# --------------------------------------------------------
# This routine determines how the add failure page will look like.
#
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 ('new_cat_error.html', {
%$tags,
%GLOBALS
}, undef, $template);
defined $dynamic and &clean_output($dynamic, \$output);
print $output;
}


And, finally, the new_cat.cgi file itself:

#!/usr/bin/perl
# ==============================================================
# --------------------------------------------
# Links SQL -- Suggest a new category script
# --------------------------------------------
# Original script and include modules Copyright 1999 Gossamer Threads Inc.
# This mod, written by PUGDOG (R) Enterprises, Inc.
#
# By using this program you agree to indemnify Gossamer Threads Inc.
# & PUGDOG(R) Enterprises, Inc. from any liability WHATSOEVER.
#
# ==============================================================

# Load required modules.
# ---------------------------------------------------
use strict;
use vars qw/%in/;
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib 'admin';
use Links;
use Links::DB_Utils;
use Links::HTML_Templates;
use Links::DBSQL;
$|++;

&main();

sub main {
# ---------------------------------------------------
# Create CGI object and figure out what to do.
#
my $in = new CGI;
my $dynamic = $in->param('d') ? $in : undef;

%in = %{&cgi_to_hash ($in)}; ## legacy from another mod, but it arguably makes doing _some_ things easier.
## The CGI object is "gone" and there is now a hash %in, and values $in{key}
print $in->header('text/html');

if (($in{'New_Cat'}) && ($in{'New_Category'})) { ## if the submit button was pressed and New_Category has a value
&process_form (\%in, $dynamic);
}
else { ## the form is incomplete
my ($name, $category);
my $id = $in{'CategoryID'};

# If we don't have an id, and can't generate a list, let's send the user a message.
## kept in for future use to limit suggestions to being _in_ that category: ie: no db_gen_category_list
if (! $id and ! $LINKS{db_gen_category_list}) {
&site_html_error ( { error => "Please go to the category you want to add to, and click add from there." }, $dynamic);
}
else {
if ($id) {
$name = &get_category_name ($id);
$category = "$name <input type=hidden name='CategoryID' value='$id'>";
}
else {
$category = &get_category_list_top (); ## new sub, adds 'Top Level' as a category option.
}
&site_html_new_cat_form ({ Category => $category, %in }, $dynamic)
}
}
}
# ==============================================================

sub process_form {
# --------------------------------------------------------
my ($in, $dynamic) = @_;
my ($new_cat, $category);

# Connect to the database.
$new_cat = new Links::DBSQL $LINKS{admin_root_path} . "/defs/New_Cat.def";

# Set date variable to today's date.
$in{'Suggest_Date'} = $new_cat->get_date(); ## today's date, mysql format.
# Convert the CategoryID into a CategoryName
$in{'Parent_Category'} = &get_category_name ($in{'CategoryID'}); ##$in{'CategoryID'} comes to us via the CGI process
# Store the current LinkID (not really useful for anything, but helps with debugging at this point.
$in{'ID'} = $new_cat->add_record ( \%in ); ## if successful, $id is the database record number of the new record.
# $in{'New_Category'} was passed from the form, and checked for non-nullness before being passed to this routine.
## the only 4 tags the form is expecting are the 4 database fields, now all 4 are defined.

if ($in{'ID'}) { # Send the visitor to the success page.
&site_html_new_cat_success ( { %in }, $dynamic);
}
else {
if ($in->param('CategoryID')) { ## if we have a parent category picked, assign it.
$in{'Category'} = $in{'Parent_Category'};
}
else { ## generate the category list again.
$in{'Category'} = &get_category_list_top();
}
&site_html_new_cat_failure( { error => $Links::DBSQL::error, %in }, $dynamic);
}
}


====

As far as I know, this is all you have to do!

Put the .cgi file in the /cgi-bin/links directory, and the other stuff where it belongs.
http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
BTW, I have this working at:

http://postcards.com/...in/pcSQL/new_cat.cgi

It's a test database, and I fully intend to ignore it, but you can see what this BS script does.

Also, you can then use the SQL Monitor to query the database:

SELECT * FROM New_Cat ORDER BY parent_category,new_category LIMIT 0, 25

Or, something pretty complex, like:

SELECT CONCAT(parent_category,new_category) AS FullCategory
FROM New_Cat
GROUP BY FullCategory
ORDER BY FullCategory
LIMIT 0, 25


It may at first seem best to store the full category name, but that limits you from doing searches on just the suggested portion of the name, something that may be of interest, since not everyone will suggest putting that sub-category in the same place.

Also, you can see which subcategories are getting the most suggestions, which means you might need to work on that area.

By making the Parent_Category/New_Category a

UNIQUE cat_index(Parent_Category,New_Category)

You can trap dupliate key entries, and increment a COUNT field, presenting the message "That category has already been requested, your vote for it has been added" to the new_cat_success.html template.

Sooooo much to do.... soooo little time.


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

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Pugdog,

You never cease to amaze me Smile


All the best
Shaun

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
I just added the "show cats" feature, to see the first 25 suggested categories.

Also, I noticed I have some problems with the $in and %in variables,they work, but they are not kosher (never program when really, really tired).

To add the "show_cats" feature, just put:
Code:
my $show_cats
if ($in{'Show_Cats'}) {
$show_cats = &show_cats(\%in);
}
inside the "else" (## form is incomplete) portion of the first if test, and add the passed tag:

&site_html_new_cat_form ({ Output=>$show_cats, Category => $category, %in }, $dynamic)

To the printout, and make sure to add:

<%if Output%><%Output%><%endif%> to your new_cat.html form.

and finally, here is the ugly little hack to add to the bottom of the new_cat.cgi file:

Code:
sub show_cats {
# --------------------------------------------------------
my ($in, $dynamic) = @_;
my ($new_cat, $sth, $categories, $output, $hit, $numhits);

# Connect to the database.
$new_cat = new Links::DBSQL $LINKS{admin_root_path} . "/defs/New_Cat.def";

$sth = $new_cat->prepare('SELECT * FROM New_Cat ORDER BY parent_category,new_category LIMIT 0, 25');
$sth->execute;
($numhits) = $sth->fetchrow_array;
$output = '';

if ($numhits) {
while ($hit = $sth->fetchrow_hashref) {
$output .= $hit->{'Parent_Category'} . '/<B>' . $hit->{'New_Category'}. "</B><BR>\n";
}
} else {
$output .= 'No Categories Suggested yet.';
}

return($output);


}

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

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Anyone wants to do a bit of logic work,

The SELECT statement returns a list of values "Parent_Category" "New_Category"

This is a Key/Value pair.

So, if you create a hash of hashes:

HOH->{Parent_Category}{New_Category}= $count

This way, each line pulled from the database creates a two dimentional hash, with the value being the number of times that element exists in the database.

If you then run through that datastructure for output:

Code:
for $suggested_categories (sort keys %HOH) {
for $key (sort keys %{HOH{$suggested_categories}}) {
$output .= $HOH{$suggested_categories}.'\'.$key ." ". $HOH{$suggested_categories}{$key}
}
}
As you can see, it's a bit convoluted to set up, but once set up, it will allow counting of the records in the database, outputting, sorting, etc. HOH is the best data structure for this sort of information.

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

Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Could anyone change this script to send the suggested category simply via mail to the admin?

Any help would be great!


Quote Reply
Re: Suggest a 'New' Category feature? In reply to
Use one of the Mailer Mods in the Resource Center...edit the forms so that it will send you a category name.

Regards,

Eliot Lee