« QuadraCentifiable 30 Days of Me »

CMS-less SilverStripe install

Posted by Simon Welsh | 6 September 2010 | Comments (2)

This pops up every so often on #silverstripe. Is it possible to use sapphire without the CMS?

(For those that don't know, sapphire is the PHP5 framework that SilverStripe runs on. You can get it on its lonesome from svn at http://svn.silverstripe.com/open/modules/sapphire/. At the time of writing, branches/2.4 is the "stable" branch. trunk may be rather borked at the moment)

While the answer is rather simple, yes, actually explaining how to do it is a bit more complicated. Luckily, I've recently done this, to an extent. While I can't share the specifics about it (with regards to the site, yay for NDAs!), I can explain how to do it now, with sample code.

For this particular site, I still had the CMS module installed, as I wanted to use the Security part of it. As such, I don't know if this will still work if you just don't have the cms folder at all, but I see no reason why it shouldn't, though a little bit of effort may be needed just to make sapphire happy. (ErrorPage, mainly, I think. Possibly also PageComment, as SiteTree wants that, though that's just an unset(SiteTree::$has_many['Comments']) in your _config.php).

The first thing I did was to remove the tabs to the parts of the CMS I didn't want to be able to access without knowing what I was doing, then set /admin to point to /admin/security. This can all be done with a couple of lines in your _config.php (usually in mysite/)

Firstly, to remove the tabs from the CMS. I removed the Pages, Comments and Reports tabs, leaving Files & Images and Security. This was done by telling CMSMenu to remove the menu items:

CMSMenu::remove_menu_item('CMSMain');
CMSMenu::remove_menu_item('CommentAdmin');
CMSMenu::remove_menu_item('ReportAdmin');

Here, the argument being passed to CMSMenu::remove_menu_item(); is the name of the LeftAndMain subclass. You can see potentially values by looking in your cms/code/ folder.

Then to point /admin to /admin/security, I used a redirect in Director. I tried setting SecurityAdmin to handle /admin itself, but that looked like it would involve a bit to much work for me, so I settled for the redirect:

Director::addRules(45, array('admin'=>'->admin/security'));

Those of you that haven't used Director rules before will probably be rather confused by this line. Basically the Director is the first step in handling a request to SilverStripe. It looks through its rules, sorted by priority, and reacts to the first one it finds that matches the request.

The first parameter to Director::addRules() is the priority all the rules should have, with higher numbers having higher priorities. As CMSMain (the class that normally handles /admin) has uses a priority of 40, we need to use something larger than that. Hence the 45.

The second parameter is an array of rules to add. This is an associative array with the pattern to match being the key and what to pass it off to being the value. If the value is prefix with '->', it acts as a redirect. Thus what the above call does is add a single rule with priority 45 that redirect admin to admin/security.

This set the CMS up as I wanted. I then started on the frontend. This is actually rather simple to do. I made Controller subclasses (note, not ContentController nor Page_Controller, but Controller) and templates with ClassName.ss. $Layout works as expected, as do most of the normal things you can do in templates.

Finally, you just need to decide how you want your content to be accessed. You can either use class names or Director rules.

If you use class names, the URL will look like http://your-site.com/ClassName. The Link function you'll need to add to your class will be:

public function Link($action = null) {
	return __CLASS__ . ($action ? '/' . $action : '');
}

Here I'm using the magic constant __CLASS__, so you can copy and paste it straight into each class.

The second option allows you to customise your URLs. You use a similar format to our previous Director::addRules() call, except this time we don't want a redirect. I'll just use an example to explain how to do it.

Director::addRules(75, array(
	'User' => 'UserController',
	'News' => 'NewsController',
));

Here, we're adding two rules with a priority of 75. We use 75 so it has a higher than anything in sapphire. This will let our UserController be accessed by http://your-site.com/User, and likewise for the NewsController. As you can see, we can pass multiple rules in at once by adding them to the array.

The Link function in your class will be pretty much the same, but __CLASS__ will be replaced with the URL that accesses it. For example, the Link function in the NewsController class will look like:

public function Link($action = null) {
	return 'News' . ($action ? '/' . $action : '');
}

This allows you to have a fully functional site using sapphire, but without using the CMS for content.

If I have the time this weekend, I'll figure out how to do it without the cms module at all.


Share on FaceBook

Trackbacks

None
Trackback URL: http://simon.geek.nz/Trackbacks/add/1260

Post your comment

Sign in with Twitter

Comments

  • Basically, we only had a member-only side with no "static" pages. I didn't notice any performance difference, but then the CMS module was still there and there's virtually no load on the VPS (it's not live yet).

    It'll be interesting to compare though. If I've got the time in the next couple of months, I'll give it a shot.

    Posted by Simon Welsh, 07/09/2010 12:22am (1 year ago)

  • Hi Simon, good explanation. Are you allowed to tell something about the use case scenario, that made you want to remove the CMS part of SS?
    Could decoupling the CMS from Sapphire have any performance improvements?

    Cheers,
    Martijn

    Posted by Martijn, 07/09/2010 12:14am (1 year ago)

RSS feed for comments on this page | RSS feed for all comments