Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Running local Perl from HTML

by Chuma (Scribe)
on Mar 10, 2019 at 14:32 UTC ( #1231092=perlquestion: print w/replies, xml ) Need Help??

Chuma has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I have an HTML file showing a table, and I'd like to be able to edit parts of it. Naturally, you can't edit the table directly in the browser, so I figure I'll click a table cell and have Javascript pop up an input box, then pass that data to a Perl script which updates the underlying data file and the HTML. I could do that using CGI, but that seems like a strange way of doing it I'm not going to put this functionality online, so why involve a server when all I want to do is edit my own files? But of course you can't run a local Perl script from a webpage, since that would be a security problem. So I'm trying to figure out a way to make Perl react to what's going on in the webpage.

So far my best idea is:

  • have my Perl program running in the background
  • on clicking a table cell, ask for user input with Javascript
  • put that input plus a cell reference in an invisible text field
  • copy that text to clipboard
  • let the Perl script listen for changes to the clipboard, and use that to update the data files

Can you think of a solution that's less ridiculous?

Replies are listed 'Best First'.
Re: Running local Perl from HTML
by choroba (Archbishop) on Mar 10, 2019 at 14:36 UTC
    Running a local web server isn't ridiculous. You don't have to install anything heavyweight like Apache, things like Dancer2 have their own simple webserver included which should be more than enough for your purposes.

    Also, if you just want to run the whole stuff locally, what about editing the table in a non-web GUI (like Tk) and outputting the final HTML table at the end?

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Running local Perl from HTML
by haukex (Bishop) on Mar 10, 2019 at 19:26 UTC
    you can't edit the table directly in the browser

    Sure you can, JavaScript makes that possible. <plug type="shameless"> It's even possible to run Perl instead of JS in the browser with WebPerl. </plug>

    I also agree with what choroba said about running a webserver locally. You can bind the webserver to your localhost IP, and if you wanted to play it extra safe (like on a multi-user machine), you could use HTTPS and pass an access token.

    The following uses Mojolicious to serve up a HTML file, injecting some JavaScript in the process. This JavaScript reacts to clicks on <td> and <th> elements, allowing you to edit their text, and then it immediately POSTs the modified HTML back to the server, which then rewrites the HTML file with what the browser sent. This is admittedly not the most elegant way to go about it, but it should work. Note it only supports one client at a time: although the JS makes sure to only send one request at a time, if two browser windows were to be open and submit requests at the same time, one of the changes would get lost.

      To add some more body parts to this Frankenstein-thing, you can take the content-reloading parts of App::Mojo::AssetReloader to broadcast any change to all connected clients. That way, multiple sessions can edit the content at the same time, with hilarious results. Ideally, you then transfer any change immediately (or as soon as it is somewhat valid HTML) to reduce the amount of edit conflicts.

      Converting this to a real multiplayer editor which shows the multiple insertion points is left as another exercise.

Re: Running local Perl from HTML
by Lotus1 (Vicar) on Mar 10, 2019 at 17:58 UTC

    You didn't mention what platform you are running on but if it is Windows you can use an HTML Application to run a Perl script from a local webpage. There is also Win32::HTA that might be useful. In addition I found this Perlmonks node which is old but relevant. I know there is a better example out there but I can't find it at the moment.

Re: Running local Perl from HTML
by clueless newbie (Curate) on Mar 10, 2019 at 16:41 UTC
    Are you running windows? If so you might want to have a look at
Re: Running local Perl from HTML
by roboticus (Chancellor) on Mar 11, 2019 at 14:40 UTC


    As has been mentioned, it's not a big deal to have a local server running. As an example, you could use HTTP::Server::Simple::CGI or other server package to build a simple perl server that will serve up your web page and let you interact with it. As a trivial example, this is a simple program that will serve up a web page and accept data:

    #!env perl { package PythonServer; use HTTP::Server::Simple::CGI; use base qw(HTTP::Server::Simple::CGI); use Data::Dump 'pp'; # URL paths to monitor my %dispatch = ( '/fetch' => \&fetch_page, '/save' => \&save_data, ); # Look up the path and execute the associated routine, or # give a typical 404 error sub handle_request { my ($self, $cgi) = @_; my $path = $cgi->path_info(); my $handler = $dispatch{$path}; if ("CODE" eq ref $handler) { print "HTTP/1.0 200 OK\r\n"; $handler->($cgi); return; } print "HTTP/1.0 404 Not found\r\n", $cgi->header, $cgi->start_html("Cheese Shoppe"), $cgi->h1("Sorry, We're fresh out of that one."), $cgi->end_html; } sub fetch_page { my $cgi = shift; return if !ref $cgi; print STDERR "Fetched page!\n"; open my $FH, '<', 'pm_1231092.html' or die "Can't open file: $ +!\n"; local $/; my $t = <$FH>; print $cgi->header; print $t; } sub save_data { my $cgi = shift; return if !ref $cgi; print STDERR "Got data: ", pp($cgi->{param}), "\n"; } } # Start up the server use strict; use warnings; my $pid = PythonServer->new(8088)->run; print "PID = $pid, press ^C to stop\n"; my $t = <>;

    And here's the web page that it will serve up:

    <html> <head> <title>A whimsical form</title> </head> <body> <h2>What is the airspeed of a laden swallow?</h2> <form action="/save"> <table class="things"> <tr><th>Number of Cocoanuts:</th> <td><input type="text" name="NumCocoanuts"/></td></tr> <tr><th>Swallow Type:</th> <td><select name="SwallowType"> <option>African</option> <option>European</option> </select> </td> </tr> </table> <input type="submit" value='Calculate Airspeed'/> </form> </body> </html>

    This is an admittedly crude example, but it works. All you need to do is add subroutines to the %dispatch table to let the server handle other actions, create the appropriate web pages, and write the JavaScript you want to use to handle the user interactions.

    The console output of a sample run gave me:

    $ perl PythonServer: You can connect to your server at http://localhost:8088/ Fetched page! Got data: { NumCocoanuts => [1], SwallowType => ["European"] }

    I hope this gives you a starting point to play with.

    Note: Internet Explorer for the win! That's a phrase I never thought I'd utter. Frikkin' Chrome kept blocking my attempt at putting in the html page of the example in there.


    When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1231092]
Approved by Discipulus
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2022-05-20 16:56 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (75 votes). Check out past polls.