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

Decorating objects give unexpected results


Go to End


2 Posts   2608 Views

Avatar
MarcusDalgren

Community Member, 288 Posts

18 July 2009 at 10:13am

Hello.

When building a site for a client I have found myself writing a couple of utility functions that extend the somewhat meagre syntax available in Silverstripes template language.

Generally these functions end up inte Page class since different sub classes use them but I'm feeling that I'm cluttering up my page object because of this.

After reading about object decorators this sounded like just the thing. Instead of bloating my page class I could decorate the relevant classes (SiteTree and DataObject) with my utility methods. This would clean up the Page class and make it easier for me when adding/modifying utility functions since I won't have to dig through the page class file.

However my attempts att DataObject decoration has so far failed. I tried decorating the DataObject with my Nth-function (code below)

public function Nth($val) {
	return ($this->owner->iteratorPos + 1) % $val == 0; 
}

a really useful function that lets you modify output at regular intervals. However this code does not behave the way it does when it's in the page class even though it should (if I understand the documentation correctly). IteratorPos is a part of DataObject and I'm decorating DataObject but when my classes (that extend DataObject) try to use it it doesn't work.

I got the same results when I tried decorating SiteTree with utility functions. Actually, scratch that. Decorating SiteTree with

public function CurrentOrSection() {
	return ($this->owner->isCurrent() || $this->owner->isSection()) ? true : false;
}

actually works which makes this even weirder.

Is it because I'm trying to access the iterator that I'm getting these odd results?

Kindly,
Marcus

Avatar
MarcusDalgren

Community Member, 288 Posts

18 July 2009 at 10:33am

UPDATE

Ok so I found out what went wrong.

When checking the ViewData class I noticed that the properties I was trying to access are protected.
However ViewData also has public functions to access the iterator properties and when I used these instead it worked!

So the code in the previous post should be

public function Nth($val) {
	return ($this->owner->Pos()) % $val == 0; 
}

and it works like a charm. YAY!

So are methods added through decoration treated as external methods trying to access the object even though they are "added" to the class/object in question? If I had put my methods in the DataObject class directly I would have had access to the iteratorPos property but the decorator apparently doesn't.

Kind of makes sense but it would have been great if the DataObjectDecorator page said something about that you can only access public properties/methods on the class you are decorating.

Kindly,
Marcus