Old magic web wrapper - one of my first applications of CT reflection. Given a class of fairly ordinary D code, it automatically creates HTML pages and forms, a Javascript file to access the functions from the client, and JSON based api responses. I do not recommend it for new projects though, as a replacement is now built into arsd.cgi.

Public Imports

public import arsd.dom;
Undocumented in source.
public import arsd.cgi;
Undocumented in source.
public import std.string;
Undocumented in source.
public import std.array;
Undocumented in source.
public import std.conv;
Undocumented in source.
public import std.range;
Undocumented in source.
public import std.traits;
Undocumented in source.



alias WrapperFunction = WrapperReturn delegate(Cgi cgi, WebDotDBaseType, in string[][string] args, in string format, in string secondaryFormat = null)

The definition of the beastly wrapper function


class ApiObject

Implement subclasses of this inside your main provider class to do a more object oriented site.

class ApiProvider

Everything should derive from this instead of the old struct namespace used before Your class must provide a default constructor.

class InsufficientParametersException

throw this if your function needs something that is missing. Done automatically by the wrapper function

class InvalidParameterException

throw this if a paramater is invalid. Automatic forms may present this to the user in a new form. (FIXME: implement that)

class NoSuchPageException

throw if the request path is not found. Done automatically by the default catch all handler.

class ParamCheckHelper
class PermissionDeniedException

throw this if the user's access is denied

class Session

Provides some persistent storage, kinda like PHP But, you have to manually commit() the data back to a file. You might want to put this in a scope(exit) block or something like that.

class TemplatedDocument

a specialization of Document that: a) is always in strict mode and b) provides some template variable text replacement, in addition to DOM manips. The variable text is valid in text nodes and attribute values. It takes the format of {$variable}, where variable is a key into the vars member.

class WebDotDBaseType

this is there so there's a common runtime type for all callables


void badParameter(string expected)

convenience for throwing InvalidParameterExceptions

string beautify(string name)

turns camelCase into human presentable capitalized words with spaces

bool checkPassword(string saltedPasswordHash, string userSuppliedPassword)

and use this to check it.

Form createAutomaticForm(Document document, FunctionInfo* func, string[string] fieldTypes)
Form createAutomaticForm(Document document, string action, Parameter[] parameters, string submitText, string method, string[string] fieldTypes)

Given a function from reflection, build a form to ask for it's params

string formatAs(T ret, string format, R api, JSONValue* returnValue, string formatJsonToStringAs)

This is the function called to turn return values into strings. Implement a template called _customFormat in your apiprovider class to make special formats. Otherwise, this provides the defaults of html, table, json, etc. call it like so: JSONValue returnValue; formatAs(value, this, returnValue, "type");

type fromUrlParam(string[] ofInterest, string name, string[][string] all)

turns a string array from the URL into a proper D type

WrapperFunction generateWrapper(ReflectionInfo* reflection, R api)

generates the massive wrapper function for each of your class' methods. it is responsible for turning strings to params and return values back to strings.

deprecated string getSessionId(Cgi cgi)

meant to give a generic useful hook for sessions. kinda sucks at this point. use the Session class instead. If you just construct it, the sessionId property works fine. Don't set any data and it won't save any file.

string getSiteLink(Cgi cgi)

This gets your site's base link. note it's really only good if you are using FancyMain.

bool isFreeOfTypicalPlainTextSpamLinks(string txt)

Looks for things like <a or [url - the kind of stuff I often see in blatantly obvious comment spam

bool isValidLookingEmailAddress(string e)

helper for param checking

string jsCall(Args args)

This is meant to beautify and check links and javascripts to call web.d functions. This function works pretty ok. You're going to want to append a string to the return value to actually call .get() or whatever; it only does the name and arglist.

string linkCall(Args args)

This is meant to beautify and check links and javascripts to call web.d functions. FIXME: this function sucks.

string makeJavascriptApi(ReflectionInfo* mod, string base, bool isNested)

This uses reflection info to generate Javascript that can call the server with some ease. Also includes javascript base (see bottom of this file)

string makeSaltedPasswordHash(string userSuppliedPassword, string salt)

These added a dependency on arsd.sha, but hashing passwords is somewhat useful in a lot of apps so I figured it was worth it. use this to make the hash to put in the database...

void run(Cgi cgi, Provider instantiation, size_t pathInfoStartingPoint, bool handleAllExceptions, Session session)

If you're not using FancyMain, this is the go-to function to do most the work. instantiation should be an object of your ApiProvider type. pathInfoStartingPoint is used to make a slice of it, incase you already consumed part of the path info before you called this.

void setLoginCookie(Cgi cgi, string name, string value)

sets a site-wide cookie, meant to simplify login code. Note: you often might not want a side wide cookie, but I usually do since my projects need single sessions across multiple thingies, hence, this.

Table structToTable(Document document, T arr, string[] fieldsToSkip)

implements the "table" format option. Works on structs and associative arrays (stringstring[])

Table structToTable(Document document, T s, string[] fieldsToSkip)

does a name/field table for just a singular object

string toHtml(T a)

////////////////////////////// Formats any given type as HTML. In custom types, you can write Element makeHtmlElement(Document document = null); to provide custom html. (the default arg is important - it won't necessarily pass a Document in at all, and since it's silently duck typed, not having that means your function won't be called and you can be left wondering WTF is going on.) Alternatively, static Element makeHtmlArray(T[]) if you want to make a whole list of them. By default, it will just concat a bunch of individual elements though.

string toJson(T a)

Translates a given type to a JSON string. TIP: if you're building a Javascript function call by strings, toJson("your string"); will build a nicely escaped string for you of any type.

JSONValue toJsonValue(T a, string formatToStringAs, R api)

like toHtml - it makes a json value of any given type. It can be used generically, or it can be passed an ApiProvider so you can do a secondary custom format. (it calls api.formatAs!(type)(typeRequestString)). Why would you want that? Maybe your javascript wants to do work with a proper object,but wants to append it to the document too. Asking for json with secondary format = html means the server will provide both to you. Implement JSONValue makeJsonValue() in your struct or class to provide 100% custom Json. Elements from DOM are turned into JSON strings of the element's html.

string toUrlName(string name)

turns camelCase into dash-separated

void translateQsa(Document document, Cgi cgi, string logicalScriptName)

This adds a custom attribute to links in the document called qsa which modifies the values on the query string

string urlToBeauty(string url)

tries to take a URL name and turn it into a human natural name. so get rid of slashes, capitalize, etc.

void writeDocument(Cgi cgi, TemplatedDocument document)

a convenience function to do filters on your doc and write it out. kinda useless still at this point.


writefln (from std.stdio)
public import std.stdio : writefln;
Undocumented in source.

Mixin templates

mixintemplate CustomCgiFancyMain(CustomCgi, T, Args...)

Like FancyMain, but you can pass a custom subclass of Cgi

mixintemplate FancyMain(T, Args...)

fancier wrapper to cgi.d's GenericMain - does most the work for you, so you can just write your class and be done with it Note it creates a session for you too, and will write to the disk - a csrf token. Compile with -version=no_automatic_session to disable this.


struct CookieParams

This is cookie parameters for the Session class. The default initializers provide some simple default values for a site-wide session cookie.

struct DefaultFormat

Attribute for the default formatting (html, table, json, etc)

struct EnumInfo

describes an enum, iff based on int as the underlying type

struct Envelope

This is the JSON envelope format

struct FunctionInfo


struct GenericContainerType
struct IfInputContentType

With this attribute, the function is only called if the input data's content type is what you specify here. Makes sense for POST and PUT verbs.

struct Parameter

Function parameter

struct PreferredMethod

Sets the preferred request method, used by things like other code generators. While this is preferred, the function is still callable from any request method.

struct ReflectionInfo

Describes the info collected about your class

struct RequestInfo

Info about the current request - more specialized than the cgi object directly

struct StructInfo

describes a plain data struct

struct StructMemberInfo


struct Text

use this in a function parameter if you want the automatic form to render it as a textarea FIXME: this should really be an annotation on the parameter... somehow

struct URL


enum string javascriptBaseImpl;

It provides the foundation to calling the server via background requests and handling the response in callbacks. (ajax style stuffs).



Written some time prior to July 2011.

Retired in June 2019. I will still maintain it until that becomes a hassle. But since I don't actively use any of my projects using it anymore, it is possible it will break without me noticing.

Suggestion Box / Bug Report