For those who don't know, DataObject->forTemplate() allows you to
define a template file to serve as the rendering template for said
DataObject. A template like this is usually comparable to a template
file you'd find in the templates/Includes folder, a small snippet of
HTML with variables relating to a DataObject's $db properties. It
allows you to just output the DataObject with the defined template as
a template variable.
So, on to the solution. I learned about the ability to do this in the
SilverStripe tutorials when I first started playing with SS. It's
explained in Step 5 of the tutorials. Typically, you have a Page
(let's say MyPage) with has_one to a DataObject (let's say
HasOneObject).
======================================
class MyPage extends Page {
static $has_one = array('SingleObject' => 'HasOneObject');
// ...
}
======================================
Then, if I define
======================================
class HasOneObject extends DataObject {
function forTemplate() { return $this->renderWith('HasOneObject'); }
}
======================================
this is saying to render the HasOneObject in templates with the
HasOneObject.ss file, probably located in the templates/Includes
folder. So in my MyPage.ss template, if I use the template variable
$SingleObject, it will render the whole HasOneObject as defined in the
HasOneObject.ss file.
So that's old news. The problem that sent me looking for answers was
how to leverage the DataObject->forTemplate() method in a control loop
that looped over a has_many relation. If I had
======================================
class MyPage extends Page {
//...
static $has_many = array('ManyObjects' => 'HasManyObject');
// ...
}
======================================
and
======================================
class HasManyObject extends DataObject {
function forTemplate() { return $this->renderWith('HasManyObject'); }
}
======================================
and in my MyPage.ss file I had
======================================
<% control ManyObjects %>
$ManyObjects
<% end_control %>
======================================
It didn't output anything. I eventually realized that ManyObjects
referred to a DataObjectSet and I had to somehow refer directly to the
DataObject as a template variable in order to leverage the
forTemplate() method. At first, I made a custom method on the
HasManyObject that just returned $this.
======================================
class HasManyObject extends DataObject {
//...
function Object() { return $this; }
}
======================================
I changed my template code to look like this
======================================
<% control ManyObjects %>
$Object
<% end_control %>
======================================
and it worked. But I wasn't satisfied. There had to be a native method
on DataObject that could be used as a template variable that just
returned the DataObject, e.g. just did "return $this;". I found the
DataObject->data() method with returned $this, but it was not a method
you use in the templates since it wasn't Capital Camel Case as is the
standard. I couldn't find another one. Then it hit me to traverse up
the class tree and see if maybe one of the parent classes had my
answer. I didn't have to look far, the answer was in ViewableData, the
direct parent class of DataObject. ViewableData has a Me() method that
returns $this. So, I tried using it.
======================================
<% control ManyObjects %>
$Me
<% end_control %>
======================================
Success!
Now traditionally, you see something more along the lines of the
following being used to accomplish the same goal
======================================
<% control ManyObjects %>
<% include HasManyObject %>
<% end_control %>
======================================
and it works great. My situation was that I had one DataObject tied to
2 different page types: one was by has_many and the other was a
has_one. So I wrote the forTemplate() method for my DataObject and
wanted to use the variable outputting method rather than including the
template on both page types.
Sorry for the long-windedness, but, as many of my friends will
confirm, I like telling stories. I hope this helps people.
--
You received this message because you are subscribed to the Google Groups "SilverStripe Development" group.
To post to this group, send email to silverst...@googlegroups.com.
To unsubscribe from this group, send email to silverstripe-d...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/silverstripe-dev?hl=en.
class MyPage {
function SmallView() {
return $this->renderWith('HasManyObject_small');
}
function LargeView() {
return $this->renderWith('HasManyObject_large');
}
}
<h2>Small views</h2>
<% control ManyObjects %>
$SmallView
<% end_control %>
...
<h2>Large views</h2>
<% control ManyObjects %>
$LargeView
<% end_control %>