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

Retrieving Data based on URL fragment.

Go to End

9 Posts   2288 Views


8 November 2009 at 7:12am (Last edited: 8 November 2009 7:16am), Community Member, 14 Posts

Okay the title might be a little confusing, but here is my actual problem. I was able to add a new Data Object to my CMS and can add entries using CMS backend. Now I would like to access a specific entry using something like '', while sermons is the page type and I would like to display entry in the database using the date as the filter.
how can I access that date fragment in the URL to then us it in the call to the database. I was looking at but was not able to figure out how to customize it for my needs. Is it even possible the way I would like to do it? or is there maybe a better way of doing it.

Thanks for your help!


8 November 2009 at 10:34am (Last edited: 8 November 2009 10:35am), Community Member, 901 Posts

Hi. Should be easy to do, but it will be easier if you specify an action to be called on the Controller.
Eg, your URL should be:
So for your case it could be:

Then you would create a method date on your Sermon_Controller. This will be called, whenever sermons/date is being opened in the browser. There you can get the date parameter via Director::urlParam('ID').

Here's an example code:

public function date(){
   $date = Director::urlParam('ID');
   // check if it's a correctly formatted date, otherwise just render the page
   // with the default template.
   if(!preg_match('/\d{2}-\d{2}-\d{4}/', $date)){
      return $this->renderWith(array($this->ClassName, 'Page'));
   // get the dataobject that matches $date
   $dataObject = DataObject::get_one('DataObjectClass', "DATE_FORMAT(DateField, '%d-%m-%Y') = '$date'");
      // if no dataobject, render with default template.
      return $this->renderWith(array($this->ClassName, 'Page'));
   // render the dataObject with a custom template (
   // can be Layout too!
   return $dataObject->renderWith(array('DataObjectTemplate', 'Page'));

Hope that helps. If you don't want to render the DataObject with its own template, you can just store the DataObject as a private member of the Controller class and provide an accessor Method to get it in your template.


8 November 2009 at 10:35am (Last edited: 8 November 2009 10:36am), Community Member, 901 Posts

Ouch. Accidentally double posted.


8 November 2009 at 3:53pm Community Member, 14 Posts

Thanks for pointing me in the right direction. Your method worked, but the problem I was running into was that my Menus and some other content disappeared. I looked around and found this thread
I was not able to figure out how their solution was supposed to work :-)

I was able to circumvent this problem by doing the following. The URL structure I left the same /sermons/date/2009-10-15 but instead of creating a date() method, I created a method called GetSermon()
(I did have to change the preg_match and DATE_FORMAT because in the URL the raw SQL date is used and I could not figure out how to change it to m-d-Y, in my custom link structure: $this->SermonHolder()->Link() . 'date/'. $this->sermonDate)

function GetSermon() {
$date = Director::urlParam('ID');

if(!preg_match('/\d{4}-\d{2}-\d{2}/', $date)){
// if date is not properly formatted, return latest entry
return DataObject::get("Sermon", "", "sermonDate DESC", "", "1");

$dataObject = DataObject::get_one('Sermon', "DATE_FORMAT(sermonDate, '%Y-%m-%d') = '$date'");
// if no dataobject, return latest entry
return DataObject::get("Sermon", "", "sermonDate DESC", "", "1");

return $dataObject;

and the method is called in the template:

<% control GetSermon %>
... data output goes here ...
<% end_control %>

It works, but I'm not sure if there could be any draw backs for doing it this way.

Thanks again Banal for your help!!


8 November 2009 at 9:48pm Community Member, 901 Posts


No, your method works just as well. There are always different ways to approach a problem like this.
Instead of using DataObject::get with a limit clause, you could also use DataObject::get_one which does basically the same but is better readable in my opinion.

The problem you got with your Menus and content is probably because you didn't pass the right templates to the renderWith method. Or it could be caused because you access stuff in the template that isn't accessible via the DataObject.

As long as you don't need two different appearances/templates (for sermon/ and sermon/date/xxxx-xx-xx), your approach works fine. I suggest you leave it the way it is. You could improve the URL in two ways though:
1) You can now skip the '/date' string in your url. Create URLs like this: and use $date = Director::urlParam('Action'); instead.
2) Use the Format method of the Date object to format the date as you desire (dd-mm-yyyy). Eg.
$this->SermonHolder()->Link() . $this->sermonDate->Format('d-m-Y')


9 November 2009 at 2:14am (Last edited: 9 November 2009 2:16am), Community Member, 14 Posts

Ah okay.. I was under the impression that the urlParam['action'] needed to be a method, so I didn't even try to just using it for my date.
And formatting the date to was my limited OOP understanding. I tried sermonDate.Format() instead of sermonDate->Format()
I definitely will make the changes to have a shorter URL because that's what I initially intended to do.

P.S: Ich hatte noch festgestellt das du in der Schweiz wohnst! Cool.. ich bin in der naehe von Schaffhausen aufgewachsen und meine Eltern und Geschwister wohnen alle noch in CH.


9 November 2009 at 8:37am Community Member, 901 Posts

The action usually maps to a method on the controller, but if the method isn't available, the Action parameter will still be available for you to use. In PHP you'll always have to use the -> syntax when dealing with Objects and Members/Methods. The dot-syntax is used in the .ss template, which can cause confusion sometimes.

Re P.S: Ja, ich wohne tatsächlich in der Schweiz (Biel). Die Welt ist klein, nicht wahr ;)


9 November 2009 at 10:52am Community Member, 244 Posts

Just to let you know that as of 2.4 you will need to explicitly define an action for it to be available - otherwise it will throw a 404 error (so the GetSemon method won't work). Also, Director::urlParam() is deprecated and you should use $this->request->param().

Go to Top