User:Ric Sherlock/Temp/UserLogin
Intro
The initial request for critique on this JHP application led Oleg Kobchenko to propose the Markup-Behind model as a mechanism for separating the programming logic and presentation in a web application. Hopefully the more detailed example here will serve as an additional illustration of how both JHP and Markup-Behind can be used.
Please feel free to critique/comment on the following.
Code
The following file is the default URL when visiting the root of the site. It also handles a number of other requests dependent on the query string. The HTML markup for two of the resulting pages is contained in the welcome.html and logout.html files shown below. [{{#file: "default.jhp"}} Download script: default.jhp ]
<% load '~.CGI/code/user.ijs' try. action=. qparam 'action' select. action case. 'logout' do. if. loggedIn'' do. DeleteCookie 'UserID' end. page=:'~CGI/welcome.html' case. 'loginfail' do. page=:'~CGI/loginfail.html' case. 'nouser' do. page=:'~CGI/nouser.html' case. do. NB. default action page=:'~CGI/welcome.html' end. transfer page catch. ContentType'text/html'[ Expires 0 println '<html><body><p>There was an error: ',13!:12'' println '</p></body></html>' end. %>
The following file contains the HTML markup for the default web page for the site. [{{#file: "welcome.html"}} Download script: welcome.html ]
<html><head> <title>Login Demo</title> </head> <body> <h2>Welcome to this site</h2> <p>If you have registered before, you can log in below.</p> <form action="login.jhp" method="post" name="login" id="login"> <p>User: <input name="usrname"></p> <p>Password: <input name="passwd" type="password"></p> <p><input type=submit></p> </form> </body></html>
The following file contains the JHP code to handle a user login request. The verbs validLogin and getUserInfo_puserdb_ are not shown here but just, validate a login and do a lookup for user info respectively. [{{#file: "login.jhp"}} Download script: login.jhp ]
<% load '~.CGI/code/user.ijs' try. uid=: validLogin qparam each 'usrname';'passwd' if. 0>uid do. NB. invalid login redirect 'default.jhp?action=loginfail' else. page=. '~CGI/userhome.asp' NB. destination page 'fname lname'=: 'greeting' getUserInfo_puserdb_ uid uid SetCookie 'UserID' transfer page end. catch. ContentType'text/html'[ Expires 0 println '<html><body><p>There was an error: ',13!:12'' println '</p></body></html>' end. %>
The following file is both valid JHP and ASP. It is given the .asp extension to distinguish it both from files containing only JHP code, and files containing only HTML markup. The .asp extension also means the file will be handled appropriately by HTML editors. The transfer verb will do the variable replacement using the variables created in login.jhp. [{{#file: "userhome.asp"}} Download script: userhome.asp ]
<html><head> <title>My Site</title> </head> <body> <h2>User Home</h2> <p>You are currently logged in as <%= fname %> <%= lname %>. If that is not correct, <a href="default.jhp?action=logout">log out</a> and login again using your username and password.</p> </body> </html>
[{{#file: "logout.html"}} Download script: logout.html ]
<html><head> <title>Login Demo</title> </head> <body> <h2>Logout Successful</h2> <p>Thanks for using my site.</p> <p>If you wish, you can login again below, otherwise, until next time!</p> <form action="login.jhp" method="post" name="login" id="login"> <p>User: <input name="usrname"></p> <p>Password: <input name="passwd" type="password"></p> <p><input type=submit></p> </form> </body></html>
I envisage that the functionality in the following script would eventually be added to JHP (probably in a much more complete and robust way). [{{#file: "jhpadd.ijs"}} Download script: jhpadd.ijs ]
require 'files' NB. require 'web/jhp/jhp' coclass 'z' fext=:'.'&(>:@i:~}.]) NB. get file extension isJHP=: (;:'jhp asp') e.~ [:<fext transfer=: 3 : 0 fnme=.y NB. map to physical path if. isJHP fnme do. ContentType'text/html'[ Expires 0 markup fnme else. ContentType'text/html'[ Expires 0 NB. Need to determine Content-Type here stdout fread jpath fnme end. ) redirect=: 3 : 0 uri=.y NB. if relative URL, convert to absolute println 'Location: ',uri ContentType'text/html' ) refresh=: 3 : 0 uri=.y NB. if relative URL, convert to absolute println 'Refresh: 0; url=',uri ContentType'text/html' )
The following script contains verbs to do the "heavy" lifting for dealing with user-related operations. They are not displayed here. [{{#file: "user.ijs"}} Download script: user.ijs ]
NB.*loggedIn v Checks if a user is currently authenticated NB. y is '' NB. result is boolean NB.*validLogin v checks if login is valid returns userid NB. y is boxed list of two strings 'username';'password' NB. result is numeric _1 if not valid, string userid if valid NB.*getUserInfo v gets user info from database NB. y is values to look up in database NB. x is string specifying name of sqlquery to run