Quinn Labs: A website about building websites

SilverStripe vs Drupal

SilverStripe vs. Drupal, a developer’s perspective

We’ve been using SilverStripe since 2008. Before that we’d worked with a ton of other open-source CMS solutions, including WordPress, Drupal, Plone, MODx, Joomla, Mambo, and others as well.

We switched to SilverStripe because it was the first CMS we found that works they way we feel a CMS should. It’s a true OO (Object-Oriented) MVC (Model/View/Controller) framework like Ruby on Rails, but with a full-featured, customizable CMS editing environment already built in.

Nowadays we use SilverStripe for almost all our projects, and I’m often asked why we don’t use some other tool. Most of the time, that other tool is Drupal.

I’ve seen lots of comparisons between SilverStripe and other CMSs like Drupal, but most of them are either very high-level, or mostly editor-centric. So I thought I’d explain why we chose SilverStripe over Drupal, from the point of view of a web developer.


Part of the problem with doing a comparison is that Drupal and SilverStripe are not really the same kind of tool. Sure, they both allow you to build and manage websites, but they were created to serve different audiences.

Drupal’s Philosophy

Drupal’s greatest strength is that you can get a feature-rich website up and running with little front– or back-end development expertise. It has a slew of modules, themes, and other extensions that allow you to build a website without having to write much code. There are both free and commercial add-ons for Drupal.

Because Drupal’s audience isn’t code-slingers, they’ve pushed many of the things that are typically managed in code into the web-based admin area of the system. This is great for content authors who want lots of control over the structure and functionality of their site. But it’s terrible for developers and sysadmins that want to be able to have testable, deployable sites.

SilverStripe’s Philosophy

SilverStripe’s approach is different. SilverStripe was built with the idea that content authors, developers, and designers all have different skill sets and roles on a project. It tries to provide the best possible experience for all three roles, while also trying to keep them from tripping each other up.

Here at QI (Quinn Interactive), we wholeheartedly agree with this approach. If you make changes to the underlying data model of your website, through the CMS’s admin interface, and store those changes in the database, you can’t deploy them easily and separately from the content of the site.

That’s a huge part of the philosophy of MVC frameworks. They strive to separate the model (how the data is stored) from the view (how the site looks) and the controller (how the site works).

This way your editors can do what they do best, creating and updating content. Your designers and front-end developers can focus on the way the site looks without getting tangled up in PHP coding. And your developers can focus on the way the content is structured and related, and how the site functions.

Wikipedia describes SilverStripe’s philosophy pretty well:

From Wikipedia.org: SilverStripe separates the roles of content authors (who get a rich (AJAX) web-based user interface that omits technical jargon) and website designers/developers (who write code: HTML, CSS, JavaScript, and PHP). This provides a contrast to CMS products that allow technical website development tasks to be performed within a GUI, and a contrast to programming frameworks that offer no out of the box content authoring application. The SilverStripe approach is stated to remove complexity for content authors, and offer more flexibility to developers.

Content Types

The way Drupal and SilverStripe approach adding custom content types is starkly different.

With the introduction of Drupal 7, the standard way to define content types is with the now built-in CCK (Content Construction Kit). You do this through the web, in the CMS. So the definition of your new content type, and its fields, are stored in the database, along with the actual content of your site.

SilverStripe, on the other hand, has you configure pages and other data objects by extending PHP classes to create new content types, all in PHP.

At first blush, this might seem like a big win for Drupal, because you can define a new type of page without having to know any PHP. But there are some serious drawbacks to defining your model in your database:

  • You can’t keep template coding and styling in sync with your site’s data model, especially if you’re using a revision control system like git or subversion.
  • You can’t deploy your data model changes to other sites without also migrating your content, since that’s where the model lives, instead of separately in the site’s code.
  • You can’t easily deploy changes to more than one site, without manually going in and re-defining your data model changes.

Using the CCK is not the only way to define content types in Drupal, but it is by far the easiest. However, most Drupal modules do it in code, for the same reasons outlined above.

To illustrate all this, let’s imagine we want to add a new page type to our out-of-the-box Drupal or SilverStripe site: a new Bio page, with a “Job Title” field and a photo.

We’re going to work with the default theme that comes with Drupal, called bartik.

Drupal Content Type Steps

Define the new Drupal page type

As we mentioned before, there’s a way to do all this in just code, although it’s quite complicated. And for most Drupal users, one of the main appeals of Drupal 7 is creating new content types and fields via the front-end admin dashboard, so let’s stick with the CCK. 

(I was going to include screenshots of all of these steps but frankly there are just too many. If you’d like to learn more about this process, and see some screenshots, read Creating and Theming a Custom Content Type with Drupal 7 from Linux® Journal.)


  1. Log into Drupal 7’s dashboard
  2. Choose “Administration”
  3. Choose “Structure”
  4. Click on “Add content type”
  5. Fill out form with name and description
  6. Click on “Save and add fields” button at bottom
  7. Add new field: “Job Title”
  8. Select “Text” field type
  9. Save form
  10. Set Maximum length to 255 (default) and save field settings
  11. Set additional field settings like Label, Help Text, Size, Default and then save settings
  12. Add new field: “Photo”
  13. Select Image field type
  14. Save form
  15. Set default image (leave blank) and then Save field settings
  16. Set additional field settings like Label, Help Text, Size, Default Image, subdirectory for uploads, min/max dimensions and size, etc… and then save settings

Now our new page type is defined in the database and we can create a theme for it.

Define Drupal page template

If you’re happy with the HTML that Drupal generates for your field, you can just style this up in your CSS. Of course, since you’re managing your CSS in code and your content/field types in the DB, they will be out of sync, and harder to manage and deploy.

Here is the HTML snippets Drupal generates by default for our two new fields.

<div class="field field-name-field-job-title field-type-text field-label-above">
  <div class="field-label">
    Job Title: 

  <div class="field-items">
    <div class="field-item even">
      President, Quinn Interactive, Inc.

<div class="field field-name-field-photo field-type-image field-label-above">
  <div class="field-label">

  <div class="field-items">
    <div class="field-item even"><img typeof="foaf:Image" src=
    "http://drupal.lh.quinn.com/sites/default/files/phil-cartoon.png" width="369"
    height="438" alt="" /></div>

If, however, you want to have more control over where and how the fields show up in your template, we’ll need to set up a custom page template.

There are dozens of ways to do this, all of them tackling this problem from a different angle. We’ll look at one of the simplest ways, although a real Drupal expert might have a more elegant solution.

In our theme’s template.php file, we’ll add (or create) to the THEME_preprocess_page() function to look for custom page types, where THEME is the name of your theme. (I’m only showing the new function, not the whole template, because this file can get lengthy).

function bartik_preprocess_page(&$vars, $hook) {
    if (isset($vars['node']->type)) {
    // If the content type's machine name is "my_machine_name" the file
    // name will be "page--my-machine-name.tpl.php".
        $vars['theme_hook_suggestions'][] = 'page__' . $vars['node']->type;

Create your new template in the theme’s templates folder called page–-bio.tpl.php (we just copied the existing page.tpl.php file) and add some code to our new page template to display our job title in an H2.

<?php if ($node->field_job_title['und'][0]['safe_value']): ?> 
    <h2 class="job-title" id="job-title">
        <?php print_r($node->field_job_title['und'][0]['safe_value']); ?>
<?php endif; ?>

Now add some PHP/HTML code to our new page template to display the photo.

<?php if ($node->field_photo['und'][0]['filename']): ?> 
    <img src="sites/default/files<?php print $node->field_photo['und'][0]['filename']; ?>" />
<?php endif; ?>

You’ll also need to remove those default generated fields from the normal content display so they don’t show up twice. I tried to get that to work, using examples I found on the web, but couldn’t. But I’m sure an experienced Drupal developer would have no problems.

There are also add ons to make more of the template design happen through the web, but that’s not really a good choice for a professional site, where you really want to have more control over your HTML and CSS, not less.

SilverStripe Content Type Steps

Ok, now let’s do the same thing in SilverStripe. SilverStripe uses an object-oriented ORM (Object Relational Mapper) approach to this. You define new content types that extend existing ones. These new content types inherit all of the fields, methods, and other attributes of their parents, and allow you to extend and alter them from there. This leads to lean, non-redundant code. But it also means your developer needs to be comfortable with object-oriented programming concepts.

Define the new SilverStripe page type

To take advantage of the ORM, first we create a new PHP file to define the new model for our bio page. We’ll call it BioPage.php and extend from the built in Page class. We could also define a new controller class to extend the Page_Controller but it’s not required if we’re not adding any new functionality beyond the model changes.

In this new class, we’ll add the definitions for our two new fields. A model’s $db array holds any new fields, and the $has_one array holds relationships to other objects, like SilverStripe’s built-in Image class. There are also arrays available to provide for things like has-many and many-many relationships, indexes, defaults, and other model characteristics.

Additionally, we’ll extend the model’s getCMSFields()  function to add these fields to the editing interface.

Here’s our final BioPage.php file.

class BioPage extends Page { 
    private static $db = array(
        'JobTitle' => 'Varchar(128)',
    private static $has_one = array(
        'Photo' => 'Image',
public function getCMSFields() {
    $fields = parent::getCMSFields();
    $fields->addFieldToTab("Root.Main", new TextField('JobTitle'));
    $fields->addFieldToTab("Root.Main", new UploadField('Photo'));
    return $fields;

That’s the entire new content type, defined in a few lines of code.

Now we run a command, either through the browser or on the command line, to tell SilverStripe to update its database’s tables and columns to reflect the new model. This command is called dev/build.

Define SilverStripe page template

To control how this page looks, we’ll create a new “Layout” template for the main content area of our new page type, and we’ll name the template after our content type’s PHP class. That way we don’t have to do anything special to make it all tie together. We’ll call this new template BioPage.ss. Right in the template, we can resize and resample the image however we want. And we’ll also include the $Title and $Content fields we inherited from Page. Here’s the entire final template file.

<% if $JobTitle %>
    <h2 class="job-title">$JobTitle</h2>
<% end_if %>    
<% if $Photo %>
<% end_if %>    

Finally, we let SilverStripe know we have a brand new template to keep tabs on for its template caching, by running a command either through the web or on the command line called ?flush=all.

That’s it. All done.

Because our data model is defined in code, it can live in sync with our template changes in our git repository, and the two get deployed together when we’re ready to move them into production.


Both Drupal and SilverStripe enable you to create custom templates for how the content on your site is displayed. But they go about it very differently.

Drupal uses PHP files with HTML in them to deliver the content. SilverStripe has its own templating language which keeps the functional code to a bare minimum in the template.

For developers, this difference can be a philosophical one. Some developers feel that a templating language restricts their ability to customize the front-end display.

However, here at QI we decided years ago that a separate templating language was the way to go. We like this approach because:

  • It enables front-end developers without strong PHP skills to work on the presentation layer of the site, using the skills they do have, namely HTML, CSS, and JavaScript.
  • It keeps all the functional logic in one place—the controller—where it belongs.
  • It keeps security problems from being accidentally introduced into the templates.
  • Good templating systems can often be much more efficient than simple PHP files, because they can take advantage of lazy loading and pre-compilation without the front-end developer having to do anything special.
  • Good templating systems have code that is much easier to read and understand than raw PHP intermixed with HTML

Here are some snippets of template code illustrating the differences between Drupal and SilverStripe templates.


// Drupal
Hi, my name is <?php print $first_name; ?>
The first item is <?php print $items[0]; ?>
<a title="<?php print htmlspecialchars($title); ?>">Link</a>

// SilverStripe
Hi, my name is $FirstName
The first item is $Items.First
<a title="$Title.ATT">Link</a>

Control Structures

// Drupal conditional
<?php if ($first_name): ?>
    Hi, my name is <?php print $first_name; ?>
<?php else; ?>
    Please log in
<?php endif; ?>

// SilverStripe conditional
<% if $FirstName %>
    Hi, my name is $FirstName
<% else %>
    Please log in
<% end_if %>

// Drupal loops
<?php foreach($items as $item): ?>
    <li><?php echo $item->getTitle(); ?></li>
<?php endforeach; ?>

// SilverStripe loops
<% loop $Items %>
<% end_loop %>

And the variables can be complex, chained object references and/or function calls like these:

  • $Title
  • $Image.SetWidth(200)
  • $Image.Size
  • $CurrentMember.FirstName
  • $Customers.First.Photo.SetHeight(100).Size

i18n (internationalization)

Both Drupal and SilverStripe have powerful i18n localization capabilities, and use similar “t” functions to control localizable strings.


Both SilverStripe and Drupal are LAMP applications, and have the same performance issues to deal with. Out of the box, Drupal may have slightly better performance because it doesn’t use an object-oriented approach for its models, which makes them tend to be simpler in the DB, but less easy to extend and customize in the API.

For any serious popular site, both platforms will typically need some performance tuning. And once you’ve done what you can with the underlying platform tuning, you’ll probably want to explore caching options. Both SilverStripe and Drupal have caching solutions built in, but they take much different approaches.

Drupal Caching

Drupal comes with built-in page caching that you can turn on in the administration panel. It does simple, whole-page caching, and you have some limited control on when to invalidate the page cache. This might work for a simple site without logged-in users. But the built-in page caching won’t work with dynamic content that changes based on your logged-in status or member attributes.

For more complex caching, Drupal provides a complex, PHP-based caching API. To use this, you write custom PHP functions that call the drupal_static() function.

Here’s a great article explaining the basics of Drupal caching by Jeff Eaton on Lullabot: A Beginner’s Guide to Caching Data in Drupal 7

SilverStripe Caching

SilverStripe caches compiled versions of the site’s templates by default, but nothing else. Unlike Drupal’s PHP based-caching, however, SilverStripe templates provide a flexible, fine-grained, partial-caching API. It enables you to cache/uncache blocks and reuse them however you want. It also allows you detailed control over when to invalidate and re-cache these blocks based on almost anything you can think of. You can learn more about it in their partial caching documentation.

Front-end performance

Although Drupal allows you to create custom themes, it makes it hard to create the themes exactly the way you want to, especially if you want them to work with all the many thousands of modules that expect your site to work a certain way.

In contrast, SilverStripe is agnostic about what you do with your themes. They give you a rich templating system, but make almost no assumptions about how you’ll use it. This allows for fine-grained control over the front-end coding, which in turn allows for much better front-end optimization.

Static Site Publisher

If your site traffic is heavy and dynamically served pages cannot be justified, then both platforms have tools to create a static HTML version of your site.  As a result, overall site performance will vastly improve as there will be minimal or no requests to the PHP engine and database.  The downside is any real time functionality requiring PHP or database access is lost.  However, client side scripting (e.g., AJAX) can be used in place. 

Static publishing is available for both CMSs. For Drupal, please see the Static Generator module. For SilverStripe, please refer to the Static Publisher or Static Publish Queue add-on. 

Third-party Tools

This is where Drupal really shines. When I checked, there were about 17,000 modules and themes for Drupal available on their module page, compared with about 1,000 for SilverStripe at their add-ons site.

So if you’re looking for pre-built functionality, Drupal is great.

SilverStripe’s attitude is that most of the time you need something more custom, and so it’s built to make creating custom functionality as easy as possible.

Having said that, we use SilverStripe add-ons all the time. 

Installing modules and themes

Drupal modules are typically installed by going to the module section on the Drupal site and downloading the code and then manually installing it on your site.

SilverStripe, on the other hand, uses the excellent PHP module dependency manager, Composer. This means that there is a slightly higher learning curve for managing your modules at first, but after that, it’s much simpler to install, and—more importantly—maintain modules.

From Composer’s documentation:

Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you.

Dependency management

Composer is not a package manager. Yes, it deals with “packages” or libraries, but it manages them on a per-project basis, installing them in a directory (e.g. vendor) inside your project. By default it will never install anything globally. Thus, it is a dependency manager.

This idea is not new and Composer is strongly inspired by Node’s npm and Ruby’s Bundler. But there has not been such a tool for PHP.

The problem that Composer solves is this:

a) You have a project that depends on a number of libraries.

b) Some of those libraries depend on other libraries.

c) You declare the things you depend on.

d) Composer finds out which versions of which libraries needs to be installed, and installs them (meaning it downloads them into your project).

We’ve found this ability to track and manage module dependencies with Composer invaluable. And SilverStripe’s entire platform is composer based. In fact, you use Composer to install SilverStripe itself.


Drupal is a great solution for less experienced developers who want to have access to a giant library of pre-made modules and themes, and then customize those to get what they want. Or for more experienced developers who want to build those modules and themes to service the Drupal ecosystem. It’s also a good choice for managers who want to be able to find lots of inexpensive developers and design firms to help them, and are comfortable with the compromises that come from leaning on third-party solutions. 

SilverStripe is a great solution for developers who want to use best practices and modern coding design patterns to build custom websites that also have a great editing environment, quickly and efficiently, without having to deal with a bunch of legacy decisions about how your site should be coded or work. It’s also a good choice for managers who need truly custom designs and functionality and are willing to pay a little more per hour to work with SilverStripe’s smaller, but often more experienced developer community.

In our experience, professional-level clients need the kind of flexibility and customizability that SilverStripe makes so easy. And as developers, we need the kind of control over both the back and front end functionality and coding that SilverStripe makes possible. 


As you’ve probably gathered, we are not a Drupal shop, but we’d like to make this comparison as accurate and balanced as possible. So, if you’re an experienced Drupal 7 developer, and have any suggestions on how we can improve the Drupal portions of this article, please contact us! We’d love to make this article better with your help!

About the Author

  • Phil Quinn

    Phil is the founder of Quinn Interactive. He has over 20 years of design experience and built his first Web site (an on-line, 30+ page weekly newspaper complete with custom CMS) in 1994. He earned his B.A. in Graphic Design from California State University, Chico, where he also taught Web Design, Computer Graphics, and Electronic Printing and Publishing for four years. In addition, he taught a graduate level class, “Principles of Usability” at the Academy of Art in San Francisco. He is an expert in visual design, usability, and computer-based publishing systems.

    More from Phil Quinn