arsd.web



string getSiteLink(Cgi cgi);
This gets your site's base link. note it's really only good if you are using FancyMain.

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 Envelope;
This is the JSON envelope format

bool success;
did the call succeed? false if it threw an exception

string type;
static type of the return value

string errorMessage;
if !success, this is exception.msg

string userData;
null unless the user request included passedThroughUserData

JSONValue result;
the return value of the function

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

string mainSitePath;
the bottom-most ApiProvider's path in this request

string objectBasePath;
the top-most resolved path in the current request

FunctionInfo currentFunction;
what function is being called according to the url?

string requestedFormat;
the format the returned data was requested to be sent

string requestedEnvelopeFormat;
the format the data is to be wrapped in

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

Cgi cgi;
lower level access to the request

void _postProcess(Document document);
Override this if you want to do something special to the document You should probably call super.postProcess at some point since I might add some default transformations here. By default, it forwards the document root to postProcess(Element).

void _postProcessElement(Element element);
Override this to do something special to returned HTML Elements. This is ONLY run if the return type is(: Element). It is NOT run if the return type is(: Document).

void ensurePost();
convenience function to enforce that the current method is POST. You should use this if you are going to commit to the database or something.

string linkCall(alias Func, Args...)(Args args);
This is meant to beautify and check links and javascripts to call web.d functions.

FIXME:
this function sucks.

string jsCall(alias Func, Args...)(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.

class ApiProvider: arsd.web.WebDotDBaseType;
Everything should derive from this instead of the old struct namespace used before Your class must provide a default constructor.

protected void checkCsrfToken();
override this to change cross-site request forgery checks.

To perform a csrf check, call ensureGoodPost(); in your code.

It throws a PermissionDeniedException if the check fails. This might change later to make catching it easier.

If there is no session object, the test always succeeds. This lets you opt out of the system.

If the session is null, it does nothing. FancyMain makes a session for you. If you are doing manual run(), it is your responsibility to create a session and attach it to each primary object.

NOTE:
it is important for you use ensureGoodPost() on any data changing things! This function alone is a no-op on non-POST methods, so there's no real protection without ensuring POST when making changes.

void ensureGoodPost();
Shorthand for ensurePost and checkCsrfToken. You should use this on non-indempotent functions. Override it if doing some custom checking.

protected string[string] _getCsrfInfo();
Gets the CSRF info (an associative array with key and token inside at least) from the session. Note that the actual token is generated by the Session class.

protected void addCsrfTokens(Document document);
Adds CSRF tokens to the document for use by script (required by the Javascript API) and then calls addCsrfTokens(document.root) to add them to all POST forms as well.

void _postProcess(Document document);
we have to add these things to the document...

protected void addCsrfTokens(Element element);
This adds CSRF tokens to all forms in the tree

void _initialize();
Override this if you have initialization work that must be done *after* cgi and reflection is ready. It should be used instead of the constructor for most work.

void _initializePerCall();
This one is called at least once per call. (initialize is only called once per process)

const string _style();
Returns the stylesheet for this module. Use it to encapsulate the needed info for your output so the module is more easily reusable Override this to provide your own stylesheet. (of course, you can always provide it via catchAll or any standard css file/style element too.)

const string stylesheet();
Returns the combined stylesheet of all child modules and this module

void redirect(string location, bool important = false);
This tentatively redirects the user - depends on the envelope fomat

Element _sitemap();
Returns a list of links to all functions in this class or sub-classes You can expose it publicly with alias: "alias sitemap sitemap;" for example.

Document _defaultPage();
If the user goes to your program without specifying a path, this function is called.

Element _getGenericContainer();
When the html document envelope is used, this function is used to get a html element where the return value is appended. It's the main function to override to provide custom HTML templates.

FileResource _catchAll(string path);
If the given url path didn't match a function, it is passed to this function for further handling. By default, it throws a NoSuchPageException. Overriding it might be useful if you want to serve generic filenames or an opDispatch kind of thing. (opDispatch itself won't work because it's name argument needs to be known at compile time!)

Note that you can return Documents here as they implement the FileResource interface too.

Document delegate(Throwable) _errorFunction;
When in website mode, you can use this to beautify the error message

class ApiObject: arsd.web.WebDotDBaseType;
Implement subclasses of this inside your main provider class to do a more object oriented site.

JSONValue makeJsonValue();
Override this to make json out of this object

struct ReflectionInfo;
Describes the info collected about your class

immutable(FunctionInfo)*[string] functions;
the methods

EnumInfo[string] enums;
.

StructInfo[string] structs;
.

const(ReflectionInfo)*[string] objects;
ApiObjects and ApiProviders

string name;
this is also used as the object name in the JS api

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

string name;
.

int[] values;
.

string[] names;
.

struct StructInfo;
describes a plain data struct

string name;
.

StructMemberInfo[] members;
.

struct StructMemberInfo;
.

string name;
.

string staticType;
.

string defaultValue;
.

struct FunctionInfo;
.

WrapperFunction dispatcher;
this is the actual function called when a request comes to it - it turns a string[][string] into the actual args and formats the return value

string name;
the URL friendly name

string originalName;
the original name in code

Parameter[] parameters;
.

string returnType;
. static type to string

Document delegate(const(immutable(char)[][string]) args) createForm;
This is used if you want a custom form - normally, on insufficient parameters, an automatic form is created. But if there's a functionName_Form method, it is used instead. FIXME: this used to work but not sure if it still does

struct Parameter;
Function parameter

string name;
name (not always accurate)

string type;
type of HTML element to create when asking

string staticType;
original type

string validator;
FIXME

bool hasDefault;
if there was a default defined in the function

string defaultValue;
the default value defined in D, but as a string, if present

string[] options;
possible options for selects

string[] optionValues;
.

void run(Provider)(Cgi cgi, Provider instantiation, size_t pathInfoStartingPoint = 0);
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.

template 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.

template CustomCgiFancyMain(CustomCgi,T,Args...) if (is(CustomCgi : Cgi))
Like FancyMain, but you can pass a custom subclass of Cgi

Form createAutomaticForm(Document document, in FunctionInfo* func, string[string] fieldTypes = null);
Form createAutomaticForm(Document document, string action, in Parameter[] parameters, string submitText = "Submit", string method = "POST", string[string] fieldTypes = null);
Given a function from reflection, build a form to ask for it's params

string toHtml(T)(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)(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, R = ApiProvider)(T a, string formatToStringAs = null, R api = null);
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.

class InsufficientParametersException: object.Exception;
throw this if your function needs something that is missing. Done automatically by the wrapper function

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

void badParameter(alias T)(string expected = "");
convenience for throwing InvalidParameterExceptions

class PermissionDeniedException: object.Exception;
throw this if the user's access is denied

class NoSuchPageException: object.Exception;
throw if the request path is not found. Done automatically by the default catch all handler.

type fromUrlParam(type)(string[] ofInterest);
turns a string array from the URL into a proper D type

WrapperFunction generateWrapper(alias ObjectType, string funName, alias f, R)(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.

string formatAs(T, R)(T ret, string format, R api = null, JSONValue* returnValue = null, string formatJsonToStringAs = null);
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");

alias WrapperFunction;
The definition of the beastly wrapper function

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.

string toUrlName(string name);
turns camelCase into dash-separated

string beautify(string name);
turns camelCase into human presentable capitalized words with spaces

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.

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.

this(Cgi cgi, string cookieName = "_sess_id", bool useFile = true);
Loads the session if available, and creates one if not. May write a session id cookie to the passed cgi object.

void invalidate();
Kill the current session. It wipes out the disk file and memory, and changes the session ID.

You should do this if the user's authentication info changes at all.

void regenerateId();
Creates a new cookie, session id, and csrf token, deleting the old disk data. If you call commit() after doing this, it will save your existing data back to disk. (If you don't commit, the data will be lost when this object is deleted.)

void clear();
Clears the session data from both memory and disk. The session id is not changed by this function. To change it, use invalidate() if you want to clear data and change the ID or regenerateId() if you want to change the session ID, but not change the data.

Odds are, invalidate() is what you really want.

const bool hasKey(string key);
like opIn

string opDispatch(string name)(string v = null);
get/set for strings

void reload();
Discards your changes, reloading the session data from the disk file.

void commit(bool force = false);
Commits your changes back to disk.

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.

class TemplatedDocument: arsd.dom.Document;
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.

string[string] vars;
use this to set up the string replacements. document.vars["name"] = "adam"; then in doc,

hellp, {$name}.

. Note the vars are converted lazily at toString time and are always HTML escaped.

string delegate(string, string[], const(Element), string)[string] viewFunctions;
In the html templates, you can write {$varname} or {$varname|func} (or {$varname|func arg arg|func} and so on). This holds the functions available these. The TemplatedDocument constructor puts in a handful of generic ones.

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.

string makeSaltedPasswordHash(string userSuppliedPassword, string salt = null);
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...

bool checkPassword(string saltedPasswordHash, string userSuppliedPassword);
and use this to check it.

Table structToTable(T)(Document document, T arr, string[] fieldsToSkip = null);
implements the "table" format option. Works on structs and associative arrays (string[string][])

Table structToTable(T)(Document document, T s, string[] fieldsToSkip = null);
does a name/field table for just a singular object

string makeJavascriptApi(const ReflectionInfo* mod, string base, bool isNested = false);
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 javascriptBaseImpl;
The Javascript code used in the generated JS API.

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

The names with a leading underscore are meant to be private.



Generally:
YourClassName.yourMethodName(args...).operation(args);



CoolApi.getABox("red").useToReplace(document.getElementById("playground"));

for example.

When you call a method, it doesn't make the server request. Instead, it returns an object describing the call. This means you can manipulate it (such as requesting a custom format), pass it as an argument to other functions (thus saving http requests) and finally call it at the end.

The operations are: get(callback, args to callback...);

See below.

useToReplace(element) // pass an element reference. Example: useToReplace(document.querySelector(".name")); useToReplace(element ID : string) // you pass a string, it calls document.getElementById for you

useToReplace sets the given element's innerHTML to the return value. The return value is automatically requested to be formatted as HTML.

appendTo(element) appendTo(element ID : String)

Adds the return value, as HTML, to the given element's inner html.

useToReplaceElement(element)

Replaces the given element entirely with the return value. (basically element.outerHTML = returnValue;)

useToFillForm(form)

Takes an object. Loop through the members, setting the form.elements[key].value = value.

Does not work if the return value is not a javascript object (so use it if your function returns a struct or string[string])

getSync()

Does a synchronous get and returns the server response. Not recommended.

get() :

The generic get() function is the most generic operation to get a response. It's arguments implement partial application for you, so you can pass just about any callback to it.

Despite the name, the underlying operation may be HTTP GET or HTTP POST. This is determined from the function's server side attributes. (FIXME: implement smarter thing. Currently it actually does it by name - if the function name starts with get, do get. Else, do POST.)



Usage:
CoolApi.getABox('red').get(alert); // calls alert(returnedValue); so pops up the returned value

CoolApi.getABox('red').get(fadeOut, this); // calls fadeOut(this, returnedValue);



Since JS functions generally ignore extra params, this lets you call just about anything:

CoolApi.getABox('red').get(alert, "Success"); // pops a box saying "Success", ignoring the actual return value



Passing arguments to the functions let you reuse a lot of things that might not have been designed with this in mind. If you use arsd.js, there's other little functions that let you turn properties into callbacks too.



Passing "this" to a callback via get is useful too since inside the callback, this probably won't refer to what you wanted. As an argument though, it all remains sane.







Error Handling:

D exceptions are translated into Javascript exceptions by the serverCall function. They are thrown, but since it's async, catching them is painful.

It will probably show up in your browser's error console, or you can set the returned object's onerror function to something to handle it callback style. FIXME: not sure if this actually works right!


Page generated by Ddoc.