Gossamer Forum
Quote Reply
Random Global Questions
I had a long long thread http://www.gossamer-threads.com/...rum.cgi?post=174933; going a while back, but I thought I would start fresh and hopefully it can be easier to follow. I really want to add fuctionality, if someone here can write it.

I have a really nice global that Alex, Paul and Pugdog helped me figure out. (I hope I didn't miss anyone!) What it does is
1) allow you to have random links from a particlar category show up
2) not have any duplicates of those links show at the same time.
3) It creates dynamic (refreshing) random links on static pages.

Global:
random_link
sub {
my $tags = shift;
my $link_db = $DB->table('Links','CatLinks');
my $cat_id = $tags->{Random_CatID};
my $limit = $tags->{Random_Limit} || 3;
my (@output, $sth);
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
if ($cat_id) {
$sth = $link_db->select ( { CategoryID => $cat_id });
}
else {
$sth = $link_db->select;
}
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
return { Random_Loop => \@output }
}


Then I create a template called:
random.html with the following in it

<%random_link%>
<%loop Random_Loop%>
<%body_font%>
<div align="left"><a href="<%build_root_url%>/Detailed/<%ID%>.html"><b>
<%Title%>
</b><br>
</A>
<%Description%>
<a href="<%build_root_url%>/Detailed/<%ID%>.html"> more</A></%body_font%> <br>
</div>
<%endloop%>

I then call that template within the category template like this:
<!--#include virtual="/cgi-bin/dir/page.cgi?p=random&Random_CatID=<%ID%>"-->
or
<!--#include virtual="/cgi-bin/dir/page.cgi?p=random&Random_CatID=9"-->

What I want to change
I would love to make it be able to choose from any of the subcats within a category. What happens is that I have:

Category 1
-subcat a
-subcat b
-subcat c

I want to be able to use <!--#include virtual="/cgi-bin/dir/page.cgi?p=random&Random_CatID=<%ID%>"--> and have it pull links from within subcat a,b and c when I put the above ssi in Category 1. (many times there are no links in Category 1)

Can this work? How? Can you explain it?

Last edited by:

Evoir: Aug 2, 2002, 4:36 PM
Quote Reply
Re: [Evoir] Random Global Questions In reply to
 You could try adding this before your return line:


my $cat_db = $DB->table('Category');
my $sth2 = $cat_db->select ( ['ID'],{ FatherID => $cat_id });

while (my ($child_id) = $sth2->fetchrow_array){
my $sth3 = $link_db->select ( { CategoryID => $child_id, isValidated => 'Yes' });
while (my $hash2 = $sth3->fetchrow_hashref) {
push @output, $hash2;

}
}

This is modified from one of my globals so I haven't tested it.

Laura.
The UK High Street
Quote Reply
Re: [afinlr] Random Global Questions In reply to
this seemed to spit out all available links from within the category and subcats. How can I limit it to a number, like my original global above? Mybe I put your additional code in the wrong place, as I don't understand the syntax exactly. The global I created using mine above and what you supplied was:

sub {
my $tags = shift;
my $link_db = $DB->table('Links','CatLinks');
my $cat_id = $tags->{Random_CatID};
my $limit = $tags->{Random_Limit} || 3;
my (@output, $sth);
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
if ($cat_id) {
$sth = $link_db->select ( { CategoryID => $cat_id });
}
else {
$sth = $link_db->select;
}
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
my $cat_db = $DB->table('Category');
my $sth2 = $cat_db->select ( ['ID'],{ FatherID => $cat_id });
while (my ($child_id) = $sth2->fetchrow_array){
my $sth3 = $link_db->select ( { CategoryID => $child_id, isValidated => 'Yes' });
while (my $hash2 = $sth3->fetchrow_hashref) {
push @output, $hash2;

}
}
return { Random_Loop => \@output }
}

Last edited by:

Evoir: Aug 3, 2002, 9:25 AM
Quote Reply
Re: [Evoir] Random Global Questions In reply to
Sorry it was very late and I was concentrating on getting the subcategories included and forgot the point of the global!

Try adding

@output = sort {return (rand > 0.5) ? 1 : -1;} @output;
splice (@output,5);

just before your return line.

Laura.
The UK High Street
Quote Reply
Re: [afinlr] Random Global Questions In reply to
Thanks. It works.

But I think there might be some extra code in the Global, because the way it was set up originally, it limited the number of links it showed already. It seems to be ignoring the first limit.

Here is the global that is a mix of what you shared with me and from pervious attempts. The items in bold are the two times I believe the limits are set (and they are set differently) The global outputs 5 right now, the way it is written below:

sub {
my $tags = shift;
my $link_db = $DB->table('Links','CatLinks');
my $cat_id = $tags->{Random_CatID};
my $limit = $tags->{Random_Limit} || 3;
my (@output, $sth);
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
if ($cat_id) {
$sth = $link_db->select ( { CategoryID => $cat_id });
}
else {
$sth = $link_db->select;
}
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
my $cat_db = $DB->table('Category');
my $sth2 = $cat_db->select ( ['ID'],{ FatherID => $cat_id });
while (my ($child_id) = $sth2->fetchrow_array){
my $sth3 = $link_db->select ( { CategoryID => $child_id, isValidated => 'Yes' });
while (my $hash2 = $sth3->fetchrow_hashref) {
push @output, $hash2;

}
@output = sort {return (rand > 0.5) ? 1 : -1;} @output;
splice (@output,5);
}
return { Random_Loop => \@output }
}

Last edited by:

Evoir: Aug 3, 2002, 11:49 AM
Quote Reply
Re: [afinlr] Random Global Questions In reply to
>>
@output = sort {return (rand > 0.5) ? 1 : -1;} @output;
splice (@output,5);
<<

What is this code supposed to do?
Quote Reply
Re: [Paul] Random Global Questions In reply to
I have no idea. I am just a beggar hoping someone will solve my problems for me Smile

I have another twist to my request. I have some links where I have no description, just a link to the detailed page. I'd like the global to ignore any links that don't have a description. Is this possible, or is this something I do in the template (with a tricky IF statement)?
Quote Reply
Re: [Paul] Random Global Questions In reply to
Its supposed to randomly order the @output array and then take the first 5 elements? Please feel free to add a better way of doing it.

Evoir,

Unless Paul comes up with something better, I think you can change the splice line to

splice (@output,$limit);

I can't see an easy way of using LIMIT as there are several calls to the Links table and you don't know which ones will contain results.
Quote Reply
Re: [afinlr] Random Global Questions In reply to
If you are using ORDER BY RAND() I'm not sure why you then need to shuffle the array again.
Quote Reply
Re: [Evoir] Random Global Questions In reply to
You can ignore links without a description by adding a condition line:

my $condition = GT::SQL::Condition->new( 'Description', 'IS NOT', \'NULL','isValidated','=','Yes');

Add it below your select option line.

And then you can add $condition into both lines which select from the Links database

$sth = $link_db->select ( $condition ,{ CategoryID => $cat_id });

and

my $sth3 = $link_db->select ( $condition, { CategoryID => $child_id});



Paul - I think that you need to resort the array because otherwise you will always get links from the main category or the first subcategory - the new links are just added on the end of the array as the code goes down the list of subcategories, so if you want to give the links in the last subcategory a chance of appearing I think you need this extra sort?
The UK High Street
Quote Reply
Re: [afinlr] Random Global Questions In reply to
This global works great. Thanks afinlr. Smile

I have another small customization, not sure if it should be in the global, or on my subcategory.html template.

I'd like the global to NOT spit out any randoms on the page that shows links. Just in catgory and subcategory pages. Does this make sense?

Main categories=yes random link
subcategories=yes random link
links=no random link

Would this be something that I change in the template or the random global, and how would I do this?

Thanks again!

current global:
sub {
my $tags = shift;
my $link_db = $DB->table('Links','CatLinks');
my $cat_id = $tags->{Random_CatID};
my $limit = $tags->{Random_Limit} || 1;
my (@output, $sth);
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
my $condition = GT::SQL::Condition->new( 'Description', 'IS NOT', \'NULL','isValidated','=','Yes');
if ($cat_id) {
$sth = $link_db->select ($condition, { CategoryID => $cat_id });
}
else {
$sth = $link_db->select;
}
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
my $cat_db = $DB->table('Category');
my $sth2 = $cat_db->select ( ['ID'],{ FatherID => $cat_id });
while (my ($child_id) = $sth2->fetchrow_array){
my $sth3 = $link_db->select ($condition, { CategoryID => $child_id, isValidated => 'Yes' });
while (my $hash2 = $sth3->fetchrow_hashref) {
push @output, $hash2;

}
}
@output = sort {return (rand > 0.5) ? 1 : -1;} @output;
splice (@output,$limit);
return { Random_Loop => \@output }
}

Last edited by:

Evoir: Aug 7, 2002, 1:09 PM
Quote Reply
Re: [Evoir] Random Global Questions In reply to
Tee hee. That was a dumb question, eh?

The answer is: <%if category%><br><br><!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=<%ID%>"--><%endif%>
Quote Reply
Re: [Paul] Random Global Questions In reply to
Hello again,

I have another RANDOM question!

Here goes:
I am using:

<!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=<%ID%>"-->
on the category pages

and using:

<!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=9"-->

on the home page. How can I specify more than 1 category for the home page to pull from? I tried using a comma like :

<!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=9,10"-->

and that didn't pull from any more than the first category (9) and then I tried just using a space like this:

<!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=9 10"-->

and that still only pulled from category (9).

Is there a way to have the include identify more than one category to pull from? I'd rather not change the gloabl, instead I'd rather it come from the include. But if that is not possible, I can create a new global.

Thanks again for your help. Angelic

Last edited by:

Evoir: Sep 13, 2002, 11:43 AM
Quote Reply
Re: [Evoir] Random Global Questions In reply to
Hi,

It would take a new global. You should specify it like:

<!--#include virtual="/cgi-bin/content/page.cgi?p=random&Random_CatID=<%ID%>&Random_CatID=<%ID2%>"-->

Then in your global, do:

my @cat_ids = $IN->param('Random_CatID');

and change your select to:

$link_db->select ($condition, { CategoryID => \@cat_ids });

which will make it search on links in any of the categories passed in.

Cheers,

Alex
--
Gossamer Threads Inc.
Quote Reply
Re: [Alex] Random Global Questions In reply to
Alex,

Thanks for helping! I may have messed something up, because I just don't understand the perl. Here is what I came up with:

sub {
my $tags = shift;
my $link_db = $DB->table('Links','CatLinks');
my $cat_id = $tags->{Random_CatID};
my @cat_ids = $IN->param('Random_CatID');
my $limit = $tags->{Random_Limit} || 3;
my (@output, $sth);
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
my $condition = GT::SQL::Condition->new( 'Description', 'IS NOT', \'NULL','isValidated','=','Yes');
if ($cat_id) {
$sth = $link_db->select ($condition, { CategoryID => $cat_ids });
}
else {
$sth = $link_db->select;
}
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
my $cat_db = $DB->table('Category');
my $sth2 = $cat_db->select ( ['ID'],{ FatherID => $cat_id });
while (my ($child_id) = $sth2->fetchrow_array){
my $sth3 = $link_db->select ($condition, { CategoryID => $child_ids, isValidated => 'Yes' });
while (my $hash2 = $sth3->fetchrow_hashref) {
push @output, $hash2;

}
}
@output = sort {return (rand > 0.5) ? 1 : -1;} @output;
splice (@output,$limit);
return { Random_Loop => \@output }
}

Is this correct? (I got no results)

Thanks again
Quote Reply
Re: [Evoir] Random Global Questions In reply to
Hmm, let's clean that up a bit. Try:

Code:
sub {
my $tags = shift;
my $limit = ($tags->{Random_Limit} =~ /^(\d+)$/) ? $1 : 3;
my @parents = $IN->param('Random_CatID');
my @cat_ids;
foreach my $id (@parents) {
push @cat_ids, $id, $DB->table('Category')->children($id);
}
my $link_db = $DB->table('Links','CatLinks');
$link_db->select_options ('ORDER BY RAND()', "LIMIT $limit");
my $condition = GT::SQL::Condition->new( 'Description', 'IS NOT', \'NULL','isValidated','=','Yes');
if (@cat_ids) {
$condition->add('CategoryID', 'IN', \@cat_ids);
}
my $sth = $link_db->select($condition);
my @output;
while (my $hash = $sth->fetchrow_hashref) {
push @output, $hash;
}
return { Random_Loop => \@output }
}


This is a little different in that it will pick random link from the category you pass in, or any subcategory, not just the first level of subcategory.

To call this, just do:

<!--#include virtual="/cgi-bin/page.cgi?page=random&Random_CatID=1&Random_CatID=2"-->

to get 3 random links from anywhere inside category 1 or 2.

Cheers,

Alex
--
Gossamer Threads Inc.
Quote Reply
Re: [Alex] Random Global Questions In reply to
Finally I can clean up my globals! Thanks for that Alex, very useful.

Laura.
The UK High Street
Quote Reply
Re: [Alex] Random Global Questions In reply to
Wink

p=random
page-random

It should be:

<!--#include virtual="/cgi-bin/page.cgi?p=random&Random_CatID=1&Random_CatID=2"-->

This works great on my home page. Thanks!
Quote Reply
Re: [Alex] Random Global Questions In reply to
Alex,

You Wrote:
Quote:
This is a little different in that it will pick random link from the category you pass in, or any subcategory, not just the first level of subcategory.

How would I call this on a category page to include links from all subcategories? My previous call does not work on category pages. Frown
Quote Reply
Re: [Alex] Random Global Questions In reply to
my call for the category pages was like this:
<!--#include virtual="/cgi-bin/dir/page.cgi?p=random&Random_CatID=<%ID%>"-->

It now returns nothing. I thought it would still work if it will show random links from within the category and subcategories within.

hu? Crazy