parser

A simple feedback tool

Misha v.3 [April 16, 2004]

The example given below is an opportunity to have and use a simple feedback at your site. Our main target, however, is to demonstrate the beginners how to work with forms, and this is why there are so many comments and so little Parser code.

You should note that the resulting tool may have too much functionality for you (for example, we provide an opportunity of attaching a file to the message), so, after you copy it, do not forget to delete the parts you don’t need.

The whole tool will be stored in one file /feedback.html, which will first display the form and then, when post is received, will process it and send the message. If you’re going to place the form in one file and processing tool in the other, do not forget to change action in <form />

# main method
@main[]
<html>
<body>
^rem{ *** the address to which the message will be sent *** }
$sTo[to@email.ru]
^rem{ *** the address from which the message will be sent *** }
$sFrom[robot@$env:SERVER_NAME]

^if($form:action eq "done"){
	^rem{ *** here is where we get after the external redirect when everything has been sent successfully *** }
	^rem{ *** here is the thank you note for the visitor’s comments *** }
	$bShowForm(0)
	<p>Thank you for sharing yourself with us.</p>
}{
	^rem{ *** set the flag that the form should be displayed *** }
	$bShowForm(1)
}

^if(def $form:do){
	^rem{ *** if we receive something in the element 'do', the form is submitted *** }
	^if(^isOk[]){
		^rem{ *** if data is valid, try to send the message *** }
		^try{
			^send[$sTo;$sFrom]

			^rem{ *** perform an _external_ redirect to itself to protect from Reload *** }
			^rem{ *** although this won’t work to protect from Back *** }
			^rem{ *** to make sure that the redirect is external, don’t forget to start the address with http:// *** }
			^Lib:location[$request:uri^if(^request:uri.pos[?]>=0){&}{?}action=done;$.bExternal(1)]
		}{
			^rem{ *** we use try since an error may crop up in sending the message *** }
			^rem{ *** and here is where we get if the error HAS occurred *** }

			^rem{ *** tell Parser that we will handle the problem on our own *** }
			$exception.handled(1)
			
			^rem{ *** we should also let the user know about the error *** }
			^rem{ *** and it would be better to record the error in the log *** }
			<p>We are sorry, but an unknown error occurred in sending the message.</p>
		}

		^rem{ *** disable the flag that the form should be displayed *** }
		$bShowForm(0)
	}{
		^rem{ *** Some fields are not filled in: bash the user *** }
		^rem{ *** the flag is still on: the form should be displayed. *** }
		^rem{ *** i.e. after the user-bashing we show the form *** }
		^rem{ *** the previously input data has not been lost *** }
		<p>Required fields are empty!</p>
	}
}
^rem{ *** Show the form if the show-the-form flag is on *** }
^if($bShowForm){
	^rem{ ***if we’re going to provide for file-sending, don’t forget to specify enctype!!! *** }
	<form
		method="post"
		action="/feedback.html"
		enctype="multipart/form-data"
	>
		^rem{ *** this is the element to help determine if the form is posted or not *** }
		^rem{ *** if you want to determine this by the element 'action', it is impossible to... *** }
		^rem{ *** ...submit your form by pressing Enter key or triggering a js event *** }
		<input type="hidden" name="do" value="do" />

		Your name:<br />
		<input type="text" name="name" value="$form:name" /><br />
		E-mail:<br />
		<input type="text" name="email" value="$form:email" /><br />
		Your comment:<br />
		<textarea name="comment">$form:comment</textarea><br />
		Attachment:<br />
		<input type="file" name="attach" /><br />

		<input type="submit" name="action" value="Send" />
	</form>
}
</body>
</html>
#end @main[]

# the method checks if all fields are filled. If so, it returns true; otherwise it returns false
@isOk[]
$result(def $form:name && def $form:comment)
#end @isOk[]


# this method send email
@send[sTo;sFrom][dtNow]
$dtNow[^date::now[]]
^mail:send[
	$.to[$sTo]
	$.from[^if(^Lib:isEmail[$form:email]){$form:email}{$sFrom}]
	^rem{ *** charset to be used by the message *** }
	$.charset[$response:charset]
	$.subject[Feedback from site http://$env:SERVER_NAME/]
	$.text[User: $form:name
^if(def $form:email){E-mail: $form:email^#0A}Comment:
$form:comment^#0A^#0AMessage sent: ^dtNow.sql-string[]]
	^rem{ *** if the visitor has attached a file, sent it, too *** }
	^if($form:attach is "file"){
		$.file[$form:attach]
	}
]
$result[]
#end @send[]


This code uses some classes, which should then be downloaded and used with the code.

The code includes simple tools of protecting against Reload (which will make the browser attempt re-sending the data). This tool, however, doesn’t protect from the Back. If the feedback is not sent as e-mail, but stored into a DB, the check may be performed by means of DB or in the way it is described in the example on double-posting protection.