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.

Data Model Questions

[SOLVED] URL slug instead of ID on DataObject?

Go to End

10 Posts   4257 Views


23 August 2009 at 12:16am (Last edited: 10 December 2009 9:50pm), Community Member, 70 Posts


I've created a news section for my site that uses the awesome DataObjectManager, and with some help from UncleCheese I've got it working with categories, with the end goal of having a much easier to use news archive in the CMS (there's likely to be more than a few hundred news articles in the next year or so, and the sitetree system can't handle it).

I've got each NewsArticle displaying on its own 'page', by using a function on the NewsHolder (which sits at /news in the site):

function display() {
$params = Director::urlParams();
$id = (int)$params['ID'];
$object = DataObject::get_by_id("NewsArticle", $id);
if($object) {
return $this
->customise(array('NewsArticle' => $object))
->renderWith(array('NewsArticle', 'Page'));
} else {

So when I go to /news/display/1 it shows me the first NewsArticle in a nice template.

My question is this - and I know it's kind of an overlap with how Objects and Pages work, but anyway - is there a way to generate a friendly URL instead of displaying by ID? I'd like to get something like /news/display/news-title-here working, but can't work out the best way to do it.

* Should I create a url-slug field in the NewsArticleObject, and set that on creation somehow, then call that from the Display function, or,

* Is there a function for returning a friendly url based on a field on the Object (e.g. Title)?

Any help on this is much appreciated!



23 August 2009 at 1:43am Community Member, 243 Posts

Hi LesC,

Surely getting the dataobject by title and passing that in the URL is how you would not use the ID?

So don't use get_by_id, use get_one() and have field that can be 'url' and then search for the data object with the URL. Simple.

something like:

$record = DataObject::get_one('NewsArticle', "`URL` = '".$id."'");

I think that should work :P

Worth a shot i think.


27 August 2009 at 3:33am Community Member, 70 Posts

Cheers Pigeon,

Yup I'm going to try what you put, but do you know if SS has the functionality to create the URL slug and save it automatically? I'm guessing that the way it's handled when you create a page in the CMS that javascript is what generates the url title but can't seem to confirm that.

Or, in Rails models you can run a function 'before save' so that you can do stuff before data inputs are saved - do the models in SS cope with 'do this before saving'?

I've found a nifty function for converting the title into a URL slug:

function slug($str)
   $str = strtolower(trim($str));
   $str = preg_replace('/[^a-z0-9-]/', '-', $str);
   $str = preg_replace('/-+/', "-", $str);
   return $str;

So hopefully there's a way for me to use this if SS doesn't have in built functionality.

Anyone have any ideas?


27 August 2009 at 8:42am Community Member, 243 Posts

There is a 'onBeforeWrite' method that you can use in the page class.

something like:

function onBeforeWrite() {

See an example of use:

Hope that is of some use.


28 August 2009 at 3:29am Community Member, 70 Posts

Thanks for that Pigeon, I'll take a look and post my findings when I can :)


29 August 2009 at 12:04am Community Member, 271 Posts

Why not use this:

   function onBeforeWrite () {
      parent::onBeforeWrite ();
         $this->URLSegment = SiteTree::generateURLSegment($this->Title);


29 August 2009 at 12:08am Community Member, 70 Posts

Now that looks interesting!

I'm hoping to spend sometime on this next week - so thank you for your suggestion Martijn!


10 December 2009 at 9:50am Community Member, 36 Posts

Hey Les,
Did you ever figure out a good way to do this? If so could you explain? Right now my URL looks like site/Employee/FirstName/LastName. It would be nice if it said site/Employee/FirstName LastName

Go to Top