Here's a blog post for all you hard-core developers.

This week we are merging a number of exciting changes from a development branch - known as "branches/roa" to some - into the main subversion trunk release.  Those of you who wish to access these features early will be able to do so by using the subversion trunk or the daily builds.

Update: These features have been merged into the main trunk and stabilised.

With these features, we are improving the usefulness not just of SilverStripe CMS, but of Sapphire, the underlying application framework that we developed in-house to power the CMS.  The common thread in all these new features is that, by increasing the intelligence of the model layer, we are able to provide an out-of-the-box application with a completed user interface, that tailors itself to the data model that it is given.

The SilverStripe CMS is a good example of this: you are able to easily customise the content fields available on each page, but the overall CMS interface is there for you out of the box, and is fairly consistent from site-to-site.  These new developments take the paradigm that we successfully applied to content management, and extend it to support a wider range of applications, such a CRM systems.

Historically, we haven't said a lot about the Sapphire framework, but you can expect this to change.  The Sapphire framework is becoming an increasingly important part of the software that SilverStripe produces.

So, what are these new features?  Here is a quick sneak-preview of what they will all be; more detailed developer documentation will be available soon.


ModelAdmin is a revised version of GenericDataAdmin, re-written from the ground up.  It lets you build a sophistic data management application solely by defining the data model that you wish to manage.  It is supported by two more general enhancements: SearchContext and scaffolding. Both of these enhancements are part of the Sapphire framework, usable in a wide range of applications beyond CMSes.


SearchContext is a class that eases the creation of a search form and the generation of its result set.  It is used to make the search system in both ModelAdmin and RestfulServer.

Given a set of search filter definitions, it will create an appropriate search form, and then it will create a SQL query when that form is submitted.  As well as searching on fields of the the DataObject itself, it also lets you traverse DataObject relationships to search by fields in related objects.  For example, suppose that we have an Organisation DataObject. Instead of having its address fields directly on it, has a 1-many relationship with an OrganisationLocation DataObject.  If you were to define the following on your Organisation object, then ModelAdmin and other users of the search context would be able to search for Organisation objects by looking for related OrganisationLocation objects.

	 static $searchable_fields = array(
"Name" => array(
'field'=> 'TextField',
"OrganizationLocations.State.ID" => array(
"title" => "State",
"OrganizationLocations.City" => array(
"title" => "City",


Our scaffolding system is a way of generating sets of FormFields for editing a DataObject, based its definition.  For example, a Varchar would be editable with a TextField, and an Enum would be editable with a DropdownField.  SilverStripe takes this a step further, and can generate fields for editing relationships as well as regular fields.  For example, a ComplexTableField is generated for a has_many relationship, and a ComplexTableField with an autocomplete facility is generated for a many_many relationship.

To access the scaffolded fields, just call getCMSFields() on any DataObject.  ModelAdmin uses this to build its add & edit forms for records. 


The RestfulServer is another system that makes use of this enhanced data model to provide you more useful functionality out of the box.

On any of your data objects, simply specify static $api_access = true;.  You will then be able to access your database using RESTful requests. All the the requests start with /api/v1, which is handled by the RestfulServer controller.  Here are some example requests that you could make on the RESTful server, if you set Page::$api_access to true:

  • GET Get Page record #36 in an XML format.
  • GET Get all the children of page #24 in JSON format.
  • PUT Update page #24 using JSON format.

Security is configured using the canView() and canEdit() methods on your data-objects, and RESTful users can authenticate themselves by sending their regular log-in details over HTTP basic authentication.

New URL Hander

As part all this work on ModelAdmin we've improved the URL handler that processes requests.  To give an example, consider the processing of the URL "admin/crm/Organisation/36/edit".

Historically, a URL such has this would have been handled by a single Controller.  It would have been up to that controller to identify the different URL components and amend the responses of all handler functions accordingly.

Now, however, the URL is processed by a chain of controllers and sub-controllers:

  •  admin/crm directs Sapphire to the ModelAdmin class you have created
  • Organisation/36 directs to a special "sub-controller" that will handle any requests about Organisation #36 within that model admin.
  • edit is an action on that sub-controller.  Specifically, it will provide the interface for editing Organisation #36.

The URLs can be arbitrarily deep.  This makes it easier create complex FormField subclasses that have their own behaviour such as pop-ups or ajax responses.  In particular, we used this new URL handler to clean up the internals of ComplexTableField.


That covers the changes that I wanted to introduce!  I'll update this post once we have merged these changes back.

Post your comment

Comments for this post are now closed.



Sam, can we see a sample of SearchContext usage rather soon?

Posted on 9 Nov 2008 by ylluminate

Ben: No it doesn't. It just means that the new URL system will allow a developer to implement the sub-level URLs you're talking about easier. To repeat: this feature is NOT in the upcoming version of SS.

Posted on 4 Sep 2008 by Sean

So can you elaborate on the new Url hANDLER A BIT MORE? Does this mean that in SS we can now have long urls? e.g

Posted on 19 Aug 2008 by Ben Felows

Christoph Strasen: I wouldn't recommend it. It's currently being merged into trunk, but it won't be stable for a number of weeks yet.

Posted on 9 Aug 2008 by Sean

dashiel / Travis: Although it doesn't directly give nested URLs out of the box, the sub-controller system will make it easier to implement that feature. I believe that "Grayzag" has been working on nested URL support, so here's hoping!

Posted on 8 Aug 2008 by Sam

Can't wait to see this!

Posted on 8 Aug 2008 by Rane

just to second travis' invquiry. will we be able to have nested pages on sites or is this just for the CMS?

Posted on 8 Aug 2008 by dashiel

Silly question: Does this sub-handler behaviour bring the ability to have nested pages? EG: /articles/how_to_cook_eggs/ rather than the current /how_to_cook_eggs/

Posted on 7 Aug 2008 by Travis S

Wohee! Nice post indeed and good to know where (in SVN) those changes lie. I Guess those sub-controllers are optional to use? Any idea how much heavy change is still going to take place in that branch? I wonder if our project currently starting should use that branch right away to not get too used to the former version.

Posted on 6 Aug 2008 by Christoph Strasen

Nice work. Looking forward to trying it out. Typo in paragraph 3 btw: "such a CRM systems."

Posted on 6 Aug 2008 by Jeremy S