NoClass Framework – Json Containers

I’ve been working with Apache Couch DB for several months, and have developed a method for templating and html storage that negates the need for actual html to be written (in many cases) and can enforce permissions and fine graned field visibility. This method relies on a scripting language (php in this case) and a few newer functions (php 5.3.x) that use an overloaded html element/tag generator inside a dozen-line static class.

We have a blog. Blogs have pretty much the same stuff, field for ‘post’ content, publisher,summary, etc.

	// JSON Record (from couch)
{
"_id": "post_example",
"_rev": "1-6122fbacd408d8700611570143d3f207",
"post_title": "a title",
"category": "",
"post_type": "post",
"content": "Here is an amazing blog post.",
"publisher": "me",
"summary": "",
"status": "published"
}

Here is a ‘template’ array structure, this could be stored and converted from a json object as well.

// PHP Container
$container =
array('head' =>
array('link__stylesheet'=>'main.css') ,
'body'=>
array('div__page'=>
array('div__post' =>
array( 'post_title'=> 'h2__' ,
'category'=>'h3__',
'publisher'=>'h4__',
'content' => 'div__',
'thumbnail_image'=> 'img__',
'post_tags' => 'div__'
)
)
)
);

The function looks at the array key value for a ‘__’, and then generates html based on that specific key name. If the value does not have ‘__’ then it is assumed to be similar to a value in the object ($this) and then uses that value of that key (without the double underscore) as the ‘html’ generation class and the value of the $this as its value.

// 'load_template' php function, that dynamically calls overloaded
// html 'generation' static class

function load_template($array,$key=false){
if(is_array($array)){
if(strpos($key,'__')){
// Handles iterative operations to properly generate the nested
// HTML (when structured appropriately) for valid values..
// I.e. reduces structures like body->page->post->post_title
// body->page = string(post,post_title);
$html_call = $key;
$r = $this->load_template($array);
foreach($r as $iField=>$iValue){
if($iValue != '')
$r2[$key] .= $iValue;
}
return htmler::$key(implode($r2));
}
foreach($array as $key2=>$array2){
$r[$key2] = $this->load_template($array2,$key2) ;
}
}
elseif($key !=false && $this->$key != false){
// get ready for htmler structure, which will set the field name to the
// could accept another parameter to determine how the field name is
// used within the created htmler structure return HTML ?? paired with
//the object's key value as a return param ??
$html_call = "$array"."$key";
return htmler::$html_call($this->$key);
}elseif(is_string($array) && strpos($key,'__') ){
$html_call = $key;
return htmler::$html_call($array);
}
return $r;
}

Advantages

Smaller json objects, so faster throughput all around. In CMS environments editors can be made to help avoid common html markup mistakes. HTML knowledge isn’t required – and can easily be abstracted to use whatever concept the developer desires (blocks,widgets,sections) while implementing their container of choice (div,ul,li). This becomes more useful when dealing with mobile-based browser web-apps, or when implementing js/mobile frameworks like jqTouch; instead of rewriting an application one may simply modify its containers and/orĀ ’editor’ class.

Scripting languages can effectively (under a default localhost restricted installation, or where passwords are required) act as a gate keeper of data restricting fields to specific users/groups (or entire records), either through the container or a session.

Control is handled primarily through calling the object as a method and passing it a directive, or loading a container when creating the object (or in many cases both)

Containers are easily cacheable and retrievable via APC or memcached, both the container and class can also be stored and converted back from json

The code base is usually very small, (and in my personal php (5.3.x) testing pages would load in normally under 1 meg) at around 20-60ms.

Complications

Storing html directly in json records is still entirely possible; with a multiuser cms this may be very likely, unless
values are parsed for markup. I do not really see this as a huge disadvantage. Most html code lies in markup containers and head values. By ‘forcing’ a designer to work in ‘containers’ we are actually doing them a favor. In the end the developer is in charge of how a designer might interface with the CMS; the developer is left to handle the big questions.. embedded html or an advanced interface that generates the needed json/array structures to avoid it.

Where from here?

In future articles I will talk about my other couchdb related libraries that handle a session cookie (couchCookie), caching (couchCache) and html form generator (poform).

Tools for Apache Couch

I have been working on several libraries that I use to interact with couch (couchCurl), forms (poform), and COOKIES (couchCookie). Although it would be easy to write a layer to use MySQL/Postgres, ‘couch’ is in the title, plus I’m a little sick of SQL.

The libraries below exist in a code base of around 6k-10k (poform being the largest).

couchCurl

couchCurl, in a nutshell, generates unix curl commands and executes them via php’s exec() function. In addition, some functions do automatic handling of some of the more obscure API behavior (like PUT versus POST).

poform

poform is sort of like a ’streamlined’ version of sqlee, that can generate a form based on a classes parameters (and values of those parameters). Simple associative array structures can define common HTML and HTML5 objects (such as select, text, password, email) and a few others. It exists as a static class with two major functions – ‘load’ – which will determine the objects state based on a $_POST variable and that classes’ construct method directives and begin to modify each parameter field by field to reflect these changes, and ‘make’ which returns a string with the HTML form. poform looks for class parameters (_r) for required fields for couchCurl insertion, _d for parameters to carry to the next $_POST state (if a class/has fields that change based on a previously selected value), and _f for parameters to ‘filter’ and render in the final ‘made’ poform object.

couchCookie

This class handles a session via a simple random-generated key in a cookie. It is designed to be used with poform, but it can be used without. A users credentials are authenticated against a view in a couchdb ‘users’ database, if successful, another record (with the cookie id, and some other information like IP address, time created, and user id) is stored in a ’sessions’ database. When the user logs out the clients’ cookie is deleted, and the record in the database is removed. If at anytime a cookie’s key changes from what is in the couch db, the transaction will not take place.

Ronaldo Returns

Honestly… I didn’t forget about you. And I have not kicked the habit…

Here’s a rundown on changes to my workflow:

I’ve jumped on the NoSQL bandwagon, stopped writing mysql statements/schemas all together in the interest of designing classes more intelligently and to use less memory/resources. And I quickly realized interacting with SQL does not help a programmer think in an object oriented fashion, which would explain my pursuits with Aiki framework and myparse … both frameworks that pretend to be object oriented, but do not take advantage of half of the basic OOP principals, let alone some of syntax introduced in modern versions of PHP.

Once my Google Summer of Code internship ended, I began exploring couchdb, map/reduce, and decided to rewrite an application (mdocs) that I have been developing for 3 years, previously running on a custom version of myparse and sqlee. Also the new version was built to be easily used with jQTouch.

Also that summer I had been dealing with a ‘rouge’ hacker who was able to gain access to the mysql database through myparses’ web interface and would delete all the users groups preventing any logins. Instead of dealing with my unmanageable code I decided maybe mysql was a bit over kill for my web application and it was time for a rewrite.

Although I still have not added every feature, the new version loads much faster, uses significantly less code, and doesn’t hit a database with several overly complex sql statement every page load. While php 5.3 uses about 50% more memory just to be called (plus whatever memory your scripts use) versus php 5.1. Its also more modular, and automatically handles dynamic class loading (require($class.php) , new $class() ).

While performance wasn’t my initial goal, for me speed is always addictive, so I decided to implement memcached on nginx (also a new to me technology), and set up an intelligent way to handle secure cookies, reducing page load times by about half. All data (except the logout which uses a $_GET var) is passed via the $_POST object, and even that is validated through PHP, and again inside of the couchdb’s view before an action takes place. Since all classes are built around poform (including couchCurl), it becomes very difficult for nefarious hackers to manipulate a session state.

Well, stay tuned, as I have a lot of stuff I have written but just have not edited and published.. Good stuff…