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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

[SOLVED] URL slug instead of ID on DataObject?


Go to End


11 Posts   11792 Views

Avatar
LesC

Community Member, 70 Posts

23 August 2009 at 12:16am

Edited: 10/12/2009 9:50pm

Hi,

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 {
            Director::redirect('not-found');
        }
    }

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!

Les

Avatar
dhensby

Community Member, 253 Posts

23 August 2009 at 1:43am

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.

Avatar
LesC

Community Member, 70 Posts

27 August 2009 at 3:33am

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?

Avatar
dhensby

Community Member, 253 Posts

27 August 2009 at 8:42am

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

something like:

function onBeforeWrite() { 
      ...
      parent::onBeforeWrite(); 
   }

See an example of use: http://www.silverstripe.org/archive/show/7431?start=0#post7656

Hope that is of some use.

Avatar
LesC

Community Member, 70 Posts

28 August 2009 at 3:29am

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

Avatar
Martijn

Community Member, 271 Posts

29 August 2009 at 12:04am

Why not use this:

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

Avatar
LesC

Community Member, 70 Posts

29 August 2009 at 12:08am

Now that looks interesting!

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

Avatar
potion_maker

Community Member, 36 Posts

10 December 2009 at 9:50am

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