<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Here it is (without an imaginative choice of name):</div><div><br class="webkit-block-placeholder"></div><div>&nbsp;&nbsp; &nbsp;<a href="http://planet.plt-scheme.org/display.ss?package=dispatch.plt&amp;owner=untyped">http://planet.plt-scheme.org/display.ss?package=dispatch.plt&amp;owner=untyped</a></div><div><br class="webkit-block-placeholder"></div><div>Dispatch is a tool for configuring controllers in web applications. It's three main functions are:</div><div><br class="webkit-block-placeholder"></div><div>1. providing a mapping from simple, elegant, permanent URLs to controller procedures;</div><div>2. providing a reverse mapping from controller calls to URLs;</div><div>3. providing a simple way to create clean, MVC oriented code without having to worry about cyclic dependencies between modules.</div><div><br></div><div>The example below uses Dispatch and Instaservlet to set up a simple blog:</div><div><br class="webkit-block-placeholder"></div><div>- "site.ss" uses Dispatch to define a simple site with three controllers;</div><div>- "run.ss" uses Instaservlet to configure the PLT web server and create a servlet that dispatches all incoming requests to the site;</div><div>- "posts.ss" provides sample implementations of two of the three controllers and demonstrates non-continuation-based linking between the controllers.</div><div><br class="webkit-block-placeholder"></div><div>The third controller is intentionally left unimplemented&nbsp;to demonstrate Dispatch's default error page, which can be used as a placeholder during development.</div><div><div><div><br class="webkit-block-placeholder"></div><div>I haven't added the continuation URL rewriting features that Jay mentioned in the recent discussion on this list. I should be able to add this in a 1.x update without significantly breaking backward&nbsp;compatibility.</div><div><br class="webkit-block-placeholder"></div><div>Cheers,</div><div><br class="webkit-block-placeholder"></div><div>-- Dave</div><div><br class="webkit-block-placeholder"></div><div>=====&nbsp;run.ss&nbsp;=====</div><div><br class="webkit-block-placeholder"></div><div><font class="Apple-style-span" face="Monaco">#lang scheme/base</font></div><div><font class="Apple-style-span" face="Monaco"><br class="webkit-block-placeholder"></font></div><div><font class="Apple-style-span" face="Monaco">(require&nbsp;(planet&nbsp;"instaservlet.ss"&nbsp;("untyped"&nbsp;"instaservlet.plt"&nbsp;1))</font></div><div><font class="Apple-style-span" face="Monaco">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (planet&nbsp;"dispatch.ss"&nbsp;("untyped"&nbsp;"dispatch.plt"&nbsp;1))</font></div><span class="Apple-style-span" style="font-family: Monaco; ">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (file&nbsp;"/posts.ss")</span><div><font class="Apple-style-span" face="Monaco">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (file&nbsp;"site.ss"))</font></div><div><font class="Apple-style-span" face="Monaco"><br>;&nbsp;(request -&gt; response)<br>(define&nbsp;(main&nbsp;request)<br>&nbsp;&nbsp;(dispatch&nbsp;request&nbsp;blog))</font></div><div><font class="Apple-style-span" face="Monaco"><div><div><p align="">(go!&nbsp;main)</p><p align=""><span class="Apple-style-span" style="font-family: 'Lucida Grande'; "><span class="Apple-style-span" style="font-family: Monaco; ">=====</span>&nbsp;site.ss&nbsp;<span class="Apple-style-span" style="font-family: Monaco; ">=====</span></span></p></div></div></font></div><div><span class="Apple-style-span" style="font-family: Times; font-size: 16px; "></span></div><div><span class="Apple-style-span" style="font-family: Times; font-size: 16px; "><span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: 13px; "><div><font class="Apple-style-span" face="Monaco">#lang scheme/base<br><br>(require&nbsp;(planet&nbsp;"dispatch.ss"&nbsp;("untyped"&nbsp;"dispatch.plt"&nbsp;1)))<br><br>(provide&nbsp;blog&nbsp;index&nbsp;review-post&nbsp;review-archive)<br><br>(define-site&nbsp;blog<br>&nbsp;&nbsp;([(url&nbsp;"/")&nbsp;index]<br>&nbsp;&nbsp; [(url&nbsp;"/post/"&nbsp;(string-arg))&nbsp;review-post]<br>&nbsp;&nbsp; [(url&nbsp;"/archive/"&nbsp;(integer-arg)&nbsp;"/"&nbsp;(integer-arg))<br>&nbsp;&nbsp; &nbsp;review-archive]))</font></div><div><font class="Apple-style-span" face="Monaco"><br class="webkit-block-placeholder"></font></div></span></span></div><div><font class="Apple-style-span" face="Times" size="4"><span class="Apple-style-span" style="font-size: 16px;"><span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: 13px; "><div>=====&nbsp;posts.ss&nbsp;=====</div><div><font class="Apple-style-span" face="Monaco"><br class="webkit-block-placeholder"></font></div><div><span class="Apple-style-span" style="font-family: Monaco; ">#lang&nbsp;scheme/base</span></div><div><font class="Apple-style-span" face="Monaco"><br class="webkit-block-placeholder"></font></div><div><span class="Apple-style-span" style="font-family: Monaco; ">(require&nbsp;(planet&nbsp;"dispatch.ss"&nbsp;("untyped"&nbsp;"dispatch.plt"&nbsp;1))</span></div><div><span class="Apple-style-span" style="font-family: Monaco; ">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (file&nbsp;"site.ss"))</span></div><div><font class="Apple-style-span" face="Monaco"><br class="webkit-block-placeholder"></font></div><div><span class="Apple-style-span" style="font-family: Monaco; ">;&nbsp;(request string -&gt; html-response)</span></div><div><span class="Apple-style-span" style="font-family: Monaco; ">(define-controller&nbsp;(review-post&nbsp;request&nbsp;slug)</span></div><div><span class="Apple-style-span" style="font-family: Monaco; ">&nbsp;&nbsp;`(html&nbsp;(head&nbsp;(title&nbsp;,slug))</span></div><div><span class="Apple-style-span" style="font-family: Monaco; ">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (body&nbsp;(h1&nbsp;"You are viewing "&nbsp;,(format&nbsp;"~s"&nbsp;slug))</span></div><div><span class="Apple-style-span" style="font-family: Monaco; ">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (p&nbsp;"And now for some content..."))))</span></div><div><font class="Apple-style-span" face="Monaco"><div><div><p align="">;&nbsp;(request -&gt; html-response)<br>(define-controller&nbsp;(index&nbsp;request)<br>&nbsp;&nbsp;`(html&nbsp;(head&nbsp;(title&nbsp;"Index"))<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (body&nbsp;(h1&nbsp;"Index")<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ul&nbsp;,@(map&nbsp;index-item-html<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(list&nbsp;"post1"<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"post2"<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"post3"))))))<br><br>;&nbsp;(string -&gt; html)<br>(define&nbsp;(index-item-html&nbsp;slug)<br>&nbsp;&nbsp;`(li&nbsp;(a&nbsp;([href&nbsp;,(controller-url&nbsp;review-post&nbsp;slug)])<br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"View "&nbsp;,(format&nbsp;"~s"&nbsp;slug))))</p><p align=""><font class="Apple-style-span" face="'Lucida Grande'">==========</font></p></div></div></font></div></span></span></font></div></div></div></body></html>