Browser displays page P0 with a button B [1] ↓ User presses the button [2] ↓ CGI action/transition on server produces page P1 [3] ↓ Browser displays page P1 [4]Two ways this view can be expanded are (1) by embedding button B in a form, and (2) by utilizing Javascrip attached to the button.
Browser displays page P0 with a button B [1] ↓ User presses the button [2] ↓ Form action invokes handler "ABC.cgi" [3] ↓ Backend language call(e.g., prolog) returns page P1 [4] ↓ Browser displays page P1 [5]Below is a simple forms-oriented sample. You can directly run it by pointing your browser at
https://kabstuff.com/prolog_web/form_sample/The sample files can be downloaded from:
Form-Oriented Sample Files
<HTML>Invoking http://kabstuff.com/prolog_web/form_sample/sample.html, we see page P0:
<HEAD>
<title>sample: forms + prolog
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</HEAD>
<BODY>
<h1>sample: forms + prolog</h1>
<form action="form_sample.cgi">
Date: <input type="date" name="seldate" value="2023-05-23">
<button type="submit">Submit Date</button>
</form>
</HTML>
#!/bin/bashStripping out all comment lines except the first and other inessential lines leaves:
#################################################################
##### form_sample.cgi
##### NOTE: This file must be executable
#################################################################
#echo 'Content-Type: text/plain'
echo 'Content-Type: text/html'
echo
#For pedagogy, print msg when no query:
if [ -z "$QUERY_STRING" ] ; then echo "IF -- EMPTY" ; fi
# Uncomment to get a dump of environment and stardard input
#printf 'Content-Type: text/plain' ; env ; echo ; cat ; echo ; exit
./alspro -q -b ./form_sample.pro ./queryproc.pro -g pro_do_sample
#!/bin/bash[4] All the stripped-down lines of form_sample.cgi are needed, but the last one is the live third rail. Using it, the server invokes alspro, with the following effects:
echo 'Content-Type: text/html'
echo
./alspro -q -b ./form_sample.pro ./queryproc.pro -g pro_do_sample
pro_do_sample :- % Get input from environment (getenv('QUERY_STRING', QS) -> true ; QS='DEFAULT QS VALUE HERE'), split_comps(QS, QueryStringVals), member(seldate=SelDate, QueryStringVals), % do something ... % finish; return page: printf('<H2>SUCCESS!</H2> got date: %t\n', [SelDate]), flush_output.The values of the fields of the html form are returned in the query string (QUERY_STRING) as equations, such as seldate=____. split_comps/2, defined in the file queryproc.pro breaks the query string up into a list of these equations that member/2 can operate on. [4/5] The page P1 to be returned by the cgi transition is the totality of the output written on user_output during execution of pro_do_sample/0. In this case, that is the output of the printf/2 call
printf('<H2>SUCCESS!</H2> got date: %t\n', [SelDate]),Note that the final call of pro_do_sample/0 is flush_output to ensure that everything written onto user_output during operation of pro_do_sample/0 has been flushed out to the stream.
SUCCESS!
got date: 2023-05-23(2) Attaching some Javascript to a button B.
A common Javascript-oriented CGI transition pattern has this high level view:Browser displays page P0 with a button B [1] ↓ User presses the button [2] ↓ Javascript on button activates CGI interface: e.g. 'window.location = "DEF.cgi" ' [3] ↓ Backend language call(e.g., prolog) returns page P1 [4] ↓ Client browser displays HTML page P1 [5]Below is a simple javascript-oriented sample. You can directly run it by pointing your browser athttps://kabstuff.com/prolog_web/js_sample/The sample files can be downloaded from:Javascript-Oriented Sample Files
[1] Now, for javascript, consider the file sample.html, containing an HTML date object and a button:<HTML>[2] The corresponding javascript file js_sample.js is:
<HEAD>
<title>sample: js + prolog</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="js_sample.js" type="text/javascript"> </script>
</HEAD>
<BODY>
<h1>sample: js + prolog</h1>
Date: <input type="date" id="date_box" value="2023-05-23">
<button type="submit" ONCLICK="submit_date();">Submit Date</button>
</HTML>function submit_date() { const x = document.getElementById("date_box"); let currentVal = x.value; // not necessary; can be eliminated: alert("cv="+currentVal); window.location = "js_sample.cgi?foo=bar&seldate="+currentVal; }[3] The file 'js_sample.cgi' contains:#!/bin/bash ################################################################# ##### js_sample.cgi ##### NOTE: This file must be executable ################################################################# #echo 'Content-Type: text/plain' echo 'Content-Type: text/html' echo #For pedagogy, print msg when no query: if [ -z "$QUERY_STRING" ] ; then echo "IF -- EMPTY" ; fi # Uncomment to get a dump of environment and stardard input #printf 'Content-Type: text/plain' ; env ; echo ; cat ; echo ; exit ./alspro -q -b ./pro_sample.pro ./queryproc.pro -g pro_do_sampleNote that a *.cgi file executes on the command line similarly to a shell script. Sometimes, this can be utilized for debugging. Here, the line "./alspro ..." in the cgi file does the following:
Closing the javascript alert, file js_sample.cgi will be executed.
Now when steps [1],[2],[3] are carried out, a stream S (back)to the client browser is passed along.
When js_sample.cgi is executed, thereby executing
./alspro -q -b ./pro_sample.pro ./queryproc.pro -g pro_do_samplethe stream S is identified with the standard output stream of the alspro invocation. Everything written and flushed by
alspro
running pro_do_sample
up to the time it exits
is accepted by the client browser as the next html page to display (transition to).
( Any output written by pro_do_sample
which has not been flushed from the alspro/pro_do_sample
image will NOT appear in the transition page displayed by the browser. Consequently, it is advisable to ensure that the last call executed by alspro/pro_do_sample
is a call to flush_output/0.
)
sh js_sample.cgiThis is true for all *.cgi files, including the ones used for the forms-based approach.
pro_do_sample :- % Get input from environment (getenv('QUERY_STRING', QS) -> true ; QS='DEFAULT QS VALUE HERE'), split_comps(QS, QueryStringVals), member(seldate=SelDate, QueryStringVals), % do something ... % finish; return page: printf('<H2>SUCCESS! got date: %t\n', [SelDate]), flush_output.The predicate split_comps/2 is defined in the file queryproc.pro.
In the predicateSUCCESS!
got date: 2023-05-23pro_do_sample/0
, the three lines(getenv('QUERY_STRING', QS) -> true ; QS='DEFAULT QS VALUE HERE'), split_comps(QS, QueryStringVals), member(seldate=SelDate, QueryStringVals),obtain the date value (currentVal
) provided by the javascript action:window.location = "js_sample.cgi?foo=bar&seldate="+currentVal;The expressionfoo=bar&
is present in that action only for illustrative purposes, showing how multimple bits of information from the original page can be passed back to prolog executing on the back end.
The page Pseudo Haiku utilizes this machinery together with an interface to an SQLite3 database.