Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.


Converting from SilverStripe 2.4 to 3.1-beta

Fred Condo has a Ph.D.

by Fred Condo

Posted 6 March 2013

Read post

Fred Condo has a Ph.D. in the Management of Information Systems and Cognitive Psychology from Claremont Graduate School, and is Chief Engineer at Quinn Interactive. Quinn Interactive is a web design & development firm located in San Francisco, California specializing in interactive design, content-management integration, IA, and custom development. Fred got into SilverStripe in 2008. He has made 24 commits to the SilverStripe framework repository, which makes him the 28th-most prolific contributor to the project. You should follow him on GitHub here.


  • We did a 2.4 → 3.1-beta conversion
  • We made the minimal changes required to get the site running under the new framework
  • Bye, Data Object Manager!
  • The ORM’s new fluid syntax is great (unless you forget to save the result!)
  • It was easy!

About our upgrade

When QI began using SilverStripe, we converted our static HTML site to SilverStripe 2.3. Over time, we upgraded to 2.4, and eagerly awaited SilverStripe 3.

We’ve now developed new sites starting with SilverStripe 3.0, and are ready to convert sites from 2.4. To prepare to upgrade our clients, we converted our own site. We also changed our make– and rsync- based deployment to something more robust, Capistrano.

We chose to convert to SilverStripe 3.1-beta, reasoning that, by the time our clients started approving upgrade projects, 3.1 would be the generally available release. We also did not want to optimize at this stage, and do only what was necessary to run under 3.1.

Converting our code base

The conversion took 91 git commits. Twelve were Capistrano-related, so 79 commits pertained to SilverStripe and code-management overhead, such as merge commits. Because this was our learning experience, we kept changes as separate commits, rather than squash them together.

Our mysite/code directory contained 2942 lines of code before the conversion, and 2820 afterwards, a reduction of 4%. Our template files had 1399 lines before, and 1366 afterwards, a 2.4% reduction.

Template changes

The new template engine is strict about include files, so it uncovered includes that referenced nonexistent files. We just removed those lines.

<% loop %> does what <% control %> once did. There is other new syntax, too.

-                    <% if ShowInToolsPages %>
-                        <% control ShowInToolsPages %>
+                    <% if $ShowInToolsPages %>
+                        <% loop $ShowInToolsPages %>
                            <% if First %><% else %> | <% end_if %>
                            <a href="$Link">$MenuTitle</a>
-                        <% end_control %>
+                        <% end_loop %>
                    <% end_if %>

Directives now accept `$` on variable names, and `loop` replaces `control`.

Template calls now take comma-separated parameters. Where we used a string with artificial delimiters, we now have a more familiar syntax. `$Image.CroppedImage(165x165)` becomes `$Image.CroppedImage(165,165)`.

PHP changes

Module updates

We had to update modules to their 3.x-compatible versions. This often meant importing the code from the master branch. Many module repositories were not clearly tagged with 2.4– and 3.x-compatible versions. It required trial-and-error to get some modules running.

We could eliminate several modules, because the new framework is more capable:

  • Data Object Manager
  • Uploadify
  • Image Extension (our internal module of image-manipulation methods; we eventually kept 2 methods—see below)

Data Object Manager by Aaron “Uncle Cheese” Carlino is popular for SilverStripe 2.x. It is not available for 3.x, because GridField supersedes it. Here’s a sample change (from a getCMSFields() method) for replacing it:












ORM changes and fluid syntax

The ORM has undergone a big overhaul. DataObjectSet is gone, and a new fluid syntax simplifies data operations. To set up paginated items, we once had to manage pagination-related GET parameters, but can now focus on our custom code. Below, we use a GET parameter only for filtering on a year. See this line:

$result = $result->filter('Date:StartsWith', $year);

We tripped over this when it wasn’t working without assigning back to $result . The new ORM returns a result rather than modifying the existing one. This works nicely with the fluid, chained syntax, but needs help when a call is conditional.








Redirection functions have moved classes

Director::redirect() and related functions have moved to Controller, and become instance methods.









Image extension

Here are the functions from our image extension that we still wanted after the 3.1 upgrade.