Server-Driven Constants

On the web today, it is commonplace to use JavaScript to communicate with the server (think AJAX or manipulating window.location). This means that there will be parameters that are the same on the server- as in the client-side code. As your code grows there will be more parameters and occasional name changes, resulting in parameter management increasingly wasting your time and/or causing errors. As a result it is considered best practices to manage these parameters on the server as constants where they can be maintained in one place and propagated throughout your code.

I recommend using constants for the following:

  • Query Parameters
  • Class and Id DOM attributes
  • Messaging and Dynamic text
  • Errors
  • XML tags and JSON keys
  • Cookie Keys

My general rule of thumb is to create a constant any place where a String references the same value in the server- and client-side code. I do a pretty good job of this on Mint.com, which allows me to change query parameter names in seconds (without having to do a find/replace), return error codes to the JavaScript for handling (such as a session has timeout out), reduce the number of query parameters to a manageable set, and a whole lot more.

Server-side you should use whatever constant paradigm you are comfortable with. In JAVA I tend to use a static object that I call WebConstants and attach constants to it. In PHP, I tend to use a large, associative array, where the constant is the associative key. Consider the technology you are most familiar with and how best to use constants.

Client-side, I recommend that you map everything to a common namespace. I usually use something like, ProjectName.constants.constantType.constantName (capitalize ProjectName, but camel-case the other namespaces). Then I make capital C a shortcut to ProjectName.Constants. This way, if I want to use the query parameter for username, you would use: C.query.username. I find that I most frequently use the query parameter constants when hand creating AJAX requests.

At this point, you are probably wondering about how to pass the constants from the server code to the JavaScript. This can be done many different ways, but the best is to have a build process that iterates through the constant, creating a constant.js file and include that in your JavaScript library. If you already run a build process when starting your web application, then just add another step, otherwise, you need to write and run a build step when changing a constant.

Here is a simple PHP function that I use in my build step to convert my PHP constants into JavaScript ones:

Example 1: PHP JavaScriptConstantWriter

JavaScriptConstantWriter


I had to link this file, because wordpress keeps choking on the PHP code snippets in here.

This function requires that several parameters are passed in: an associative array of constants, the path to your projects JavaScript directory, the name of your constant file (defaults to constants.js), and the namespace to attach the constants to (defaults to Core.Constants). Since this function is for personal use, I make several assumptions about the naming convention used for constants, which well discuss below.

Example 2: Calling writeJavaScriptConstants

$_C = array(
    HTML_KLASS_PROJECT_NAME =>project,
    HTML_ID_PROJECT_NAME =>project,
    QUERY_KEY_USERNAME =>username,
    QUERY_KEY_EMAIL =>email,
    QUERY_KEY_PASSWORD =>password,
    SESSION_KEY_USER =>user
);
$pathToJs = .. . DIRECTORY_SEPARATOR . .. . DIRECTORY_SEPARATOR . .. . DIRECTORY_SEPARATOR . assets . DIRECTORY_SEPARATOR . js . DIRECTORY_SEPARATOR;
$fileName = constants.js;
$prefix = Core.Constants;

writeJavaScriptConstants($_C, $pathToJs, $fileName, $prefix);

Example 2 will produce the following constants.js file:

Example 3: Results of writeJavaScriptConstants

Core.Constants={};
Core.Constants.html={};
Core.Constants.html.klass={};
Core.Constants.html.klass.PROJECT_NAME=project;
Core.Constants.html.id={};
Core.Constants.html.id.PROJECT_NAME=project;
Core.Constants.query={};
Core.Constants.query.key={};
Core.Constants.query.key.USERNAME=username;
Core.Constants.query.key.EMAIL=email;
Core.Constants.query.key.PASSWORD=password;
Core.Constants.session={};
Core.Constants.session.key={};
Core.Constants.session.key.USER=user;

First it is important to note that the method makes no assumptions that a given namespace object exists, and creates a new Object for each new namespace. Therefore, if you attach anything to these namespaces, make sure you do so after you include constants.js in your library.

I use a very strict namespace convention for constants, where OBJECT + _ + TYPE + _ + NAME. If you use my logic, it is important that both OBJECT and TYPE are single words and do not have extra underscores. I sometimes use abbreviations or shortcuts to achieve this, but I find that this convention keep my constant names shorter. The NAME portion of the constant can have as many underscores as desired; I usually separate words with underscores.

So, if we consider the PHP cosntant HTML_KLASS_PROJECT_NAME, then the object is HTML, the type is KLASS, and the name is PROJECT_NAME. This will attach the namespace html to Core.Constants, then attach the namespace klass to html, and then attach the actual constant name to klass. Once I setup my shortcut C to reference Core.Constants, then I can reference this constant in JavaScript using C.html.klass.PROJECT_NAME. Therefore, if we ever decide to change the project name to say, Mint, then we change the constant value in PHP ($_C) and run writeJavaScriptConstants, and every reference in ones JavaScript is also updated. On a side note, I have used klass instead of class, because class&rsquot; is a reserved word in JavaScript.