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.

Archive /

Our old forums are still available as a read-only archive.

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

Issue with multiple has_one of same class on page


Go to End


5 Posts   11467 Views

Avatar
asinesio

6 Posts

25 April 2008 at 4:42pm

Edited: 25/04/2008 4:43pm

So, I'm creating a site using SilverStripe, and I'm having some struggles trying to figure out the best way to accomplish a goal.

The site I'm creating has a HomePage where there are three "content boxes" that have a header, an image, and some links below them.

I am trying to allow my clients to manage the data that appears in each box.

I have a ContentBox DataObject class that has a few data members. I also have a HomePage class that has three instances of ContentBox, e.g.:

class HomePage extends Page {

static $has_one = array(
'LeftContentBox' => 'ContentBox',
'RightContentBox' => 'ContentBox',
'BottomContentBox' => 'ContentBox'
);

function getCMSFields() {
$fields = parent::getCMSFields();

// content boxes
$fields->addFieldsToTab('Root.Content.LeftContentBox', LeftContentBox::getCMSFieldsToInclude());
$fields->addFieldsToTab('Root.Content.RightContentBox', RightContentBox::getCMSFieldsToInclude());
$fields->addFieldsToTab('Root.Content.BottomContentBox', BottomContentBox::getCMSFieldsToInclude());
return $fields;
}
}

ContentBox has its own array() of fields:

class ContentBox extends DataObject {
...
function getCMSFieldsToInclude() {

$fields = array(
new TextField('HeaderText', 'Header Text'),
new TextField('HeaderLink', 'Header Link URL'),
new ImageField('Image')
);
return $fields;
}
}

When I try and edit a HomePage in the CMS, I get the following error:

FATAL ERROR: collateDataFields() I noticed that a field called 'HeaderText' appears twice in your form: 'Form_EditForm'. One is a 'TextField' and the other is a 'TextField'
At line 110 in /Applications/MAMP/htdocs/sapphire/forms/CompositeField.php

------

So, does anyone have any suggestions as to how I should design this? Do I need to make three separate subclasses of ContentBox (left, bottom, right) that implement different named fields?

Thanks in advance for any help you can provide.

-Andy

Avatar
Blackdog

Community Member, 156 Posts

25 April 2008 at 6:39pm

I can't see why you are using DataObject.

Please explain what type of content you propose for each of those 3 "content boxes".

Avatar
Willr

Forum Moderator, 5523 Posts

25 April 2008 at 7:31pm

If a page has 3 content boxes I usually just 'hardcode' all the fields on HomePage. Seems easier. Sure you do repeat yourself 3 times and it looks nasty but it works :P

Avatar
asinesio

6 Posts

26 April 2008 at 2:27am

Blackdog, the reason I'm using it is because many different pages of my site have the same content box.

A content box will have something like this:

---------------
|"Header Text"|
---------------
| Image |
---------------
| > Link 1 |
| > Link 2 |
| > Link 3 |
---------------

So, the reason I'm using DataObject is because I wanted to allow the user to manage the 1...N links in each content box.

I suppose the easier way is just to give them another HTML field where they can enter an unordered list.

willr, thanks for the advice. I'll take it to heart. I was just trying to DRY my code. :)

If anyone else has any suggestions, I'm all ears.

-Andy

Avatar
Blackdog

Community Member, 156 Posts

26 April 2008 at 10:56am

Edited: 26/04/2008 10:59am

ok, serious. don't use Dataobjects for that, you will over complicate the situation.

If the content boxes will just be replicated on another page, use the following.

For example if you set the root of the content to be entered on the home page.

<% control Page(home) %>
$Title
$Content
$Some-other-field
<% end_control %>

That will pull the data from the home page to any other template you put that within. You can use it multiple times for your different content boxes.

<% control Page(home) %>
$Header
<% end_control %>

<% control Page(home) %>
$Image
<% end_control %>

<% control Page(home) %>
$Links
<% end_control %>