Introduction
A requirements management free source wiki for software development teams that takes advantage of the IHttpModule
interface to support the .wiki file extension for each document in the wiki.
Background
I wrote this application for use in the software development teams in which I participate because I was tired of the static nature of Word documents being passed around via email with no way to review and account for revisions and no way to understand the relationships of any given document with others in the project. The first incarnation used a standard plain text wiki editor and syntax for documents but it became clear that general users would not adopt this interface rapidly, so I switched to a free DHTML editor, eliminating all wiki-like editing syntax except the double [[ ]] brackets used for defining links.
Using the code
The code was written using Visual Studio .NET 2003 in C#. It is organized into several projects within the solution. It relies on Windows authentication, so no user management is included except the management of a user's email address to which changes notices are sent. In addition to the source code, you will need to download and install the Data Access Application Block for.NET from Microsoft and the FreeTextBox control by John Dyer.
The code is written to rely on SQL Server 2000 (the SQL scripts for DB create and stored procedures and views are included), but you could certainly run it on MSDE 2000 or any other database. The OpenCollective.Data project would require modifications should you wish to use another database server.
Project Setup
- Download and install Microsoft's Data Access Application Block for .NET at http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp
- Download and install FreeTextBox by John Dyer at http://www.freetextbox.com/
- Create a virtual directory called OpenCollective.Web and point it to the OpenCollective.Web directory in the source code you just downloaded. Make sure that you turn off anonymous access.
- Open the OpenCollective Solution file and correct the references to the two external controls in the OpenCollective.Web and OpenCollective.Edit projects.
- Copy the images folder and the two modified javascripts in the FreeTextBox_mods directory included in the source to your IIS wwwroot directory\aspnet_client\FreeTextBox\ directory.
- Create a SQL database (SQL Server 2000 or MSDE 2000) and run the SQL scripts in the OpenCollectiveSQL directory: db_create.sql, views.sql and then stored_procs.sql.
- Set your connection string in web.config in the OpenCollective.Web project.
- Add a mapping to .wiki in your IIS application configuration settings to be handled by c:\windows\microsoft.net\framework\v1.1.4322\aspnet_isapi.dll
- Compile and run.
Indexer Setup
The search feature will not work unless the index in the database is populated. There is a console
application in the solution called OpenCollectiveIndexer which must be configured either
via the app.config and then compile it (or via the OpenCollectiveIndexer.exe.config file
directly). You must configure the connection string to your database.
On my installs, I just set a database job to run the OpenCollectiveIndexer.exe file
once a day or once every few hours. The OpenCollectiveIndexer will then build your index
and your search will then work properly.
Http Module and the .wiki Extension
Implementing an HttpModule is not difficult. In this case, I rewrite the path to the wiki.aspx page which handles all of the web page functionality of this wiki. The original URL is attached as a query string parameter in order to carry the project and document name in the request.
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
string url = app.Request.Url.PathAndQuery;
string qry = app.Request.Url.Query;
string page = app.Request.Url.AbsolutePath.ToLower();
string appPath = app.Request.ApplicationPath.ToLower();
if( url.ToLower().IndexOf( Config.ContentExtension ) > -1
&& url.ToLower().IndexOf( "/wiki/" ) > -1 )
{
if(qry.StartsWith("?url="))
app.Context.RewritePath(appPath + "/wiki.aspx" + qry);
else
app.Context.RewritePath(appPath + "/wiki.aspx?url=" +
app.Context.Server.UrlEncode(url));
}
}
Post to the Original Page
The tricky part is in keeping the non-existant .wiki page in the address bar of the browser. The page is rendered by wiki.aspx and would normally post back to the wiki.aspx page. That would ruin the illusion of having a real .wiki page living on the server. The only way that I have been able to figure that out is to have javascript rewrite the action attribute of the form element in the page.
So the body tag is set to run on the server side in which I set the onload attribute as follows:
string origPage = appUrlPath + "/wiki/" + wikiName +
"/" + topicName + ".wiki" + origQry;
pgBody.Attributes["onload"] = "SetAction('" + reqUrl + "');";
And then a simple JavaScript called SetAction
rewrites the URL to which the form will post.
function SetAction(url)
{
document.forms[0].action = url;
}
History
While I have written other wikis, this is the first that has taken on so much. I plan to continue to upgrade the code and will post revisions here.
- 10/08/2004 Version 0.72 released: included previous documents visited menu and index tab which provides full index to all documents in the database.
- 10/18/2004 Indexer Setup noted: added note to article for setting up and using the OpenCollectiveIndexer.
- 11/02/2004 Readme updated : updated download readme to reflect article steps. Thanks for the suggestion goes to
chavezal, who was understandably frustrated that it was not done before he downloaded.
- 11/08/2004 Version 0.73 released: added rollback and delete functionality and completed the Files tab with author column in WikiFile table. Download includes updated readme with database upgrade instructions and scripts.