Commits

Greg Slepak  committed ea5d5e7

updated documentation and guide for 0.60

  • Participants
  • Parent commits fe040dd

Comments (0)

Files changed (45)

 Version 0.6
 
   * added DF.DB and ObjNL
-  * updated documentation
+  * added Dragonfly's own improved SMTP module
+  * added new add-to-load-path and wrap-func functions to utils.lsp
+  * added CGI-like route to the inactive plugins: route_cgi.lsp
+  * added utf8-urlencode/decode functions to Request, they handle foreign characters perfectly.
+  * added 'SET_DF_SELF' function and the corresponding DF_SELF and DF_SELF_DIR global symbols.
+  * added 'DF_PAGE' to point to the currently loaded, host-unqualified web URL
+  * added global path functions to utils.lsp: file-ext del-ext basename dirname
+  * updated and rewrote parts of the user guide
   * improved windows compatibility by creating /tmp if necessary
   * improved the 'load-once' function (load replacement)
-  * bugfix in Response:cookie
-  * added new add-to-load-path and wrap-func functions to utils.lsp
-  * added CGI-like route to the inactive plugins. Move to the active
-    active plugins folder if you want to use it.
-  * added utf8-urlencode/decode functions to Request, they handle foreign characters perfectly.
-  * much improved the smtp module that comes with newLISP and added it to the inactive plugins.
-  * added 'SET_DFLY_SELF' function and the corresponding DFLY_SELF and DFLY_SELF_DIR global symbols.
-  * added 'DFLY_PAGE' to point to the currently loaded, host-unqualified web URL
-  * added some preliminary stuff to path.lsp in plugins-inactive
+  * bugfix in Response:cookie for deleting a cookie
+  * bugfix when directly accessing an .html file related to 'title' function
+  * removed path.lsp in plugins-inactive
+  * removed the 'into-ctx-assoc' function
+  * removed 'viewname' from STATIC_TRANSFORMATIONS. Replace with: DF_PAGE or (basename DF_PAGE)
+  * the winning transformation from STATIC_TRANSFORMATIONS is no longer evaluated twice
 
 Version 0.51
 

File example-site/.htaccess

 
 # if don't want Dragonfly to process html files comment
 # out the line below (you may need to remove the [OR] above too).
-RewriteCond %{REQUEST_FILENAME} \.html$
+RewriteCond %{REQUEST_FILENAME} \.(html|nl)$
 
 # Main URL rewriting.
 RewriteRule (.*) index.cgi?$1 [L,QSA]

File example-site/dragonfly-api/DF.DB/database.lsp.html

+<!DOCTYPE HTML PUBLIC "HTML 4.01 Transitional">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>database.lsp</title>
+
+<link rel="stylesheet" type="text/css" href="newlispdoc.css" />
+</head>
+
+<body style="margin: 20px;" text="#111111" bgcolor="#FFFFFF" 
+			link="#376590" vlink="#551A8B" alink="#ffAA28">
+<blockquote>
+<center><h1>database.lsp</h1></center>
+<p><a href="index.html">Module index</a></p><br/><br/><br/><h2>Module:&nbsp;DF.DB, DF.SQL, DF.BLOB</h2><p>Generic database access interface for <a href="http://www.rundragonfly.com">Dragonfly</a> using Objective newLISP</p>
+<b>Version: </b>1.1<br/>
+<b>Author: </b>Greg Slepak<br/>
+<b>Location: </b><a href="http://www.taoeffect.com/newlisp/database.lsp.txt">http://www.taoeffect.com/newlisp/database.lsp.txt</a><br/>
+ <p>The purpose of this module is to standardize the interface to
+ access databases. This will allow you, for the most part, to write your code once
+ and easily switch the type of database that you're using.</p>
+ <p>To accomplish this, the interface introduces three Objective newLISP classes:
+ <tt>DF.DB</tt>, <tt>DF.SQL</tt>, and <tt>DF.BLOB</tt>.</p>
+ <h3>DF.DB</h3>
+ A <tt>DF.DB</tt> object represents a database connection. Using it you connect to
+ the database and execute SQL queries.
+ <h3>DF.SQL</h3>
+ A <tt>DF.SQL</tt> object is a wrapper around an SQL statement, is retrieved through one of
+ two functions: <tt>DF.DB:execute-query</tt> and the lower-level <tt>DF.DB:preprare-sql</tt>.
+ <p>It is used to retrieve rows from the result set of a query one-by-one.</p>
+ <h3>DF.BLOB</h3>
+ <tt>DF.BLOB</tt> is used to insert and retrieve (possibly large) binary data into databases.
+ It is needed for two reasons:
+ <ol>
+ <li>newLISP uses strings to buffer and store binary data, and that's already used to store text.</li>
+ <li>BLOBs can be very large, so by storing them in a context we avoid excessive copying.</li>
+ </ol>
+ <p>Unlike the other two classes, <tt>DF.BLOB</tt> provides a basic working implementation for <tt>DF.SQL</tt> subclasses
+ to use. You may of course subclass it if your database requires additional functionality. It requires
+ special usage considerations, see its documentation below.</p>
+ <h3>Example</h3>
+ <pre>
+ (push-autorelease-pool) ; we<tt>re going to be using DF.BLOB</tt>s.
+ (setf db (instantiate Sqlite3 ":memory:"))
+ (if-not db (throw-error "couldn't open db"))
+ (db:execute-update "CREATE TABLE fish (id INTEGER PRIMARY KEY, name TEXT, weight REAL, blah BLOB)")
+ (db:execute-update "INSERT INTO fish (name,weight) VALUES (?,?)" '("flipper" 234.123))
+ (db:execute-update "INSERT INTO fish (name,weight) VALUES (?1,?2)" '(("?1" "catfish") ("?2" 100.3)))
+ (db:execute-update "INSERT INTO fish (blah) VALUES (?)" (list (DF.BLOB (dup "\000" 10))))
+ (db:execute-update "INSERT INTO fish (blah) VALUES (:cat)" (list (list ":cat" (DF.BLOB (dup "\000" 10)))))
+ (setf sql (db:execute-query "SELECT * FROM fish"))
+ (do-while (list? row)
+     (push-autorelease-pool) ; "in case" we end up fetching a lot of large blobs
+     (setf row (sql:next-row))
+     (println "row: " row)
+     (pop-autorelease-pool)
+ )
+ (deallocate sql)
+ (deallocate db)
+ (pop-autorelease-pool) ; deallocate the blobs we created</pre>
+ <h3>Requirements</h3>
+ <ul>
+ <li>Dragonfly newLISP Web Framework (see note below)</li>
+ <li>newLISP 10.1.9 or higher is <b>strongly recommended</b>, but any version after 10.1 should work.</li>
+ <li>Objective newLISP 1.0</li>
+ <li>Libraries for a supported database</li>
+ </ul><br/>
+ <a href="http://www.rundragonfly.com">Dragonfly</a> is only required for its logging functions. You can easily implement your own
+ versions of <tt>DF:log-err</tt>, <tt>DF:log-debug</tt>, and the other functions found in Dragonfly&apos;s <tt>log.lsp</tt>.
+ <h3>Version history</h3>
+ <b>1.1</b> &bull; <tt>DF.BLOB</tt> added<br/>
+ <b>1.0</b> &bull; initial release
+
+
+
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_DF.DB"></a><h3><font color=#CC0000>DF.DB</font></h3>
+<b>syntax: DF.DB</b><br/>
+ <p>Represents a database connection. You create a DF.DB object
+ like so:</p>
+ <pre>(instantiate <em>DF.DB-Subclass</em> [<em>connection</em> [<em>args...</em>]])</pre>
+ <p>What type should be represented by <em>connection</em> is undefined, but
+ it&apos;s recommended that subclasses use strings. If <em>connection</em> is specified
+ the a connected instance must be returned (or <tt>nil</tt> upon failure).</p>
+ <p>The possibly optional <em>args...</em> are specific to which subclass you're using. See its
+ corresponding documentation.</p>
+ <p>Instances must have code in their <tt>dealloc</tt> method so that they can properly cleanup their resources
+ (e.g. shutdown connection) if deallocated with <tt>deallocate</tt>.</p>
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_open"></a><h3><font color=#CC0000>DF.DB:open</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:open</font> <em>connection</em>)</b><br/>
+ <p>Returns <tt>true</tt> if the connection was opened successfully, <tt>nil</tt>
+ if there was an error opening the connection, or throws an exception
+ if already connected.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_close"></a><h3><font color=#CC0000>DF.DB:close</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:close</font>)</b><br/>
+ <p>Returns <tt>true</tt> if the connection was closed successfully or was
+ already closed, or <tt>nil</tt> if there was an error closing the connection.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_prepare-sql"></a><h3><font color=#CC0000>DF.DB:prepare-sql</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:prepare-sql</font> <em>str-sql</em>)</b><br/>
+<b>parameter: </b><em>str-sql</em> - A single SQL statement. Does not need to end in ';'<br/>
+ <p>Returns a <tt>DF.SQL</tt> object upon success, <tt>nil</tt> on failure, or throws
+ an exception if not connected.</p>
+ <p><b>important:</b> If your SQL statement contains placeholders (to be
+ bound later using <tt>DF.SQL:bind-params</tt>) you may not mix and match placeholder styles!
+ Pick one placeholder style and stick with it for the entire statement.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_execute-update"></a><h3><font color=#CC0000>DF.DB:execute-update</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:execute-update</font> <em>str-sql</em> [<em>list-params</em>])</b><br/>
+<b>parameter: </b><em>str-sql</em> - A single SQL statement. Does not need to end in ';'<br/>
+<b>parameter: </b><em>list-params</em> - A list of parameters to bind to a parameterized query<br/>
+ <p>Same as <tt>DF.DB:execute-query</tt> but returns <tt>true</tt> instead of a <tt>DF.SQL</tt> object upon success.
+ Useful for SQL such as "UPDATE" and "INSERT".</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_execute-query"></a><h3><font color=#CC0000>DF.DB:execute-query</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:execute-query</font> <em>str-sql</em> [<em>list-params</em>])</b><br/>
+<b>parameter: </b><em>str-sql</em> - A single SQL statement. Does not need to end in ';'<br/>
+<b>parameter: </b><em>list-params</em> - A list of parameters to bind to a parameterized query<br/>
+ <p>A short-hand for <tt>DF.DB:prepare-sql</tt> and <tt>DF.SQL:bind-params</tt>. Returns
+ a <tt>DF.SQL</tt> object upon success, <tt>nil</tt> on failure, or throws an exception if
+ not connected.</p>
+ <p><b>see:</b> documentation for <tt>DF.SQL:bind-params</tt> for more info on <em>list-params</em>.
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_rows-for-query"></a><h3><font color=#CC0000>DF.DB:rows-for-query</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:rows-for-query</font> <em>str-sql</em> [<em>list-params</em>])</b><br/>
+ <p>Same as <tt>DF.DB:execute-query</tt> but retrieves all of the rows and returns them as a list of results.</p>
+ <p><b>important:</b> If any columns contain BLOB types, you <b><i>must</i></b> have
+ an autorelease pool allocated prior to calling this function!</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_rowid"></a><h3><font color=#CC0000>DF.DB:rowid</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:rowid</font>)</b><br/>
+ <p>Returns the row id for the last row that was inserted or throws an
+ exception if not connected.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_changes"></a><h3><font color=#CC0000>DF.DB:changes</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:changes</font>)</b><br/>
+ <p>Returns how many rows were affected by the last INSERT/UPDATE, or throws
+ an exception of not connected</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_version"></a><h3><font color=#CC0000>DF.DB:version</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:version</font>)</b><br/>
+ <p>Returns the version number of the database library being used as an integer.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_table-exists?"></a><h3><font color=#CC0000>DF.DB:table-exists?</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:table-exists?</font> <em>table-name</em>)</b><br/>
+ <p>Returns nil or non-nil depending on whether the table named <tt>table-name</tt> exists,
+ or throws an exception if not connected.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_connected?"></a><h3><font color=#CC0000>DF.DB:connected?</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:connected?</font>)</b><br/>
+<p><b>return: </b>nil or non-nil depending on whether this <tt>DF.DB</tt> object has an active connection.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.DB_last-error"></a><h3><font color=#CC0000>DF.DB:last-error</font></h3>
+<b>syntax: (<font color=#CC0000>DF.DB:last-error</font>)</b><br/>
+<p><b>return: </b>a list of two elements: the most recent error code and a description string.</p>
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_DF.SQL"></a><h3><font color=#CC0000>DF.SQL</font></h3>
+<b>syntax: DF.SQL</b><br/>
+ <p>Represents a prepared statement. It is used to bind values to a statement's parameters
+ and retrieve the results of a query.</p>
+ <p>You do not create a DF.SQL instance yourself but obtain one through <tt>DF.DB:prepare-sql</tt>.
+ However, if you've obtained an instance then you are responsible for freeing its memory
+ and closing its connection when you're finished with it.</p>
+ <p>Subclasses should make sure that their <tt>dealloc</tt> method calls <tt>DF.SQL:close</tt> so that
+ statements can be freed and closed in one function call using <tt>deallocate</tt>.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.SQL_bind-params"></a><h3><font color=#CC0000>DF.SQL:bind-params</font></h3>
+<b>syntax: (<font color=#CC0000>DF.SQL:bind-params</font> <em>list-params</em>)</b><br/>
+ <p>Binds the placeholders of this SQL statement to the values in <em>list-params</em>.</p>
+ <p><em>list-params</em> may be simply a list of values, or an association list of key/value
+ pairs, depending on the placeholder pattern used in the SQL. Placeholder styles
+ <b>may not</b> be mixed per SQL statement.</p>
+ <p>Values may be any of newLISP's primitives. To specify a BLOB wrap your string
+ in a <tt>DF.BLOB</tt>:</p>
+ <b>example:</b>
+ <pre>
+ ; "weight" is a REAL and "blah" is a BLOB
+ (push-autorelease-pool) ; create our autorelease pool since we're using DF.BLOB
+ (setf sql (db:prepare-sql "INSERT INTO fish (weight,blah) VALUES (?,?)"))
+ (sql:bind-params (list 1043.3 (DF.BLOB (dup "\000" 5))))
+ (println (sql:next-row))
+ (deallocate sql)
+ (pop-autorelease-pool)
+ </pre>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.SQL_next-row"></a><h3><font color=#CC0000>DF.SQL:next-row</font></h3>
+<b>syntax: (<font color=#CC0000>DF.SQL:next-row</font>)</b><br/>
+ <p>Returns a row as a list from the result set of a statement, <tt>true</tt> if
+ there are no more rows to return, or <tt>nil</tt> if there was an error.</p>
+ <b>example:</b>
+ <pre> (push-autorelease-pool) ; only necessary if there's a BLOB column
+ (while (list? (setf row (sql:next-row)))
+ 	(println "row: " row)
+ )
+ (pop-autorelease-pool) ; free any blobs</pre>
+ <p><b>important:</b> If any columns contain BLOB types, you <b><i>must</i></b> have
+ an autorelease pool allocated prior to calling this function!</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.SQL_reset"></a><h3><font color=#CC0000>DF.SQL:reset</font></h3>
+<b>syntax: (<font color=#CC0000>DF.SQL:reset</font>)</b><br/>
+ <p>Resets the statement so that it can be re-used without preparing another
+ statement (which is more efficient). After reseting a statement you typically
+ use <tt>DF.SQL:bind-params</tt> to bind new values and then <tt>DF.SQL:next-row</tt>.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.SQL_close"></a><h3><font color=#CC0000>DF.SQL:close</font></h3>
+<b>syntax: (<font color=#CC0000>DF.SQL:close</font>)</b><br/>
+ <p>Releases the resources used by the SQL statement represented by this object.
+ You cannot use it anymore after calling this method, the only thing left to do
+ is to <tt>deallocate</tt> it, and since sublasses of <tt>DF.SQL</tt> must call <tt>close</tt> in
+ their <tt>dealloc</tt> methods, it&apos;s often simpler to call <tt>deallocate</tt> on the object instead.</p>
+ <p>Returns <tt>true</tt> upon success, <tt>nil</tt> on failure or if already closed.</p>
+
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="DF.BLOB_DF.BLOB"></a><h3><font color=#CC0000>DF.BLOB:DF.BLOB</font></h3>
+<b>syntax: (<font color=#CC0000>DF.BLOB:DF.BLOB</font> <em>str-blob</em>)</b><br/>
+ <p>An object wrapper around a blob of data represented by <em>str-blob</em>, used
+ for efficient passing of possibly large binary data.</p>
+ <p>Unlike most other <tt>ObjNL</tt> classes, you typically create an instance
+ by simply calling its constructor instead of calling <tt>instantiate</tt> yourself.
+ It will then <tt>instantiate</tt> and <tt>autorelease</tt> a <tt>DF.BLOB</tt> instance containing the data
+ in <tt>DF.BLOB:blob</tt>.</p>
+ <p><b>important:</b> An autorelease pool <b>must</b> be in place when using the
+ constructor to instantiate a blob!</p>
+ <p><b>see:</b> the introduction to this document for example usage.</p>
+
+
+<br/><br/><center>- &part; -</center><br/>
+<center><font face='Arial' size='-2' color='#444444'>
+generated with <a href="http://newlisp.org">newLISP</a>&nbsp;
+and <a href="http://newlisp.org/newLISPdoc.html">newLISPdoc</a>
+</font></center>
+</blockquote>
+</body>
+</html>

File example-site/dragonfly-api/DF.DB/database_sqlite3.lsp.html

+<!DOCTYPE HTML PUBLIC "HTML 4.01 Transitional">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>database_sqlite3.lsp</title>
+
+<link rel="stylesheet" type="text/css" href="newlispdoc.css" />
+</head>
+
+<body style="margin: 20px;" text="#111111" bgcolor="#FFFFFF" 
+			link="#376590" vlink="#551A8B" alink="#ffAA28">
+<blockquote>
+<center><h1>database_sqlite3.lsp</h1></center>
+<p><a href="index.html">Module index</a></p><br/><br/><br/><h2>Module:&nbsp;Sqlite3</h2><p>SQLite3 subclass of DF.DB. Only lists Sqlite3 specific functions.</p>
+<b>Version: </b>1.1.1<br/>
+<b>Author: </b>Greg Slepak <br/>
+<b>Location: </b><a href="http://www.taoeffect.com/newlisp/database_sqlite3.lsp.txt">http://www.taoeffect.com/newlisp/database_sqlite3.lsp.txt</a><br/>
+ <h3>Features not found in newLISP's sqlite3.lsp:</h3>
+ <ul>
+ <li>Multiple connections</li>
+ <li>Multiple active SQL statements</li>
+ <li>Supports reuse of SQL statements through parameter rebinding</li>
+ <li>Supports BLOB data-type as per <tt>DF.DB</tt> and <tt>DF.BLOB</tt> specification</li>
+ <li>Conforms to generic <tt>DF.DB</tt> interface</li>
+ <li>Grabs integers directly through 64-bit function</li>
+ <li>Can go through results row-by-row</li>
+ <li>Allows specification of custom sqlite3 library page with <tt>SQLITE3_LIBRARY_PATH</tt></li>
+ <li>Uses the latest Sqlite3 library functions if they are available</li>
+ <li>Better error handling</li>
+ </ul>
+ <h3>Requirements</h3>
+ See module <a href="http://www.taoeffect.com/newlisp/database.lsp.html">DF.DB</a> for requirements.
+ <h3>Version history</h3>
+ <b>1.1.1</b> &bull; improved readability in error logging, fixed binding of integers on 32-bit newlisp builds<br/>
+ <b>1.1.0</b> &bull; support for <tt>DF.BLOB</tt><br/>
+ <b>1.0.0</b> &bull; initial release
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_Sqlite3"></a><h3><font color=#CC0000>Sqlite3</font></h3>
+<b>syntax: Sqlite3</b><br/>
+ <p>Represents a connection to an SQLite3 database. Create one like so:</p>
+ <pre>(instantiate Sqlite3 [<em>str-filepath</em> [<em>flags</em> [<em>vfs-module</em>]]])</pre>
+ <p>If <em>str-filepath</em> is specified a connected instance will be returned or <tt>nil</tt>
+ upon failure to connect. If they are not specified then an unconnected instance
+ will be returned.</p>
+ <p><b>see:</b> documentation for <tt>Sqlite3:open</tt> for an explanation of the parameters.</p>
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="Sqlite3_open"></a><h3><font color=#CC0000>Sqlite3:open</font></h3>
+<b>syntax: (<font color=#CC0000>Sqlite3:open</font> <em>str-filepath</em> [<em>flags</em> [<em>vfs-module</em>]])</b><br/>
+ <p><em>str-filepath</em> specifies the path to the sqlite3 database, but it can also be
+ ":memory:" to indicate an in-memory database.</p>
+ <p><em>flags</em> and <em>vfs-module</em> are optional parameters as defined in the sqlite
+ reference <a href="http://www.sqlite.org/c3ref/open.html">documentation</a> for
+ <tt>sqlite3_open_v2</tt>. Your installation of sqlite3 may need to be updated for this to be available.</p>
+ <p>For return values see <tt>DF.DB:open</tt>.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="Sqlite3_set-timeout"></a><h3><font color=#CC0000>Sqlite3:set-timeout</font></h3>
+<b>syntax: (<font color=#CC0000>Sqlite3:set-timeout</font> <em>int-ms</em>)</b><br/>
+ <p>Sets the sqlite3's busy timeout for this connection in milliseconds.</p>
+ <p>By default the timeout is set to 30 seconds.</p>
+<p><b>return: </b>nil or non-nil on success</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<br/><br/><center>- &part; -</center><br/>
+<center><font face='Arial' size='-2' color='#444444'>
+generated with <a href="http://newlisp.org">newLISP</a>&nbsp;
+and <a href="http://newlisp.org/newLISPdoc.html">newLISPdoc</a>
+</font></center>
+</blockquote>
+</body>
+</html>

File example-site/dragonfly-api/DF.DB/index.html

+<!DOCTYPE HTML PUBLIC "HTML 4.01 Transitional">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Index</title>
+
+<link rel="stylesheet" type="text/css" href="newlispdoc.css" />
+</head>
+
+<body style="margin: 20px;" text="#111111" bgcolor="#FFFFFF" 
+			link="#376590" vlink="#551A8B" alink="#ffAA28">
+<blockquote>
+<center><h1>Index</h1></center>
+<a href="database.lsp.html"><br/><br/><h2>Module:&nbsp;DF.DB, DF.SQL, DF.BLOB</h2></a>
+<p>Generic database access interface for <a href="http://www.rundragonfly.com">Dragonfly</a> using Objective newLISP</p>
+<a href="database.lsp.html#_DF.DB">DF.DB</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_open">open</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_close">close</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_prepare-sql">prepare-sql</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_execute-update">execute-update</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_execute-query">execute-query</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_rows-for-query">rows-for-query</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_rowid">rowid</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_changes">changes</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_version">version</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_table-exists?">table-exists?</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_connected?">connected?</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.DB_last-error">last-error</a>&nbsp; &nbsp; <a href="database.lsp.html#_DF.SQL">DF.SQL</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.SQL_bind-params">bind-params</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.SQL_next-row">next-row</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.SQL_reset">reset</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.SQL_close">close</a>&nbsp; &nbsp; <a href="database.lsp.html#DF.BLOB_DF.BLOB">DF.BLOB</a>&nbsp; &nbsp; <a href="database_sqlite3.lsp.html"><br/><br/><h2>Module:&nbsp;Sqlite3</h2></a>
+<p>SQLite3 subclass of DF.DB. Only lists Sqlite3 specific functions.</p>
+<a href="database_sqlite3.lsp.html#_Sqlite3">Sqlite3</a>&nbsp; &nbsp; <a href="database_sqlite3.lsp.html#Sqlite3_open">open</a>&nbsp; &nbsp; <a href="database_sqlite3.lsp.html#Sqlite3_set-timeout">set-timeout</a>&nbsp; &nbsp; 
+<br/><br/><center>- &part; -</center><br/>
+<center><font face='Arial' size='-2' color='#444444'>
+generated with <a href="http://newlisp.org">newLISP</a>&nbsp;
+and <a href="http://newlisp.org/newLISPdoc.html">newLISPdoc</a>
+</font></center>
+</blockquote>
+</body>
+</html>

File example-site/dragonfly-api/SMTP/index.html

+<!DOCTYPE HTML PUBLIC "HTML 4.01 Transitional">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Index</title>
+
+<link rel="stylesheet" type="text/css" href="newlispdoc.css" />
+</head>
+
+<body style="margin: 20px;" text="#111111" bgcolor="#FFFFFF" 
+			link="#376590" vlink="#551A8B" alink="#ffAA28">
+<blockquote>
+<center><h1>Index</h1></center>
+<a href="smtp.lsp.html"><br/><br/><h2>Module:&nbsp;smtp.lsp </h2></a>
+<p>Send mail using SMTP protocol</p>
+<a href="smtp.lsp.html#SMTP_send-mail">send-mail</a>&nbsp; &nbsp; <a href="smtp.lsp.html#SMTP_get-error-text">get-error-text</a>&nbsp; &nbsp; <a href="smtp.lsp.html#SMTP_clear-attachments">clear-attachments</a>&nbsp; &nbsp; <a href="smtp.lsp.html#SMTP_attach-document">attach-document</a>&nbsp; &nbsp; <a href="smtp.lsp.html#SMTP_encode64-widthsafe">encode64-widthsafe</a>&nbsp; &nbsp; <a href="smtp.lsp.html#SMTP_encode64-line">encode64-line</a>&nbsp; &nbsp; 
+<br/><br/><center>- &part; -</center><br/>
+<center><font face='Arial' size='-2' color='#444444'>
+generated with <a href="http://newlisp.org">newLISP</a>&nbsp;
+and <a href="http://newlisp.org/newLISPdoc.html">newLISPdoc</a>
+</font></center>
+</blockquote>
+</body>
+</html>

File example-site/dragonfly-api/SMTP/smtp.lsp.html

+<!DOCTYPE HTML PUBLIC "HTML 4.01 Transitional">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>smtp.lsp</title>
+
+<link rel="stylesheet" type="text/css" href="newlispdoc.css" />
+</head>
+
+<body style="margin: 20px;" text="#111111" bgcolor="#FFFFFF" 
+			link="#376590" vlink="#551A8B" alink="#ffAA28">
+<blockquote>
+<center><h1>smtp.lsp</h1></center>
+<p><a href="index.html">Module index</a></p><br/><br/><br/><h2>Module:&nbsp;smtp.lsp </h2><p>Send mail using SMTP protocol</p>
+<b>Version: </b>3.0 - Partial rewrite for Dragonfly. Addition attachments, custom port and proper utf8 encoding for subject/message/attachments<br/>
+<b>Version: </b>2.3 - fix in mail-send-body, thanks to Alessandro<br/>
+<b>Version: </b>2.2 - doc changes<br/>
+<b>Version: </b>2.1 - changes for 10.0<br/>
+<b>Version: </b>2.0 - March 2008, Cormullion added AUTH PLAIN authentication <br/>
+<b>Author: </b>Lutz Mueller 2001-2009, Cormullion 2008, Greg Slepak 2009-2010<br/>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_send-mail"></a><h3><font color=#CC0000>SMTP:send-mail</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:send-mail</font> <em>str-from</em> <em>str-to</em> <em>str-subject</em> <em>str-message</em> [<em>str-server</em> [<em>str-usr</em> <em>str-pass</em> [<em>int-port</em>]]])</b><br/>
+<b>parameter: </b><em>str-from</em> - The email address of the sender.<br/>
+<b>parameter: </b><em>str-to</em> - The email address of the recipient.<br/>
+<b>parameter: </b><em>str-subject</em> - The subject line of the email.<br/>
+<b>parameter: </b><em>str-message</em> - The message part of the email.<br/>
+<b>parameter: </b><em>str-server</em> - The address of the SMTP server (default: "localhost")<br/>
+<b>parameter: </b><em>str-user</em> - Optional user name for authentication.<br/>
+<b>parameter: </b><em>str-pass</em> - Optional password for authentication.<br/>
+<b>parameter: </b><em>int-port</em> - Optional port to communicate on (default: 25)<br/>
+<p><b>return: </b>On success <tt>true</tt>, on failure <tt>nil</tt>.</p>
+ In case the function fails returning <tt>nil</tt>, the function
+ <tt>SMTP:get-error-text</tt> can be used to receive the error text.
+<br/><br/>
+<b>example:</b><blockquote><pre> (SMTP:send-mail "jdoe@asite.com" "somebody@isp.com" "Greetings" 
+   "How are you today? - john doe -" "smtp.asite.com" "jdoe" "secret") 
+ 
+ This logs in to the server, tries to authenticate using the username 'jdoe' and password 'secret' (if supplied), 
+ and sends an email with the format: 
+
+  From:    jdoe@asite.com 
+  To:      somebody@isp.com 
+  Subject: Greetings 
+  Message: How are you today? - John Doe - </pre></blockquote>
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_get-error-text"></a><h3><font color=#CC0000>SMTP:get-error-text</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:get-error-text</font>)</b><br/>
+ <p>Call this to get the reason <tt>send-mail</tt> returned <tt>nil</tt>.</p>
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_clear-attachments"></a><h3><font color=#CC0000>SMTP:clear-attachments</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:clear-attachments</font>)</b><br/>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_attach-document"></a><h3><font color=#CC0000>SMTP:attach-document</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:attach-document</font> <em>str-content</em> <em>str-filename</em> [<em>str-disposition</em> [<em>str-mime-type</em> [<em>str-encoding</em>]]])</b><br/>
+<b>parameter: </b><em>str-content</em> - The attachment data.<br/>
+<b>parameter: </b><em>str-filename</em> - How you'd like your attachment to appear named in the email.<br/>
+<b>parameter: </b><em>str-disposition</em> - "attachment" or "inline". default is "attachment".<br/>
+<b>parameter: </b><em>str-mime-type</em> - default is "application/octet-stream".<br/>
+<b>parameter: </b><em>str-encoding</em> - default is "base64". If <tt>encoding</tt> is "base64" it will be automatically transformed using <tt>encode64-widthsafe</tt><br/>
+
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_encode64-widthsafe"></a><h3><font color=#CC0000>SMTP:encode64-widthsafe</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:encode64-widthsafe</font> <em>buff-data</em>)</b><br/>
+ <p>Useful for attaching binary data such as images. Converts the data into base64
+ and chops it up so that the lines are not longer than 76 characters long, making
+ it safe to include in the body of emails.</p>
+ <p>If the attachment's encoding to "base64" (which it is by default), this function
+ will automatically applied to the <em>str-content</em> of the email.</p>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="SMTP_encode64-line"></a><h3><font color=#CC0000>SMTP:encode64-line</font></h3>
+<b>syntax: (<font color=#CC0000>SMTP:encode64-line</font> <em>str-line</em>)</b><br/>
+ <p>Creates a base64 UTF-8 compatible string, suitable for including foreign characters
+ in the subjects of emails. This is used by <tt>send-mail</tt> automatically on the filename
+ of any attachments, as well as the subject of the email.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<br/><br/><center>- &part; -</center><br/>
+<center><font face='Arial' size='-2' color='#444444'>
+generated with <a href="http://newlisp.org">newLISP</a>&nbsp;
+and <a href="http://newlisp.org/newLISPdoc.html">newLISPdoc</a>
+</font></center>
+</blockquote>
+</body>
+</html>

File example-site/dragonfly-api/dragonfly.lsp.html

 
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="_DFLY_PAGE"></a><h3><font color=#CC0000>DFLY_PAGE</font></h3>
-<b>syntax: DFLY_PAGE</b><br/>
+<a name="_DF_PAGE"></a><h3><font color=#CC0000>DF_PAGE</font></h3>
+<b>syntax: DF_PAGE</b><br/>
  <p>The web-friendly, host-unqualified URL to the "current page"</p>
  <pre> ; load http://www.mysite.com/foo/bar?baz
- DFLY_PAGE ;=> "/foo/bar"
+ DF_PAGE ;=> "/foo/bar"
  ; load http://www.mysite.com
- DFLY_PAGE ;=> "/"</pre>
+ DF_PAGE ;=> "/"</pre>
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="_DFLY_SELF"></a><h3><font color=#CC0000>DFLY_SELF</font></h3>
-<b>syntax: DFLY_SELF</b><br/>
+<a name="_DF_SELF"></a><h3><font color=#CC0000>DF_SELF</font></h3>
+<b>syntax: DF_SELF</b><br/>
  <p>The full, local path (on the server) to the currently loaded file
  or view being displayed.</p>
  <b>example:</b>
  <pre> ; load http://www.mysite.com/foo/bar?baz
- DFLY_SELF ;=> "/home/www/mysite.com/foo/bar.html"</pre>
- <b>see:</b> the <tt>SET_DFLY_SELF</tt> function in utils.lsp for more info
+ DF_SELF ;=> "/home/www/mysite.com/foo/bar.html"</pre>
+ <b>see:</b> the <tt>SET_DF_SELF</tt> function in utils.lsp for more info
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="_DFLY_SELF_DIR"></a><h3><font color=#CC0000>DFLY_SELF_DIR</font></h3>
-<b>syntax: DFLY_SELF_DIR</b><br/>
+<a name="_DF_SELF_DIR"></a><h3><font color=#CC0000>DF_SELF_DIR</font></h3>
+<b>syntax: DF_SELF_DIR</b><br/>
  <p>The full, local path (on the server) to the directory holding
  the currently loaded file or view being displayed.</p>
  <b>example:</b>
  <pre> ; load http://www.mysite.com/foo/bar?baz
- DFLY_SELF_DIR ;=> "/home/www/mysite.com/foo/"</pre>
- <b>see:</b> the <tt>SET_DFLY_SELF</tt> function in utils.lsp for more info
+ DF_SELF_DIR ;=> "/home/www/mysite.com/foo"</pre>
+ <b>see:</b> the <tt>SET_DF_SELF</tt> function in utils.lsp for more info
 
 
 
 
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_activate-plugin"></a><h3><font color=#CC0000>Dragonfly:activate-plugin</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:activate-plugin</font> <em>str-plugin-name</em> [<em>str-plugin-name-2</em> ...])</b><br/>
+<a name="DF_activate-plugin"></a><h3><font color=#CC0000>DF:activate-plugin</font></h3>
+<b>syntax: (<font color=#CC0000>DF:activate-plugin</font> <em>str-plugin-name</em> [<em>str-plugin-name-2</em> ...])</b><br/>
 <b>parameter: </b><em>str-plugin-name</em> - The name of the plugin to load, without the ".lsp" extension.<br/>
  <br>Loads (once only) a the named plugin from the <tt>plugins-inactive</tt> folder.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_web-root"></a><h3><font color=#CC0000>Dragonfly:web-root</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:web-root</font> [<em>str-path</em> [<em>bool-question-mark</em>]])</b><br/>
+<a name="DF_web-root"></a><h3><font color=#CC0000>DF:web-root</font></h3>
+<b>syntax: (<font color=#CC0000>DF:web-root</font> [<em>str-path</em> [<em>bool-question-mark</em>]])</b><br/>
 <b>parameter: </b><em>str-path</em> - Path relative to the folder containing <tt>index.cgi</tt>.<br/>
 <b>parameter: </b><em>bool-question-mark</em> - Whether to return a URL with /? prepended.<br/>
  <p>This function is quite handy for making working links when your <tt>index.cgi</tt> file
  (web-root "/foo" true) =&gt; "/example-site/?foo"
  (web-root) =&gt; /example-site/</pre></blockquote>
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_view-path"></a><h3><font color=#CC0000>Dragonfly:view-path</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:view-path</font> <em>str-view-name</em>)</b><br/>
+<a name="DF_view-path"></a><h3><font color=#CC0000>DF:view-path</font></h3>
+<b>syntax: (<font color=#CC0000>DF:view-path</font> <em>str-view-name</em>)</b><br/>
 <b>parameter: </b><em>str-view-name</em> - Name of view in <tt>VIEWS_PATH</tt>, without any extension.<br/>
  <br>Returns the absolute path to the view as a string, appending <tt>VIEW_EXTENSION</tt> if necessary.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_partial-path"></a><h3><font color=#CC0000>Dragonfly:partial-path</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:partial-path</font> <em>str-partial-name</em>)</b><br/>
+<a name="DF_partial-path"></a><h3><font color=#CC0000>DF:partial-path</font></h3>
+<b>syntax: (<font color=#CC0000>DF:partial-path</font> <em>str-partial-name</em>)</b><br/>
  <br>Just like <tt>view-path</tt>, except for partials in <tt>PARTIALS_PATH</tt>.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_resource-path"></a><h3><font color=#CC0000>Dragonfly:resource-path</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:resource-path</font> <em>str-resource-name</em>)</b><br/>
+<a name="DF_resource-path"></a><h3><font color=#CC0000>DF:resource-path</font></h3>
+<b>syntax: (<font color=#CC0000>DF:resource-path</font> <em>str-resource-name</em>)</b><br/>
  <br>Similar to <tt>view-path</tt>, except for resources in <tt>RESOURCES_PATH</tt>.
  Don't include the .lsp extension.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_include"></a><h3><font color=#CC0000>Dragonfly:include</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:include</font>)</b><br/>
+<a name="DF_include"></a><h3><font color=#CC0000>DF:include</font></h3>
+<b>syntax: (<font color=#CC0000>DF:include</font>)</b><br/>
  <br>Like <tt>display-file</tt> but does not pass the file through <tt>eval-template</tt>.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_display-file"></a><h3><font color=#CC0000>Dragonfly:display-file</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:display-file</font>)</b><br/>
+<a name="DF_display-file"></a><h3><font color=#CC0000>DF:display-file</font></h3>
+<b>syntax: (<font color=#CC0000>DF:display-file</font>)</b><br/>
  <br>String-concats its arguments and displays the file
  at that path after passing it through <tt>eval-template</tt>.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_display-partial"></a><h3><font color=#CC0000>Dragonfly:display-partial</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:display-partial</font> <em>str-partial-name</em>)</b><br/>
+<a name="DF_display-partial"></a><h3><font color=#CC0000>DF:display-partial</font></h3>
+<b>syntax: (<font color=#CC0000>DF:display-partial</font> <em>str-partial-name</em>)</b><br/>
  Displays the partial named <em>str-partial-name</em> using <tt>display-file</tt> and <tt>partial-path</tt>.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_display-view"></a><h3><font color=#CC0000>Dragonfly:display-view</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:display-view</font> <em>str-view-name</em>)</b><br/>
+<a name="DF_display-view"></a><h3><font color=#CC0000>DF:display-view</font></h3>
+<b>syntax: (<font color=#CC0000>DF:display-view</font> <em>str-view-name</em>)</b><br/>
  Displays the view named <em>str-view-name</em> using <tt>display-file</tt> and <tt>view-path</tt>.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_display-error"></a><h3><font color=#CC0000>Dragonfly:display-error</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:display-error</font> <em>int-error-code</em>)</b><br/>
+<a name="DF_display-error"></a><h3><font color=#CC0000>DF:display-error</font></h3>
+<b>syntax: (<font color=#CC0000>DF:display-error</font> <em>int-error-code</em>)</b><br/>
  <br>Sends the <em>int-error-code</em> and, if it exists, displays the view named
  <em>int-error-code</em> using <tt>display-view</tt>. Otherwise, displays the built-in error
  template <tt>Dragonfly:ERROR_TEMPLATE</tt>.
  with an <em>int-error-code</em> of 500 (Internal Server Error).
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_eval-template"></a><h3><font color=#CC0000>Dragonfly:eval-template</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:eval-template</font> <em>str</em> [<em>ctx</em>])</b><br/>
+<a name="DF_eval-template"></a><h3><font color=#CC0000>DF:eval-template</font></h3>
+<b>syntax: (<font color=#CC0000>DF:eval-template</font> <em>str</em> [<em>ctx</em>])</b><br/>
 <b>parameter: </b><em>str</em> - A string containing the template.<br/>
 <b>parameter: </b><em>ctx</em> - Optional. Represents the context the template is evaluted in. Defaults to Dragonfly.<br/>
  <br>newLISP code in the template between the <tt>OPEN_TAG</tt> and <tt>CLOSE_TAG</tt> (see <tt>config.lsp</tt>) is
  evaluated, and the result, along with the text outside of the "code islands" will be sent if no errors occur.
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="Dragonfly_die"></a><h3><font color=#CC0000>Dragonfly:die</font></h3>
-<b>syntax: (<font color=#CC0000>Dragonfly:die</font>)</b><br/>
+<a name="DF_die"></a><h3><font color=#CC0000>DF:die</font></h3>
+<b>syntax: (<font color=#CC0000>DF:die</font>)</b><br/>
  <br>String-concats its arguments, logs them as an error via <tt>log-err</tt>, and calls
  <tt>throw-error</tt> with the same string.
 <br/><br/>

File example-site/dragonfly-api/gendocs

 # place ObjNL.lsp at the bottom
 newlispdoc ../dragonfly-framework/dragonfly.lsp `find -E ../dragonfly-framework/lib -regex "[./a-z_-]+lsp" | xargs` ../dragonfly-framework/lib/ObjNL.lsp
 
+if [ ! -d ./DF.DB ] ; then
+	mkdir -v DF.DB
+fi
+
 # we link to DF.DB etc from the guide on included plugins
+
+cd DF.DB
+
+newlispdoc ../../dragonfly-framework/plugins-inactive/db/*.lsp
+
+cd ..
+
+if [ ! -d ./SMTP ] ; then
+	mkdir -v SMTP
+fi
+
+cd SMTP
+
+newlispdoc ../../dragonfly-framework/plugins-inactive/smtp.lsp
+
+cd ..
+

File example-site/dragonfly-api/index.html

 <center><h1>Index</h1></center>
 <a href="dragonfly.lsp.html"><br/><br/><h2>Module:&nbsp;dragonfly.lsp</h2></a>
 <p>The heart of Dragonfly - A newLISP web framework for rapid web development.</p>
-<a href="dragonfly.lsp.html#_DFLY_PAGE">DFLY_PAGE</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_DFLY_SELF">DFLY_SELF</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_DFLY_SELF_DIR">DFLY_SELF_DIR</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_STDOUT">STDOUT</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_activate-plugin">activate-plugin</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_web-root">web-root</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_view-path">view-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_partial-path">partial-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_resource-path">resource-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_include">include</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_display-file">display-file</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_display-partial">display-partial</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_display-view">display-view</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_display-error">display-error</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_eval-template">eval-template</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#Dragonfly_die">die</a>&nbsp; &nbsp; <a href="log.lsp.html"><br/><br/><h2>Module:&nbsp;log.lsp</h2></a>
+<a href="dragonfly.lsp.html#_DF_PAGE">DF_PAGE</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_DF_SELF">DF_SELF</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_DF_SELF_DIR">DF_SELF_DIR</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#_STDOUT">STDOUT</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_activate-plugin">activate-plugin</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_web-root">web-root</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_view-path">view-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_partial-path">partial-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_resource-path">resource-path</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_include">include</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_display-file">display-file</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_display-partial">display-partial</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_display-view">display-view</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_display-error">display-error</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_eval-template">eval-template</a>&nbsp; &nbsp; <a href="dragonfly.lsp.html#DF_die">die</a>&nbsp; &nbsp; <a href="log.lsp.html"><br/><br/><h2>Module:&nbsp;log.lsp</h2></a>
 <p>Provides convenient logging facility for all of Dragonfly.</p>
 <a href="log.lsp.html#Dragonfly_log-func">log-func</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-debug">log-debug</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-info">log-info</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-warn">log-warn</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-err">log-err</a>&nbsp; &nbsp; <a href="request.lsp.html"><br/><br/><h2>Module:&nbsp;request.lsp</h2></a>
 <p></p>
 <p></p>
 <a href="response.lsp.html#Response_status">status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_header">header</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_cookie">cookie</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers">send-headers</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_redirect">redirect</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers-with-status">send-headers-with-status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_content-type">content-type</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_extension->type">extension->type</a>&nbsp; &nbsp; <a href="utils.lsp.html"><br/><br/><h2>Module:&nbsp;utils.lsp</h2></a>
 <p></p>
-<a href="utils.lsp.html#_add-to-load-path">add-to-load-path</a>&nbsp; &nbsp; <a href="utils.lsp.html#_regex-captcha">regex-captcha</a>&nbsp; &nbsp; <a href="utils.lsp.html#_load-files-in-dir">load-files-in-dir</a>&nbsp; &nbsp; <a href="utils.lsp.html#_wrap-func">wrap-func</a>&nbsp; &nbsp; <a href="utils.lsp.html#_into-ctx-assoc">into-ctx-assoc</a>&nbsp; &nbsp; <a href="utils.lsp.html#_SET_DFLY_SELF">SET_DFLY_SELF</a>&nbsp; &nbsp; <a href="utils.lsp.html#_NEWLISP64">NEWLISP64</a>&nbsp; &nbsp; <a href="utils.lsp.html#_get-ptr">get-ptr</a>&nbsp; &nbsp; <a href="utils.lsp.html#_throw-not-implemented">throw-not-implemented</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html"><br/><br/><h2>Module:&nbsp;ObjNL.lsp</h2></a>
+<a href="utils.lsp.html#_add-to-load-path">add-to-load-path</a>&nbsp; &nbsp; <a href="utils.lsp.html#_file-ext">file-ext</a>&nbsp; &nbsp; <a href="utils.lsp.html#_del-ext">del-ext</a>&nbsp; &nbsp; <a href="utils.lsp.html#_basename">basename</a>&nbsp; &nbsp; <a href="utils.lsp.html#_dirname">dirname</a>&nbsp; &nbsp; <a href="utils.lsp.html#_regex-captcha">regex-captcha</a>&nbsp; &nbsp; <a href="utils.lsp.html#_load-files-in-dir">load-files-in-dir</a>&nbsp; &nbsp; <a href="utils.lsp.html#_wrap-func">wrap-func</a>&nbsp; &nbsp; <a href="utils.lsp.html#_SET_DF_SELF">SET_DF_SELF</a>&nbsp; &nbsp; <a href="utils.lsp.html#_NEWLISP64">NEWLISP64</a>&nbsp; &nbsp; <a href="utils.lsp.html#_get-ptr">get-ptr</a>&nbsp; &nbsp; <a href="utils.lsp.html#_throw-not-implemented">throw-not-implemented</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html"><br/><br/><h2>Module:&nbsp;ObjNL.lsp</h2></a>
 <p>Objective newLISP - Real Object Oriented Programming for newLISP</p>
 <a href="ObjNL.lsp.html#_ObjNL">ObjNL</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_ObjNL">ObjNL</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_dealloc">dealloc</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#ObjNL_equals">equals</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_new-class">new-class</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_instantiate">instantiate</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_add-interface">add-interface</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_deallocate">deallocate</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_implements?">implements?</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_retain">retain</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_release">release</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_autorelease">autorelease</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_push-autorelease-pool">push-autorelease-pool</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_pop-autorelease-pool">pop-autorelease-pool</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_.">.</a>&nbsp; &nbsp; <a href="ObjNL.lsp.html#_.&">.&</a>&nbsp; &nbsp; 
 <br/><br/><center>- &part; -</center><br/>

File example-site/dragonfly-api/utils.lsp.html

  ; no need to update any source files, it just works.</pre>
  <b>warning:</b> Use this function sparingly as name-conflicts could
  result in the wrong file being loaded!
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_file-ext"></a><h3><font color=#CC0000>file-ext</font></h3>
+<b>syntax: (<font color=#CC0000>file-ext</font> <em>str-path</em>)</b><br/>
+ <p>Returns the file extension of the file in <em>str-path</em></p>
+ <pre> (file-ext "")
+ ;=> ""
+ (file-ext "asdf")
+ ;=> ""
+ (file-ext "asdf.")
+ ;=> ""
+ (file-ext "asdf.jpg")
+ ;=> "jpg"</pre>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_del-ext"></a><h3><font color=#CC0000>del-ext</font></h3>
+<b>syntax: (<font color=#CC0000>del-ext</font> <em>str-path</em>)</b><br/>
+ <p>Returns the <em>str-path</em> without the file extension removed.</p>
+ <pre> (del-ext "")
+ ;=> ""
+ (del-ext "asdf")
+ ;=> "asdf"
+ (del-ext "asdf.")
+ ;=> "asdf."
+ (del-ext "asdf.jpg")
+ ;=> "asdf"</pre>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_basename"></a><h3><font color=#CC0000>basename</font></h3>
+<b>syntax: (<font color=#CC0000>basename</font> <em>str-path</em>)</b><br/>
+ <p>Returns the filename component of <em>str-path</em>.</p>
+ <pre> (basename "")
+ ;=> ""
+ (basename "/")
+ ;=> ""
+ (basename "asdf")
+ ;=> "asdf"
+ (basename "/foo/bar")
+ ;=> "bar"
+ (basename "/foo/bar/")
+ ;=> "bar"</pre>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_dirname"></a><h3><font color=#CC0000>dirname</font></h3>
+<b>syntax: (<font color=#CC0000>dirname</font> <em>str-path</em>)</b><br/>
+ <p>Returns the directory path component of <em>str-path</em>.</p>
+ <pre> (dirname "")
+ ;=> ""
+ (dirname "/")
+ ;=> "/"
+ (dirname "asdf")
+ ;=> "."
+ (dirname "/asdf/")
+ ;=> "/"
+ (dirname "asdf/foo")
+ ;=> "asdf"</pre>
+
 <br/><br/><center>- &sect; -</center><br/>
 <a name="_regex-captcha"></a><h3><font color=#CC0000>regex-captcha</font></h3>
 <b>syntax: (<font color=#CC0000>regex-captcha</font> <em>str-regex</em> <em>str</em> [<em>int-options</em>] [<em>int-captcha</em>])</b><br/>
          (throw-error (string "execute-update failed: " $args)))))</pre>
 
 <br/><br/><center>- &sect; -</center><br/>
-<a name="_into-ctx-assoc"></a><h3><font color=#CC0000>into-ctx-assoc</font></h3>
-<b>syntax: (<font color=#CC0000>into-ctx-assoc</font> <em>ctx</em> <em>list-assoc</em>)</b><br/>
- <p>Places the key/value pairs in <em>list-assoc</em> into the context <em>ctx</em>
- to be used as a lookup table.<br/>This is a global function.</p>
- <b>example:</b>
- <pre> (new Tree 'MyCtx)
- (into-ctx-assoc MyCtx '(
-     ("key" "value")
-     ("apple" "mmmm... good")
-     ("organic?" true)
- ))</pre>
-<br/><br/>
-<br/><br/><center>- &sect; -</center><br/>
-<a name="_SET_DFLY_SELF"></a><h3><font color=#CC0000>SET_DFLY_SELF</font></h3>
-<b>syntax: (<font color=#CC0000>SET_DFLY_SELF</font> <em>str-filepath</em>)</b><br/>
+<a name="_SET_DF_SELF"></a><h3><font color=#CC0000>SET_DF_SELF</font></h3>
+<b>syntax: (<font color=#CC0000>SET_DF_SELF</font> <em>str-filepath</em>)</b><br/>
 <b>parameter: </b><em>str-filepath</em> - The path to the file being served, or the primary file responsible for handling this route.<br/>
  <p>Routes should call this global function with the path to the file that's being displayed
  or the file that's principly in charge of handling this route. This function will then
- set the global variables <tt>DFLY_SELF</tt> and <tt>DFLY_SELF_DIR</tt> to point to that file and its
+ set the global variables <tt>DF_SELF</tt> and <tt>DF_SELF_DIR</tt> to point to that file and its
  parent directory, respectively.</p>
  <p>The default routes <tt>Route.Static</tt> and <tt>Route.Resource</tt> call this function first thing
  in their <tt>Route:run</tt> methods, prior to loading the files. This is the recommended way of

File example-site/dragonfly-framework/config.lsp

 (constant (global 'DOCUMENT_ROOT) (env "DOCUMENT_ROOT"))
 ; dragonfly root
 (constant (global 'DRAGONFLY_ROOT) (string DOCUMENT_ROOT "/dragonfly-framework"))
+
 ; ------------------------------------------------------
 ; sync any customization of DOCUMENT_ROOT with the 'env'
 ; don't modify these two lines below!
 (constant (global 'ORIGINAL_ROOT) (env "DOCUMENT_ROOT"))
 (env "DOCUMENT_ROOT" DOCUMENT_ROOT)
 ; ------------------------------------------------------
+
 (context 'Dragonfly)
 
 ;===============================================================================
 ; to the path, which is bound to the '_' symbol). If one of them matches a file,
 ; the entire route matches and the file is passed through the template evaluator,
 ; otherwise it will not match and defer to the other handler(s).
-; Note that these expressions can be used to do more than just match URLs.
 (constant 'STATIC_TRANSFORMATIONS '(
 	(string DOCUMENT_ROOT "/" _ "/index.html")
-	(begin (set 'viewname _) (string VIEWS_PATH "/" _))
-	(begin (set 'viewname _) (string VIEWS_PATH "/" _ VIEW_EXTENSION))
+	(string VIEWS_PATH "/" _)
+	(string VIEWS_PATH "/" _ VIEW_EXTENSION)
 ))
 
 ;===============================================================================

File example-site/dragonfly-framework/dragonfly.lsp

 	(env "QUERY_STRING" QUERY_STRING)
 )
 
-;; @syntax DFLY_PAGE
+;; @syntax DF_PAGE
 ;; <p>The web-friendly, host-unqualified URL to the "current page"</p>
 ;; <pre> ; load http://www.mysite.com/foo/bar?baz
-;; DFLY_PAGE ;=> "/foo/bar"
+;; DF_PAGE ;=> "/foo/bar"
 ;; ; load http://www.mysite.com
-;; DFLY_PAGE ;=> "/"</pre>
+;; DF_PAGE ;=> "/"</pre>
 (if (empty? QUERY_STRING)
-	(constant (global 'DFLY_PAGE) "/")
-	(constant (global 'DFLY_PAGE) (string "/" ((parse QUERY_STRING {[?&]} 0) 0)))
+	(constant (global 'DF_PAGE) "/")
+	(constant (global 'DF_PAGE) (string "/" ((parse QUERY_STRING {[?&]} 0) 0)))
 )
 
-;; @syntax DFLY_SELF
+;; @syntax DF_SELF
 ;; <p>The full, local path (on the server) to the currently loaded file
 ;; or view being displayed.</p>
 ;; <b>example:</b>
 ;; <pre> ; load http://www.mysite.com/foo/bar?baz
-;; DFLY_SELF ;=> "/home/www/mysite.com/foo/bar.html"</pre>
-;; <b>see:</b> the 'SET_DFLY_SELF' function in utils.lsp for more info
+;; DF_SELF ;=> "/home/www/mysite.com/foo/bar.html"</pre>
+;; <b>see:</b> the 'SET_DF_SELF' function in utils.lsp for more info
 
-;; @syntax DFLY_SELF_DIR
+;; @syntax DF_SELF_DIR
 ;; <p>The full, local path (on the server) to the directory holding
 ;; the currently loaded file or view being displayed.</p>
 ;; <b>example:</b>
 ;; <pre> ; load http://www.mysite.com/foo/bar?baz
-;; DFLY_SELF_DIR ;=> "/home/www/mysite.com/foo/"</pre>
-;; <b>see:</b> the 'SET_DFLY_SELF' function in utils.lsp for more info
+;; DF_SELF_DIR ;=> "/home/www/mysite.com/foo"</pre>
+;; <b>see:</b> the 'SET_DF_SELF' function in utils.lsp for more info
 
 ; seed the random number generator immediately.
 (seed (time-of-day))
 ; !Public Functions
 ;===============================================================================
 
-;; @syntax (Dragonfly:activate-plugin <str-plugin-name> [<str-plugin-name-2> ...])
+;; @syntax (DF:activate-plugin <str-plugin-name> [<str-plugin-name-2> ...])
 ;; @param <str-plugin-name> The name of the plugin to load, without the ".lsp" extension.
 ;; <br>Loads (once only) a the named plugin from the 'plugins-inactive' folder.
 (define (activate-plugin)
 	)
 )
 
-;; @syntax (Dragonfly:web-root [<str-path> [<bool-question-mark>]])
+;; @syntax (DF:web-root [<str-path> [<bool-question-mark>]])
 ;; @param <str-path> Path relative to the folder containing 'index.cgi'.
 ;; @param <bool-question-mark> Whether to return a URL with /? prepended.
 ;; <p>This function is quite handy for making working links when your 'index.cgi' file
 	(string WEB_ROOT (if question-mark "?" "") path)
 )
 
-;; @syntax (Dragonfly:view-path <str-view-name>)
+;; @syntax (DF:view-path <str-view-name>)
 ;; @param <str-view-name> Name of view in 'VIEWS_PATH', without any extension.
 ;; <br>Returns the absolute path to the view as a string, appending 'VIEW_EXTENSION' if necessary.
 (define (view-path view-name)
 	(string VIEWS_PATH "/" view-name (if VIEW_EXTENSION VIEW_EXTENSION ""))
 )
 
-;; @syntax (Dragonfly:partial-path <str-partial-name>)
+;; @syntax (DF:partial-path <str-partial-name>)
 ;; <br>Just like 'view-path', except for partials in 'PARTIALS_PATH'.
 (define (partial-path partial-name)
 	(string PARTIALS_PATH "/" partial-name (if VIEW_EXTENSION VIEW_EXTENSION ""))
 )
 
-;; @syntax (Dragonfly:resource-path <str-resource-name>)
+;; @syntax (DF:resource-path <str-resource-name>)
 ;; <br>Similar to 'view-path', except for resources in 'RESOURCES_PATH'.
 ;; Don't include the .lsp extension.
 (define (resource-path resource-name)
 	(string RESOURCES_PATH "/" resource-name ".lsp")
 )
 
-;; @syntax (Dragonfly:include)
+;; @syntax (DF:include)
 ;; <br>Like 'display-file' but does not pass the file through 'eval-template'.
 (define (include)
 	(print (read-file (apply string $args)))
 )
 
-;; @syntax (Dragonfly:display-file)
+;; @syntax (DF:display-file)
 ;; <br>String-concats its arguments and displays the file
 ;; at that path after passing it through 'eval-template'.
 (define (display-file)
 	(eval-template (read-file (apply string $args)))
 )
 
-;; @syntax (Dragonfly:display-partial <str-partial-name>)
+;; @syntax (DF:display-partial <str-partial-name>)
 ;; Displays the partial named <str-partial-name> using 'display-file' and 'partial-path'.
 (define (display-partial partialname)
   	(display-file (partial-path partialname))
 )
 
-;; @syntax (Dragonfly:display-view <str-view-name>)
+;; @syntax (DF:display-view <str-view-name>)
 ;; Displays the view named <str-view-name> using 'display-file' and 'view-path'.
 (define (display-view viewname)
 	(display-file (view-path viewname))
 )
 
-;; @syntax (Dragonfly:display-error <int-error-code>)
+;; @syntax (DF:display-error <int-error-code>)
 ;; <br>Sends the <int-error-code> and, if it exists, displays the view named
 ;; <int-error-code> using 'display-view'. Otherwise, displays the built-in error
 ;; template 'Dragonfly:ERROR_TEMPLATE'.
 	)
 )
 
-;; @syntax (Dragonfly:eval-template <str> [<ctx>])
+;; @syntax (DF:eval-template <str> [<ctx>])
 ;; @param <str> A string containing the template.
 ;; @param <ctx> Optional. Represents the context the template is evaluted in. Defaults to Dragonfly.
 ;; <br>newLISP code in the template between the 'OPEN_TAG' and 'CLOSE_TAG' (see 'config.lsp') is
 	)
 )
 
-;; @syntax (Dragonfly:die)
+;; @syntax (DF:die)
 ;; <br>String-concats its arguments, logs them as an error via 'log-err', and calls
 ;; 'throw-error' with the same string.
 ;; 
 (new Route 'Route.Static) 
 (new Route 'Route.Resource)
 
-(context Route.Static)
+(context 'Route.Static)
 
 (define (matches?)
 	(set 'chunks (parse QUERY_STRING {[?&]} 0))
 		; if the path ends with one of the trigger extensions, match if it exists
 		(file? path)
 		; otherwise, check if one of the transformations exists
-		(set 'path (eval (exists (fn (x) (file? (eval x))) DF:STATIC_TRANSFORMATIONS)))
+		(exists (fn (x) (file? (setf path (eval x)))) DF:STATIC_TRANSFORMATIONS)
 	)
 )
 (define (run)
 	(replace {\.\.[/|\\]} path "" 0) ; we don't want them getting at things they shouldn't
-	(if-not ext (set 'ext (regex-captcha {.*\.(\w+)$} path)))
-	(if ext (Response:content-type (Response:extension->type ext)))
-	(SET_DFLY_SELF path)
+	(SET_DF_SELF path)
+	(unless ext (setf ext (regex-captcha {.*\.(\w+)$} path)))
+	(when ext (Response:content-type (Response:extension->type ext)))
 	(unless (DF:display-file path)
 		(DF:die "Failed to get: " path)
 	)
 )
 
-(context Route.Resource)
+(context 'Route.Resource)
 
 (define (matches?)
 	(when (regex {^([a-z]\w+)(/([a-z]\w+))?(/(\d+))?(\.([a-z]+))?} QUERY_STRING 1)
 	)
 )
 (define (run)
-	(SET_DFLY_SELF path)
+	(SET_DF_SELF path)
 	(load path)
 	(set 'ctx-str (string "Resource." (join (map title-case (parse resource_name "_")))))
 	(set 'ctx-sym (sym ctx-str))
 
 (context 'Dragonfly)
 
-(if ENABLE_STATIC_TEMPLATES (push (Route.Static) dragonfly-routes -1))
-(if ENABLE_RESTFUL_HANDLER (push (Route.Resource) dragonfly-routes -1))
+(when ENABLE_STATIC_TEMPLATES (push (Route.Static) dragonfly-routes -1))
+(when ENABLE_RESTFUL_HANDLER  (push (Route.Resource) dragonfly-routes -1))
 
 ;===============================================================================
 ; !Private Functions (i.e. you shouldn't ever call these)

File example-site/dragonfly-framework/lib/response.lsp

 		(map (fn(k v) (if v (set k v))) '(value expires path domain http-only) $args)
 		(if (nil? key) cookies
 			(empty? $args) (lookup key cookies)
-			(nil? value) (pop cookies (find key cookies comp-func))
+			(nil? value) (cookie key "" (date-value))
 			(let (cookie (list key value expires path domain http-only))
 				(if (assoc key cookies)
 					(setf (assoc key cookies) cookie)

File example-site/dragonfly-framework/lib/utils.lsp

 	)
 	
 	(define (Dragonfly:print)
-		(write-buffer Dragonfly:STDOUT (apply string (args)))
-		(last (args)) ; to behave the same way as print
+		(write-buffer Dragonfly:STDOUT (apply string $args))
+		(last $args) ; to behave the same way as print
 	)
 	
-	; If someday newLISP supports switching contexts like this we'll use it
-	(define-macro (define-subclass)
-		(new (args 0 1) (args 0 0))
-		;(context (args 0 0))
-		(dolist (method (rest $args))
-			(setf (method 0 0) (sym $it (args 0 0)))
-			(eval (push 'define method))
+	(set 'file-ext-regex (regex-comp {^.*\.(.+)$})
+	     'del-ext-regex  (regex-comp {^(.*)\..+$})
+	     'basename-regex (regex-comp {^(.*/)?(.+)$})
+	     'dirname-regex  (regex-comp {^(.*)/([^/]+/?)$})
+	)
+
+;; @syntax (file-ext <str-path>)
+;; <p>Returns the file extension of the file in <str-path></p>
+;; <pre> (file-ext "")
+;; ;=> ""
+;; (file-ext "asdf")
+;; ;=> ""
+;; (file-ext "asdf.")
+;; ;=> ""
+;; (file-ext "asdf.jpg")
+;; ;=> "jpg"</pre>
+	(define (file-ext path)
+		(if (regex file-ext-regex path 0x10000)
+			$1
+			""
 		)
-		;(context MAIN)
 	)
-	
+
+;; @syntax (del-ext <str-path>)
+;; <p>Returns the <str-path> without the file extension removed.</p>
+;; <pre> (del-ext "")
+;; ;=> ""
+;; (del-ext "asdf")
+;; ;=> "asdf"
+;; (del-ext "asdf.")
+;; ;=> "asdf."
+;; (del-ext "asdf.jpg")
+;; ;=> "asdf"</pre>
+	(define (del-ext path)
+		(if (regex del-ext-regex path 0x10000)
+			$1
+			path
+		)
+	)
+
+;; @syntax (basename <str-path>)
+;; <p>Returns the filename component of <str-path>.</p>
+;; <pre> (basename "")
+;; ;=> ""
+;; (basename "/")
+;; ;=> ""
+;; (basename "asdf")
+;; ;=> "asdf"
+;; (basename "/foo/bar")
+;; ;=> "bar"
+;; (basename "/foo/bar/")
+;; ;=> "bar"</pre>
+	(define (basename path)
+		(if (regex basename-regex path 0x10000)
+			(trim $2 "/")
+			""
+		)
+	)
+
+;; @syntax (dirname <str-path>)
+;; <p>Returns the directory path component of <str-path>.</p>
+;; <pre> (dirname "")
+;; ;=> ""
+;; (dirname "/")
+;; ;=> "/"
+;; (dirname "asdf")
+;; ;=> "."
+;; (dirname "/asdf/")
+;; ;=> "/"
+;; (dirname "asdf/foo")
+;; ;=> "asdf"</pre>
+	(define (dirname path)
+		(if (empty? path)
+			""
+			(if (regex dirname-regex path 0x10000)
+				(if (empty? $1) "/" $1)
+				(if (starts-with path "/") "/" ".")
+			)
+		)
+	)
+
 ;; @syntax (regex-captcha <str-regex> <str> [<int-options>] [<int-captcha>])
 ;; @param <int-options> options to regex, defaults to 0.
 ;; @param <int-captch> which of the regex group captures to return, defaults to 1.
 		(set func-sym (eval (expand wrapper 'wrapped-func)))
 	)
 
-;; @syntax (into-ctx-assoc <ctx> <list-assoc>)
-;; <p>Places the key/value pairs in <list-assoc> into the context <ctx>
-;; to be used as a lookup table.<br/>This is a global function.</p>
-;; <b>example:</b>
-;; <pre> (new Tree 'MyCtx)
-;; (into-ctx-assoc MyCtx '(
-;;     ("key" "value")
-;;     ("apple" "mmmm... good")
-;;     ("organic?" true)
-;; ))</pre>
-;; 
-	(define (into-ctx-assoc ctx assoc-list)
-		; dolist is slightly faster than map
-		(dolist (x assoc-list) (ctx (first x) (last x)))
-	)
-	
-;; @syntax (SET_DFLY_SELF <str-filepath>)
+;; @syntax (SET_DF_SELF <str-filepath>)
 ;; @param <str-filepath> The path to the file being served, or the primary file responsible for handling this route.
 ;; <p>Routes should call this global function with the path to the file that's being displayed
 ;; or the file that's principly in charge of handling this route. This function will then
-;; set the global variables 'DFLY_SELF' and 'DFLY_SELF_DIR' to point to that file and its
+;; set the global variables 'DF_SELF' and 'DF_SELF_DIR' to point to that file and its
 ;; parent directory, respectively.</p>
 ;; <p>The default routes 'Route.Static' and 'Route.Resource' call this function first thing
 ;; in their 'Route:run' methods, prior to loading the files. This is the recommended way of
 ;; calling this function.</p>
-	(define (SET_DFLY_SELF file)
+	(define (SET_DF_SELF file)
 		(when (setf file (real-path file))
-			(set (global 'DFLY_SELF)     file
-			     (global 'DFLY_SELF_DIR) (regex-captcha {^(.+/)} file)
-			)
+			(constant (global 'DF_SELF) file)
+			(constant (global 'DF_SELF_DIR) (regex-captcha {^(.+)/} file))
 		)
 	)
 	
 	; these functions should be global (define-subclass should not)
 	(global 'load-files-in-dir 'regex-captcha 'load-once
-		'wrap-func 'into-ctx-assoc 'add-to-load-path 'SET_DFLY_SELF
+		'wrap-func 'add-to-load-path 'SET_DF_SELF
+		'file-ext 'del-ext 'basename 'dirname
 	)
 	
 	; swap these functions for ours and save the originals

File example-site/dragonfly-framework/newlisp-redirection.lsp

 ;; 	http://localhost:8080/dragonfly_welcome
 ;; Instead of:
 ;; 	http://localhost:8080/?dragonfly_welcome
+;;
+;; NEWLISP_REDIRECTION_EXTENSIONS is a list of file extensions that,
+;; when specified explicitely in the URL, will cause the URL to be
+;; process through Dragonfly's routes and not sent directly to newLISP.
+;; 
+;; This allows you to explicitely specify a file, like so:
+;;  http://localhost:8080/foo.html
+;; 
+;; That will process 'foo.html' through Dragonfly's routes, typically
+;; this allows newLISP code in an HTML template to be evaluated (as with
+;; Route.Static).
+;; 
+;; Feel free to customize this list to your liking.
 
-(set 'NEWLISP_REDIRECTION_EXTRACT_PATH (regex-comp {\w+\s+/([^\s]+)}))
-(set 'NEWLISP_REDIRECTION_REWRITE (regex-comp {^(\w+)\s+/([^\?]+)(\?)?}))
+(set 'NEWLISP_REDIRECTION_EXTRACT_PATH (regex-comp {\w+\s+/([^\s]+)})
+     'NEWLISP_REDIRECTION_REWRITE (regex-comp {^(\w+)\s+/([^\?]+)(\?)?})
+     'NEWLISP_REDIRECTION_EXTENSIONS '(".html" ".nhtml" ".nl")
+)
 
 ; on windows newlisp will complain if this directory doesn't exist
 (when (and (= ostype "Win32") (not (directory? "/tmp")))
 
 (command-event (fn (s , request)
 	(regex NEWLISP_REDIRECTION_EXTRACT_PATH s 0x10000)
-	(set 'request $1)
-	; TODO: we account for most scenarios here but we don't account
-	; for the situation where say an .html template is directly requested
-	; by its actual path. The demo site doesn't use this but some other
-	; sites might. The fix is to check STATIC_TRIGGER_EXTENSIONS.
-	; The workaround is to use views (i.e. STATIC_TRANSFORMATIONS) so
-	; that the actual file isn't specified (the way the example-site does it)
-	(if (and request (or (not (file? request)) (directory? request)))
+	(setf request $1)
+	(if (and request
+			(or (not (file? request))
+				(exists (curry ends-with request) NEWLISP_REDIRECTION_EXTENSIONS)
+				(directory? request)
+			)
+		)
 		(replace NEWLISP_REDIRECTION_REWRITE s
 			(string $1 " /?" $2 (if $3 "&" "")) 0x10000
 		)

File example-site/dragonfly-framework/plugins-active/dragonfly_basic.lsp

 	<h2>QUERY_STRING</h2>"QUERY_STRING"
 	<h2>REQUEST METHOD</h2>"REQUEST_METHOD"
 	<h2>DEFAULT_VIEW</h2>"DEFAULT_VIEW"
-	<h2>DF:viewname</h2>"viewname"
+	<h2>DF_PAGE</h2>"DF_PAGE"
+	<h2>DF_SELF</h2>"DF_SELF"
 	<h2>HTTP_USER_AGENT</h2>"HTTP_USER_AGENT"
 	<h2>HTTP_PROXY</h2>"HTTP_PROXY"
 	<h2>SERVER_SOFTWARE</h2>"SERVER_SOFTWARE"
 ;; <p>Writes a title including the current navigation entry.</p>
 ;; 
 (define (title websitename)
-  (println (string (title-case (replace "_" (copy viewname) " ")) " " websitename  ))
+	(println (string (title-case (replace "_" (basename (del-ext DF_PAGE)) " ")) " " websitename  ))
 )
 
 ;; @syntax (Dragonfly:css <css-media> <css-location>)

File example-site/dragonfly-framework/plugins-inactive/artfulcode/web.lsp

 ; !Encoding and decoding
 ;===============================================================================
 
-(define ENTITIES
-  (list
-    (list 34 {&quot;})       (list 38 {&amp;})        (list 39 {&apos;})       (list 60 {&lt;})
-    (list 62 {&gt;})         (list 160 {&nbsp;})      (list 161 {&iexcl;})     (list 162 {&cent;})
-    (list 163 {&pound;})     (list 164 {&curren;})    (list 165 {&yen;})       (list 166 {&brvbar;})
-    (list 167 {&sect;})      (list 168 {&uml;})       (list 169 {&copy;})      (list 170 {&ordf;})
-    (list 171 {&laquo;})     (list 172 {&not;})       (list 173 {&shy;})       (list 174 {&reg;})
-    (list 175 {&macr;})      (list 176 {&deg;})       (list 177 {&plusmn;})    (list 178 {&sup2;})
-    (list 179 {&sup3;})      (list 180 {&acute;})     (list 181 {&micro;})     (list 182 {&para;})
-    (list 183 {&middot;})    (list 184 {&cedil;})     (list 185 {&sup1;})      (list 186 {&ordm;})
-    (list 187 {&raquo;})     (list 188 {&frac14;})    (list 189 {&frac12;})    (list 190 {&frac34;})
-    (list 191 {&iquest;})    (list 192 {&Agrave;})    (list 193 {&Aacute;})    (list 194 {&Acirc;})
-    (list 195 {&Atilde;})    (list 196 {&Auml;})      (list 197 {&Aring;})     (list 198 {&AElig;}) 
-    (list 199 {&Ccedil;})    (list 200 {&Egrave;})    (list 201 {&Eacute;})    (list 202 {&Ecirc;})
-    (list 203 {&Euml;})      (list 204 {&Igrave;})    (list 205 {&Iacute;})    (list 206 {&Icirc;})
-    (list 207 {&Iuml;})      (list 208 {&ETH;})       (list 209 {&Ntilde;})    (list 210 {&Ograve;})
-    (list 211 {&Oacute;})    (list 212 {&Ocirc;})     (list 213 {&Otilde;})    (list 214 {&Ouml;})
-    (list 215 {&times;})     (list 216 {&Oslash;})    (list 217 {&Ugrave;})    (list 218 {&Uacute;})
-    (list 219 {&Ucirc;})     (list 220 {&Uuml;})      (list 221 {&Yacute;})    (list 222 {&THORN;})
-    (list 223 {&szlig;})     (list 224 {&agrave;})    (list 225 {&aacute;})    (list 226 {&acirc;})
-    (list 227 {&atilde;})    (list 228 {&auml;})      (list 229 {&aring;})     (list 230 {&aelig;})
-    (list 231 {&ccedil;})    (list 232 {&egrave;})    (list 233 {&eacute;})    (list 234 {&ecirc;})
-    (list 235 {&euml;})      (list 236 {&igrave;})    (list 237 {&iacute;})    (list 238 {&icirc;})
-    (list 239 {&iuml;})      (list 240 {&eth;})       (list 241 {&ntilde;})    (list 242 {&ograve;})
-    (list 243 {&oacute;})    (list 244 {&ocirc;})     (list 245 {&otilde;})    (list 246 {&ouml;})
-    (list 247 {&divide;})    (list 248 {&oslash;})    (list 249 {&ugrave;})    (list 250 {&uacute;})
-    (list 251 {&ucirc;})     (list 252 {&uuml;})      (list 253 {&yacute;})    (list 254 {&thorn;})
-    (list 255 {&yuml;})      (list 338 {&OElig;})     (list 339 {&oelig;})     (list 352 {&Scaron;})
-    (list 353 {&scaron;})    (list 376 {&Yuml;})      (list 402 {&fnof;})      (list 710 {&circ;})
-    (list 732 {&tilde;})     (list 913 {&Alpha;})     (list 914 {&Beta;})      (list 915 {&Gamma;})
-    (list 916 {&Delta;})     (list 917 {&Epsilon;})   (list 918 {&Zeta;})      (list 919 {&Eta;})
-    (list 920 {&Theta;})     (list 921 {&Iota;})      (list 922 {&Kappa;})     (list 923 {&Lambda;})
-    (list 924 {&Mu;})        (list 925 {&Nu;})        (list 926 {&Xi;})        (list 927 {&Omicron;})
-    (list 928 {&Pi;})        (list 929 {&Rho;})       (list 931 {&Sigma;})     (list 932 {&Tau;})
-    (list 933 {&Upsilon;})   (list 934 {&Phi;})       (list 935 {&Chi;})       (list 936 {&Psi;})
-    (list 937 {&Omega;})     (list 945 {&alpha;})     (list 946 {&beta;})      (list 947 {&gamma;})
-    (list 948 {&delta;})     (list 949 {&epsilon;})   (list 950 {&zeta;})      (list 951 {&eta;})
-    (list 952 {&theta;})     (list 953 {&iota;})      (list 954 {&kappa;})     (list 955 {&lambda;})
-    (list 956 {&mu;})        (list 957 {&nu;})        (list 958 {&xi;})        (list 959 {&omicron;})
-    (list 960 {&pi;})        (list 961 {&rho;})       (list 962 {&sigmaf;})    (list 963 {&sigma;})
-    (list 964 {&tau;})       (list 965 {&upsilon;})   (list 966 {&phi;})       (list 967 {&chi;})
-    (list 968 {&psi;})       (list 969 {&omega;})     (list 977 {&thetasym;})  (list 978 {&upsih;})
-    (list 982 {&piv;})       (list 8194 {&ensp;})     (list 8195 {&emsp;})     (list 8201 {&thinsp;})
-    (list 8204 {&zwnj;})     (list 8204 {&zwj;})      (list 8204 {&lrm;})      (list 8204 {&rlm;})
-    (list 8211 {&ndash;})    (list 8212 {&mdash;})    (list 8216 {&lsquo;})    (list 8217 {&rsquo;})
-    (list 8218 {&sbquo;})    (list 8220 {&ldquo;})    (list 8221 {&rdquo;})    (list 8222 {&bdquo;})
-    (list 8224 {&dagger;})   (list 8225 {&Dagger;})   (list 8226 {&bull;})     (list 8230 {&hellip;})
-    (list 8240 {&permil;})   (list 8242 {&prime;})    (list 8243 {&Prime;})    (list 8249 {&lsaquo;})
-    (list 8250 {&rsaquo;})   (list 8254 {&oline;})    (list 8260 {&frasl;})    (list 8364 {&euro;})
-    (list 8465 {&image;})    (list 8472 {&weierp;})   (list 8476 {&real;})     (list 8482 {&trade;})
-    (list 8501 {&alefsym;})  (list 8592 {&larr;})     (list 8593 {&uarr;})     (list 8594 {&rarr;})
-    (list 8595 {&darr;})     (list 8596 {&harr;})     (list 8629 {&crarr;})    (list 8656 {&lArr;})
-    (list 8657 {&uArr;})     (list 8658 {&rArr;})     (list 8659 {&dArr;})     (list 8660 {&hArr;})
-    (list 8704 {&forall;})   (list 8706 {&part;})     (list 8707 {&exist;})    (list 8709 {&empty;})
-    (list 8711 {&nabla;})    (list 8712 {&isin;})     (list 8713 {&notin;})    (list 8715 {&ni;})
-    (list 8719 {&prod;})     (list 8721 {&sum;})      (list 8722 {&minus;})    (list 8727 {&lowast;})
-    (list 8730 {&radic;})    (list 8733 {&prop;})     (list 8734 {&infin;})    (list 8736 {&ang;})
-    (list 8743 {&and;})      (list 8744 {&or;})       (list 8745 {&cap;})      (list 8746 {&cup;})
-    (list 8747 {&int;})      (list 8756 {&there4;})   (list 8764 {&sim;})      (list 8773 {&cong;})
-    (list 8776 {&asymp;})    (list 8800 {&ne;})       (list 8801 {&equiv;})    (list 8804 {&le;})
-    (list 8805 {&ge;})       (list 8834 {&sub;})      (list 8835 {&sup;})      (list 8836 {&nsub;})
-    (list 8838 {&sube;})     (list 8839 {&supe;})     (list 8853 {&oplus;})    (list 8855 {&otimes;})
-    (list 8869 {&perp;})     (list 8901 {&sdot;})     (list 8968 {&lceil;})    (list 8969 {&rceil;})
-    (list 8970 {&lfloor;})   (list 8971 {&rfloor;})   (list 9001 {&lang;})     (list 9002 {&rang;})
-    (list 9674 {&loz;})      (list 9824 {&spades;})   (list 9827 {&clubs;})    (list 9829 {&hearts;})
-    (list 9830 {&diams;})))
+(define ENTITIES '(
+    (34 {&quot;})       (38 {&amp;})        (39 {&apos;})       (60 {&lt;})
+    (62 {&gt;})         (160 {&nbsp;})      (161 {&iexcl;})     (162 {&cent;})
+    (163 {&pound;})     (164 {&curren;})    (165 {&yen;})       (166 {&brvbar;})
+    (167 {&sect;})      (168 {&uml;})       (169 {&copy;})      (170 {&ordf;})
+    (171 {&laquo;})     (172 {&not;})       (173 {&shy;})       (174 {&reg;})
+    (175 {&macr;})      (176 {&deg;})       (177 {&plusmn;})    (178 {&sup2;})
+    (179 {&sup3;})      (180 {&acute;})     (181 {&micro;})     (182 {&para;})
+    (183 {&middot;})    (184 {&cedil;})     (185 {&sup1;})      (186 {&ordm;})
+    (187 {&raquo;})     (188 {&frac14;})    (189 {&frac12;})    (190 {&frac34;})
+    (191 {&iquest;})    (192 {&Agrave;})    (193 {&Aacute;})    (194 {&Acirc;})
+    (195 {&Atilde;})    (196 {&Auml;})      (197 {&Aring;})     (198 {&AElig;}) 
+    (199 {&Ccedil;})    (200 {&Egrave;})    (201 {&Eacute;})    (202 {&Ecirc;})
+    (203 {&Euml;})      (204 {&Igrave;})    (205 {&Iacute;})    (206 {&Icirc;})
+    (207 {&Iuml;})      (208 {&ETH;})       (209 {&Ntilde;})    (210 {&Ograve;})
+    (211 {&Oacute;})    (212 {&Ocirc;})     (213 {&Otilde;})    (214 {&Ouml;})
+    (215 {&times;})     (216 {&Oslash;})    (217 {&Ugrave;})    (218 {&Uacute;})
+    (219 {&Ucirc;})     (220 {&Uuml;})      (221 {&Yacute;})    (222 {&THORN;})
+    (223 {&szlig;})     (224 {&agrave;})    (225 {&aacute;})    (226 {&acirc;})
+    (227 {&atilde;})    (228 {&auml;})      (229 {&aring;})     (230 {&aelig;})
+    (231 {&ccedil;})    (232 {&egrave;})    (233 {&eacute;})    (234 {&ecirc;})
+    (235 {&euml;})      (236 {&igrave;})    (237 {&iacute;})    (238 {&icirc;})
+    (239 {&iuml;})      (240 {&eth;})       (241 {&ntilde;})    (242 {&ograve;})
+    (243 {&oacute;})    (244 {&ocirc;})     (245 {&otilde;})    (246 {&ouml;})
+    (247 {&divide;})    (248 {&oslash;})    (249 {&ugrave;})    (250 {&uacute;})
+    (251 {&ucirc;})     (252 {&uuml;})      (253 {&yacute;})    (254 {&thorn;})
+    (255 {&yuml;})      (338 {&OElig;})     (339 {&oelig;})     (352 {&Scaron;})
+    (353 {&scaron;})    (376 {&Yuml;})      (402 {&fnof;})      (710 {&circ;})
+    (732 {&tilde;})     (913 {&Alpha;})     (914 {&Beta;})      (915 {&Gamma;})
+    (916 {&Delta;})     (917 {&Epsilon;})   (918 {&Zeta;})      (919 {&Eta;})
+    (920 {&Theta;})     (921 {&Iota;})      (922 {&Kappa;})     (923 {&Lambda;})
+    (924 {&Mu;})        (925 {&Nu;})        (926 {&Xi;})        (927 {&Omicron;})
+    (928 {&Pi;})        (929 {&Rho;})       (931 {&Sigma;})     (932 {&Tau;})
+    (933 {&Upsilon;})   (934 {&Phi;})       (935 {&Chi;})       (936 {&Psi;})
+    (937 {&Omega;})     (945 {&alpha;})     (946 {&beta;})      (947 {&gamma;})
+    (948 {&delta;})     (949 {&epsilon;})   (950 {&zeta;})      (951 {&eta;})
+    (952 {&theta;})     (953 {&iota;})      (954 {&kappa;})     (955 {&lambda;})
+    (956 {&mu;})        (957 {&nu;})        (958 {&xi;})        (959 {&omicron;})
+    (960 {&pi;})        (961 {&rho;})       (962 {&sigmaf;})    (963 {&sigma;})
+    (964 {&tau;})       (965 {&upsilon;})   (966 {&phi;})       (967 {&chi;})
+    (968 {&psi;})       (969 {&omega;})     (977 {&thetasym;})  (978 {&upsih;})
+    (982 {&piv;})       (8194 {&ensp;})     (8195 {&emsp;})     (8201 {&thinsp;})
+    (8204 {&zwnj;})     (8204 {&zwj;})      (8204 {&lrm;})      (8204 {&rlm;})
+    (8211 {&ndash;})    (8212 {&mdash;})    (8216 {&lsquo;})    (8217 {&rsquo;})
+    (8218 {&sbquo;})    (8220 {&ldquo;})    (8221 {&rdquo;})    (8222 {&bdquo;})
+    (8224 {&dagger;})   (8225 {&Dagger;})   (8226 {&bull;})     (8230 {&hellip;})
+    (8240 {&permil;})   (8242 {&prime;})    (8243 {&Prime;})    (8249 {&lsaquo;})
+    (8250 {&rsaquo;})   (8254 {&oline;})    (8260 {&frasl;})    (8364 {&euro;})
+    (8465 {&image;})    (8472 {&weierp;})   (8476 {&real;})     (8482 {&trade;})
+    (8501 {&alefsym;})  (8592 {&larr;})     (8593 {&uarr;})     (8594 {&rarr;})
+    (8595 {&darr;})     (8596 {&harr;})     (8629 {&crarr;})    (8656 {&lArr;})
+    (8657 {&uArr;})     (8658 {&rArr;})     (8659 {&dArr;})     (8660 {&hArr;})
+    (8704 {&forall;})   (8706 {&part;})     (8707 {&exist;})    (8709 {&empty;})
+    (8711 {&nabla;})    (8712 {&isin;})     (8713 {&notin;})    (8715 {&ni;})
+    (8719 {&prod;})     (8721 {&sum;})      (8722 {&minus;})    (8727 {&lowast;})
+    (8730 {&radic;})    (8733 {&prop;})     (8734 {&infin;})    (8736 {&ang;})
+    (8743 {&and;})      (8744 {&or;})       (8745 {&cap;})      (8746 {&cup;})
+    (8747 {&int;})      (8756 {&there4;})   (8764 {&sim;})      (8773 {&cong;})
+    (8776 {&asymp;})    (8800 {&ne;})       (8801 {&equiv;})    (8804 {&le;})
+    (8805 {&ge;})       (8834 {&sub;})      (8835 {&sup;})      (8836 {&nsub;})
+    (8838 {&sube;})     (8839 {&supe;})     (8853 {&oplus;})    (8855 {&otimes;})
+    (8869 {&perp;})     (8901 {&sdot;})     (8968 {&lceil;})    (8969 {&rceil;})
+    (8970 {&lfloor;})   (8971 {&rfloor;})   (9001 {&lang;})     (9002 {&rang;})
+    (9674 {&loz;})      (9824 {&spades;})   (9827 {&clubs;})    (9829 {&hearts;})
+    (9830 {&diams;})
+))
 
 (define UNENTITIES
   (map reverse ENTITIES))
 
-(define JS_ESCAPE_CHARS
-  (list
-    (list {\} {\\})
-    (list {"} {\"})
-    (list {'} {\'})
-    (list "\n" {\n})
-    (list "\r" {\r})
-    (list "</" {<\/})))
+(define JS_ESCAPE_CHARS '(
+    ({\} {\\})
+    ({"} {\"})
+    ({'} {\'})
+    ("\n" {\n})
+    ("\r" {\r})
+    ("</" {<\/})
+))
 
 ;; @syntax (Web:escape-js <str>)
 ;; @param <str> a string to escape

File example-site/dragonfly-framework/plugins-inactive/dragonfly_api.lsp

 
 (context 'Dragonfly)
 
-(set 'dragonfly-api-directory "dragonfly-api")
-
-(define (api-browser)
+(define (api-browser api-dir)
 	(print (format [text]
 		<div id="api-browser">&nbsp</div>
 		<script type="text/javascript">
 				);
 			})("%s/index.html");
 		</script>
-		[/text] (web-root "dragonfly_ajax-api") dragonfly-api-directory dragonfly-api-directory)
+		[/text] (web-root "dragonfly_ajax-api") api-dir api-dir)
 	)
 )
 

File example-site/dragonfly-framework/plugins-inactive/dragonfly_sqlite3.lsp

-;;  Copyright (C) <2009> <Marc Hildmann>
-;;
-;;  This program is free software: you can redistribute it and/or modify
-;;  it under the terms of the GNU General Public License as published by
-;;  the Free Software Foundation, either version 3 of the License, or
-;;  (at your option) any later version.
-;;
-;;  This program is distributed in the hope that it will be useful,
-;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;  GNU General Public License for more details.
-;;  You should have received a copy of the GNU General Public License
-;;  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-;;
-;; @module Dragonfly
-;; @author Marc Hildmann <marc.hildmann at gmail.com>
-;; @version 0.20
-;; 
-;; @location http://code.google.com/p/dragonfly-newlisp/
-;; @description A newLISP web framework for rapid web development
-;; <h4>About Dragonfly web framework</h4>
-;; <p>Dragonfly is a small web framework which is currently under heavy development.
-;; Its's features are a short learning curve, lightweight and fun in programming - 
-;; just like newLISP itself.</p>
-
-(module "sqlite3.lsp")
-
-;===============================================================================
-; !Defining new context
-;===============================================================================
-
-(context 'Dragonfly)
-
-;===============================================================================
-; !sqlite3 Wrapper
-;===============================================================================
-
-
-;; @syntax (Dragonfly:sqlite-open <databasename>)
-;; @param <databasename> string containing the database name
-;; <p>Open the SQLite database or creates it, if it does not exist.</p>
-;;
-(define (sqlite-open databasename)
-	;; close old connections
-	(sql3:close)
-	
-	(if (sql3:open databasename) 
-		(set 'flashnotice "Database was successfully opened or created.") 
-	) 	
-)
-
-;; @syntax (Dragonfly:sqlite-tables)
-;; <p>Shows the existing tables in the current database.</p>
-;;
-(define (sqlite-tables) 
-	(println "
-	<div id='dragonfly_database-information' style='border:1px dotted #00aeef; width:800px; padding:8px; margin-top:20px;margin-bottom:20px' >
-	<h2>Existing tables in SQLite Database</h2><pre>
-	"
-	(sql3:tables)"
-	</pre></div>")
-)
-
-;; @syntax (Dragonfly:sqlite-columns)
-;; <p>Shows the existing columns in a given table.</p>
-;;
-(define (sqlite-columns table) 
-	(println "
-	<div id='dragonfly_database-information' style='border:1px dotted #00aeef; width:800px; padding:8px; margin-top:20px;margin-bottom:20px' >
-	<h2>Existing columns in SQLite table <i>"table"</i></h2><pre>
-	"
-	(sql3:columns table)"
-	</pre></div>")
-)
-
-(define (sqlite-empty-table table) 
-	(set 'query (string "DELETE FROM "table))
-	(sql3:sql query)
-)
-
-(define (sqlite-query query) 
-	(set 'sqlarray (sql3:sql query)) ; results of query
-	;; close old connections
-	(sql3:close)	
-)
-
-(define (sqlite-insert table values)
-	(set 'query (string "INSERT INTO "table" VALUES ("values")"))
-	(sql3:sql query)
-)
-
-(define (sqlite-get-tabledata query) 
-	(set 'sqlarray (sql3:sql query)) ; results of query
-	
-)
-
-(context Dragonfly)

File example-site/dragonfly-framework/plugins-inactive/path.lsp

-; @author Greg Slepak
+;; @module path.lsp
+;; @description Global convenience functions for dealing with file paths
+;; @author Greg Slepak
+;; @version 1.0
+;; <br/>All of these functions are made global, so watch out for name conflicts.
 
-(context 'Path)
-
-(set 'ext-regex		 (regex-comp {.*\.(.+)$})
-     'ext-del-regex	 (regex-comp {(.*)\..+$})
+(set 'file-ext-regex (regex-comp {^.*\.(.+)$})
+     'del-ext-regex  (regex-comp {^(.*)\..+$})
+     'basename-regex (regex-comp {^(.*/)?(.+)$})
+     'dirname-regex  (regex-comp {^(.*)/([^/]+/?)$})
 )
 
-(define (ext path)
-	(if (regex ext-regex path 0x10000)
+;; @syntax (file-ext <str-path>)
+;; <p>Returns the file extension of the file in <str-path></p>
+;; <pre> (file-ext "")
+;; ;=> ""
+;; (file-ext "asdf")
+;; ;=> ""
+;; (file-ext "asdf.")
+;; ;=> ""
+;; (file-ext "asdf.jpg")
+;; ;=> "jpg"</pre>
+(define (file-ext path)
+	(if (regex file-ext-regex path 0x10000)
 		$1
 		""
 	)
 )
 
+;; @syntax (del-ext <str-path>)
+;; <p>Returns the <str-path> without the file extension removed.</p>
+;; <pre> (del-ext "")
+;; ;=> ""
+;; (del-ext "asdf")
+;; ;=> "asdf"
+;; (del-ext "asdf.")
+;; ;=> "asdf."
+;; (del-ext "asdf.jpg")
+;; ;=> "asdf"</pre>
 (define (del-ext path)
-	(if (regex ext-del-regex path 0x10000)
+	(if (regex del-ext-regex path 0x10000)
 		$1
 		path
 	)
 )
 
-(define (del-comp path remove-leading-slash , lst)
-	(set 'lst (parse path "/"))
-	(if (empty? lst)
-		path ; we were given ""
-		(begin
-			; check for leading slash at the end
-			(when (null? (pop lst -1))
-				(pop lst -1)
-			)
-			(when (starts-with path "/")
-				(if (empty? lst)
-					(push "/" lst)
-					(= (length lst) 1)
-					(push "" lst)
-				)
-				(when remove-leading-slash
-					(pop lst)
-				)
-			)
-			(join lst "/")
+;; @syntax (basename <str-path>)
+;; <p>Returns the filename component of <str-path>.</p>