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...
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.