Reputation: 53
I have a text data file called "poduct_data.txt"
id | name | top
------------------
id01-- name01-- top
id02-- name02--
id03-- name03--
id04-- name04-- top
id05-- name05-- top
id06-- name06--
id07-- name07-- top
id08-- name08--
id09-- name09--
id10-- name10-- top
Here is 3 columns called id,name&top. "my task is :
if reload page then show randomly another 3 data may be : name07 name05 name10
Every time reload page show different 3 data from top data
1 is done and displaying like: name01 name10 name04 name07 name 05
but having problem in 2.
My work files are in below:
library file : ProductLib.pm
package ProductLib;
use strict;
use File::Basename;
use FileHandle;
use Encode;
use CGI;
use POSIX;
use Date::Parse;
sub new {
my $class = shift;
my ($ProgramName, $ProgramPath, undef) = fileparse($0);
my $self = {
'program_name' => $ProgramName,
'program_path' => $ProgramPath,
'data_dir' => 'data',
'product_data_file' => 'product_data.txt',
'template_dir' => 'templates',
'template' => {},
'cgi' => new CGI(),
@_,
};
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
return bless $self, $class;
}
sub SearchRandomProduct{
my $self = shift;
my $TargetTop = shift;
my $ProductHash = $self->GetProductData();
my $TargetProduct = {};
foreach my $ProductId (sort {$a cmp $b} (keys %{$ProductHash})){
my $ProductData = $ProductHash->{$ProductId};
my $ProductTop = $ProductData->{'top'};
next if(defined $TargetTop && $ProductTop ne $TargetTop);
$TargetProduct->{$ProductId} = $ProductData;
}
return $TargetProduct;
}
sub GetProductData{
my $self = shift;
my $FilePath = sprintf('%s/%s',
$self->{'data_dir'},
$self->{'product_data_file'}
);
my $FileData = ${$self->GetFileData($FilePath)};
my $ProductHash = {};
my @LineData = split("\n", $FileData);
foreach my $LineData (@LineData){
next if($LineData eq '' || $LineData =~ /^#/);
my @DataArray = split("\t", $LineData, 3);
my $ProductId = $DataArray[0];
my $ProductName = $DataArray[1];
my $ProductTop = $DataArray[2];
$ProductHash->{$ProductId} = {
'id' => $ProductId,
'name' => $ProductName,
'top' => $ProductTop,
};
}
return $ProductHash;
}
sub SetTemplateParameter{
my $self = shift;
my $TemplateData = shift;
my $ProductData = shift;
$TemplateData = ${$TemplateData} if(ref($TemplateData) eq 'SCALAR');
$TemplateData =~ s/\$\{(.*?)\}/$ProductData->{$1}/ges;
return \$TemplateData;
}
sub GetFileData{
my $self = shift;
my $FilePath = shift;
my $FileData = '';
if(-e "${FilePath}"){
my $FileHandle = new FileHandle;
sysopen($FileHandle, "${FilePath}", O_RDONLY);
$FileData = join'',<$FileHandle>;
close($FileHandle);
}
return \$FileData;
}
1;
cgi file: product_random_list.cgi
#!/usr/bin/perl
use FindBin;
use lib "$FindBin::Bin/lib";
use strict;
use CGI;
use ProductLib;
use Data::Dumper;
my $ProductFormat = ' <a class="card">
<div class="card-body">
<strong>${name}</strong>
</div>
</a>';
my $q = new CGI;
my $ProductLib = new ProductLib();
my $TargetMode = $q->param('mode') || 'init';
my $TargetTop = $q->param('top');
my $ProductList = {};
if($TargetMode eq 'init'){
$ProductList = $ProductLib->SearchRandomProduct($TargetTop);
}
my $ProductHtml = '';
foreach my $ProductId (
sort {
$ProductList->{$a}->{'id'} cmp $ProductList->{$b}->{'id'}
}
(keys %{$ProductList})){
my $ProductData = $ProductList->{$ProductId};
$ProductHtml .= ${$ProductLib->SetTemplateParameter(\$ProductFormat, $ProductData)};
}
print "Content-Type: text/plain; charset=utf8\n\n";
print $ProductHtml;
exit;
index file : index.html
<!DOCTYPE html>
<html>
<body>
<section>
<div class="container-fluid">
<div class="card-deck sMb">
<!--#include virtual="/ssi/product_random_list.cgi?top=top" -->
</div>
</div>
</section>
</body>
</html>
please help me to display them randomly by three top data when reload page in above index page...
Upvotes: 1
Views: 72
Reputation: 40778
display them randomly by three top data when reload page.
You can select three random items from the product list by using for example List::Util::shuffle(). Example:
use strict;
use warnings;
use List::Util qw(shuffle);
my $ProductList = {
id01 => {id => 'id01', name => 'name01', top => 'top'},
id10 => {id => 'id10', name => 'name10', top => 'top'},
id04 => {id => 'id04', name => 'name04', top => 'top'},
id07 => {id => 'id07', name => 'name07', top => 'top'},
id05 => {id => 'id05', name => 'name05', top => 'top'},
};
my @ids = keys %$ProductList;
my @idx = shuffle 0..$#ids;
my @randidx = @ids[@idx[0..2]];
Every time reload page show different 3 data from top data
In order to recognize if the page is reloaded or not, you could use a session variable. See CGI::Session for more information.
Upvotes: 0