The Birth of the JS API

by Nic Hubbard

It was June 17, 2009 and I was working at Pacific Union College in the middle of a project that required me to build an interface for Department Newsletters. At the time, I wanted to allow Department users to build their own newsletters and send them out to bulk mail lists. It was a complex system and I was running into problems because I required a great number of nested asset listings to retrieve the data that I was needing. After building complicated pages filled with multiple nested asset listings, it occurred to me that there had to be a better way to do this.

With this idea in mind I moved over to my development system to take a look deep into the code. I started out building a single .php file that lived in the _lib directory. It was a hacked together file that included some of the core Matrix files and allowed an asset ID to be passed in as a GET var. The page would then return a set of information in JSON format. It was a great start and did what I wanted at the time, but that quickly changed. There was more that I wanted to do with it but it was getting complicated fast. Adding additional GET vars to the query string to specify what kind of data I wanted returned was nice but it still seemed really hacky. So at this point I thought it would be a good idea to get a feel for what Squiz thought about the idea. It wasn't something that was already in Matrix, so it seemed like it might be something that users would want. So I emailed Greg Sherwood with a simple email about my idea:

Hey Greg,

I have been working on something today that I personally feel is awesome, and would be a great addition to Matrix.  But, not sure how you feel about this.

I want a way to better get information about assets using javascript.  So, I wrote a javascript api page, that lives in the __lib folder, what when you pass an asset ID, it will return JSON about the asset.  A wealth of info could be sent back, including normal asset data, attributes, even linking info, multiple webpaths in arrays, etc. etc.

Would this be something that could eventually submit to the Matrix core, or, do you feel this is better left to my dev systems?  Personally, I think it would be a very cool addition to Matrix to have something like this.  With of course, appropriate permissions built in, so that any person can't get grab info about another systems assets.

What do you think?

I wasn't sure how they would feel about it, but the next day Greg wrote back with his support of the idea. He had some suggestions and requirements such as building it into its own asset type, which I also though was a great idea. So I went to work building the asset type and writing in some features that I thought would be cool. When I finally had a finished 0.1 version of the API to send to Squiz it didn't have very many features available. It has the following core features:

  • Get General Info
  • Get Attributes
  • Set Attributes
  • Trash Asset
  • Get Metadata
  • Set Metadata

The 0.1 version was released in MySource Matrix 3.22.2

But then something bad happened. My Dad was admitted to the ICU for pneumonia and Swine Flu.

Now this may not seem like it has anything to do with the creation of the JS API, but it really does. My wife and I flew up to Washington State to be with family while my Dad was in the hospital. Most every day involved going to the hospital and visiting my Dad. Between those times were filled by sitting in the waiting room where they had free WiFi. With all the extra time that I had I figured there was no better time to work on developing and testing the JS API. So I spent the next two weeks working on the code for hours each day. I can happily say that after those two weeks (and some very scary moments) my Dad was ok. But that time allowed me to get some of the grunt work done and get some of the kinks worked out.

The next week I was ready to send a plethora of new updates to Squiz. I moved the version from 0.1 to 0.2 and included the following features:

  • URL can now be used in addition to the asset id. Managed by a new setAsset() function.
  • Additional getGeneral items added: web_path
  • getAttributes now does not allow the API key attribute to be sent, it returns ''.
  • getChildren function added. This allows you to get all the children below an asset by specifying the levels to return.
  • getParents function added.  This allows you to get the parents of an asset.
  • getPermissions function added. This allows you to return all permissions for an asset, including children of groups.
  • getGroupChildren used to get child asset information about user groups.
  • createAsset function added.  This allows you to create assets under a parent.  There are also many advanced options that can be used for the function.
  • getAssetTypes function added. This returns all installed assets types that can be created. (Instantiable assets)
  • acquireLock function added. This aquires the lock for specific assets and screens.
  • releaseLock function added. This releases the lock for specific assets and screens.
  • createLink function added. This will create a link from one asset to another.
  • removeLink function added. This will remove a link between a parent and child.
  • moveLink function added. This will move a link from one parent to another.
  • updateLink functino added. This will update a link between a parent and a child asset.
  • getLinkId function added. This will get the link id of a parent and a child asset.
  • hasLink function used as helper to see if a parent and child have a link.
  • getAssetTree function added. This will return asset tree information.

A few months later I was working on another project for PUC and needed to create an asset and include attributes when creating. This led to another JS API update:

  • Create Asset Types: Users can now restrict what types of assets are allowed to be created with the createAsset() function.  They can choose multiple asset types, or leave it blank to allow creation of any type. The php function createAsset() checks if asset types are used, and if the asset types requesting to be created don't match those set in the API, an error will be returned.
  • Allow Attributes on Create: This boolean attribute which defaults to no, allows a user to send additional data to the API that will populate attributes of newly created assets.  The createAsset() JS function has two new params, extra_attributes (set to 1 to allow this feature) and attributes (pass additional serialized string). The php function createAsset() uses the passed type code to get attributes for that asset type, then loops through the post array, looking for name/value pairs that match, making sure not to use anything from the $link_info array. If it finds values that match those available for the type_code they are set as values of the attributes.
  • Return JSON: This boolean attribute which defaults to yes, allows the user to suppress JSON. This can be useful when using functions like createAsset() which would return the newly created asset id, link id, etc.  Which might not be info that you want users seeing.

This was my final update to the JS API and I was more than happy to leave it where I did. Squiz took the API and ran with it, cleaning up my code, creating great new features and finally using it in the Easy Edit Suite. Recently the most amazing update was added (in my opinion) which was the Enhanced version of the API. This brought jQuery style method calls which I think are absolutely amazing!

Thanks Squiz for the amazing work that you have done on my original idea!

Nic Hubbard is the Webmaster at Pacific Union College as well as owner of Zed Said Studio.
You can find him on Twitter as @zedsaid or contact him on zedsaid.com.