2
votes

I'm currently working on a project that demand a few web application written in Prolog, and I choosed to use the famous SWI-Prolog PWP library. Which parses a script with prolog queries inside an HTML file.

I have a page responding to the following request example:

/user?id=N

Where N is a integer value.

But I'm having trouble to read the query string ID of the request inside the HTML file.

I have the .pl file:

showUser(UserId, Request) :- 
    reply_pwp_file(mydir('user_page.html'), [mime_type('text/html')], Request).

I don't know how I can read the UserId or the Request to retrieve again the UserId in the query strings.

I tried this way in the HTML markup:

<span pwp:ask="http_parameters(Request, [id(UserId, [optional(true)])])." pwp:use="UserId" />

Someone had this kind of trouble before?

Thank you very much.

Here's some interesting links that may help us:

2
Is really famous PWP library ? If I google pwp library I don't ever get a single URL... That's crazy... - CapelliC

2 Answers

1
votes

It took to me some time, but at least I've been able to run the demo_pwp.pl that I found in ~/pl-devel/packages/http/examples. Now, after

?- server(1234).

I open the URL

http://localhost:1234/user_id.pwp?user_id=1&user_name=carlo

where I wrote in ~/pl-devel/packages/http/examples/pwp/user_id.pwp file

<?xml version="1.0"?>
<!DOCTYPE html>

<html xmlns:pwp="http://www.cs.otago.ac.nz/staffpriv/ok/pwp.pl">

<head>
  <title>Context variables for PWP scripts</title>
</head>
<body>
  <p>This PWP demo lists the context-parameters that are passed into
     the script.
  </p>
  <ul>
    <li pwp:ask="member(Name=Value, CONTEXT)">
      <span class=name pwp:use="Name"/>
      =
      <span class=value pwp:use="writeq(Value)"/>
    </li>
  </ul>
  <!-- here is the specific part for my answer -->
  <p pwp:ask="memberchk('QUERY'=Q, CONTEXT),memberchk(user_id=UID,Q),memberchk(user_name=NAME,Q)">
     UID : <span pwp:use="UID"/> / NAME : <span pwp:use="NAME"/>
  </p>
  <!-- nested access is well thought -->
  <p pwp:ask="member('QUERY'=Q,CONTEXT)">
     UID : <span pwp:use="UID" pwp:ask="member(user_id=UID,Q)"/>
   / NAME : <span pwp:use="NAME" pwp:ask="member(user_name=NAME,Q)"/>
  </p>
</body>

</html>

(that's a copy of context.pwp, with added my info at bottom) and I get

This PWP demo lists the context-parameters that are passed into the script.
...    
-   QUERY = [user_id='1',user_name=carlo]
...    
UID : 1 / NAME : carlo 
UID : 1 / NAME : carlo 

Then I can confirm that the guidelines that Giulio suggested are ok.

0
votes

This is really out of the blue, since I've not churned Prolog in a long time, but I'm slightly amused at the effort of writing web applications in Prolog, and because I sympathize (long story short: I tried myself years ago, but it wasn't pure Prolog) I figured I could just take my chance at pointing you what I noticed by reading the documentation. Its clarity and extensivity, by the way, are not the reason why PWP is "famous", I presume.

However, buried somewhere in the PWP page you linked there is a blurb about the attribute pwp:use, that's said to take a Term as its value.

Term is a Prolog term; variables in Term are bound by the context. An empty Term is regarded as a missing value for this attribute. The Prolog variable CONTEXT refers to the entire context, a list of Name = Value, where Name is a Prolog atom holding the name of the context variable and Value is an arbitrary Prolog term.

Buried somewhere else, namely the documentation page for reply_pwp_page/3 (oh, there's no reply_pwp_file/3 up there in the page you linked, really, even if you used it) there's another interesting snippet listing the contents of the so-called initial context, and in particular:

QUERY [is a] Var=Value list representing the query-parameters

Since there is no hint or suggestion or even example about the use of the query parameters list - but that's hardly the worst problem for one that's forced to write web applications in Prolog anyway - my personal take is that the name for query parameter id is just id (hoping that Var is just a misname for Param, not a real Prolog variable) and that the value is, well, just the value, but then again we know nothing about conversions or whatever may happen automatically during the parsing of the query string, since in the query string everything is, well, a string, but you may need a numeric id, and you are probably left on your own converting that string to a number. I guess there's some magical predicate doing exactly that, somewhere. Ain't Prolog wonderful?

So, without any other clue, and with lots of thanks for those writing the documentation of this... stuff, my wild guess is that you need somewhere the following element, an empty span nonetheless, which is illegal in any reasonably valid HTML document:

<span pwp:ask="..."/>

where, as the ask value, you should provide a query that traverse the CONTEXT list (by means of member/2, maybe?) until it finds a term of the form 'QUERY'=QueryParameters; then in QueryParameters you should have the actual query parameters list, so you need to traverse it in the same fashion as the CONTEXT list before, and when you find a term of the form id=N here you finally are, N should contain the value of your hardly earned user id.

Now, I really hope it's way simpler that what I have outlined. Remember, it's just a wild guess by looking at the documentation you pointed to. But, while others will be quite probably busy down-voting this answer for a number of reasons (and hopefully because it's plain wrong, and the solution is way simpler), my last, parting suggestion is for you to discuss the constraints of your project again with whoever is in charge of them, because writing web applications in Prolog is really an unreasonable thing to do when there are plenty of frameworks (frameworks, I say, not just some module thrown into the standard library for the "greater good") written in other languages that are incredibly well documented, much simpler to understand and, of course, to use.