Hello Monks,
I need to implement a server-side file tree and the best approach I've seen is this one: link. However, it needs a little rework for a modern mojolicious implementation, and the trouble is, I don't understand several of the technologies at work here.
The script uses jQuery AJAX, with the crucial part here (remember, this is javascript):
function showTree(c, t) {
$(c).addClass('wait');
$(".jqueryFileTree.start").remove();
$.post(o.script, { dir: t }, function(data) { // X----- Th
+is is the crucial part
$(c).find('.start').html('');
$(c).removeClass('wait').append(data);
if( o.root == t ) $(c).find('UL:hidden').show(); else
+$(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o
+.expandEasing });
bindTree(c);
});
}
It uses the post command to write to "o.script", earlier defined in this case as a CGI script. But CGI is old stuff, and I don't understand it well enough to rewrite its functionality in Mojolicious. Here's where I hope for your help: what exactly does my Mojo code need to do to respond to the AJAX post properly? Below is the original CGI connector; it seems to use print statements as the central mechanism, but not knowing how CGI works, I don't know that having my Mojo server respond with prints will do the trick. What is the strategy I need to implement to make the appropriate post response from my server?
Old CGI Connector
use strict;
use HTML::Entities ();
#-----------------------------------------------------------
# jQuery File Tree Perl Connector
#
# Version 1.0
#
# Oleg Burlaca
# http://www.burlaca.com/2009/02/jquery-file-tree-connector/
# 12 February 2009
#-----------------------------------------------------------
# for security reasons, specify a root folder
# to prevent the whole filesystem to be shown
# for ex: the root folder of your webbrowser
my $root = "/var/www/html/";
#----------------------------------------------------------
my $params = &getCGIParams();
print "Content-type: text/html\n\n";
my $dir = $params->{dir};
my $fullDir = $root . $dir;
exit if ! -e $fullDir;
opendir(BIN, $fullDir) or die "Can't open $dir: $!";
my (@folders, @files);
my $total = 0;
while( defined (my $file = readdir BIN) ) {
next if $file eq '.' or $file eq '..';
$total++;
if (-d "$fullDir/$file") {
push (@folders, $file);
} else {
push (@files, $file);
}
}
closedir(BIN);
return if $total == 0;
print "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
# print Folders
foreach my $file (sort @folders) {
next if ! -e $fullDir . $file;
print '<li class="directory collapsed"><a href="#" rel="' .
&HTML::Entities::encode($dir . $file) . '/">' .
&HTML::Entities::encode($file) . '</a></li>';
}
# print Files
foreach my $file (sort @files) {
next if ! -e $fullDir . $file;
$file =~ /\.(.+)$/;
my $ext = $1;
print '<li class="file ext_' . $ext . '"><a href="#" rel="' .
&HTML::Entities::encode($dir . $file) . '/">' .
&HTML::Entities::encode($file) . '</a></li>';
}
print "</ul>\n";
#---------------------------------------------------------------------
+-----------------------------
sub getCGIParams {
my $line;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $line, $ENV{'CONTENT_LENGTH'});
} else {
$line = $ENV{'QUERY_STRING'};
}
my (@pairs) = split(/&/, $line);
my ($name, $value, %F);
foreach (@pairs) {
($name, $value) = split(/=/);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
if (! exists $F{$name}) {
$F{$name} = $value;
} elsif (exists $F{$name} and ref($F{$name}) ne 'ARRAY') {
my $prev_value = $F{$name};
delete $F{$name};
$F{$name} = [ $prev_value, $value ];
} else { push @{ $F{$name} }, $value }
}
return \%F;
}