To keep the CMS users happy in their day-to-day work, it’s important to have the CMS configured in a way that gives a good user experience. One of the more complicated relations to add, is a one to many relation, for example on a page. This is pretty straight forward with the default dropdown, but is not always the best solution.
Consider you have a one to one relation with
belongs_to back. This means you need a ModelAdmin for handling all the DataObjects that are only used once on the other side of the relation.
Although it works, it’s slightly inconvenient for the CMS users as they have to go through multiple steps to get a single relation set up.
We’ll stick with a
Page::has_one ⇔ DataObject::belongs_to relation for the rest of this article.
For example, a CMS user has to go through the following steps:
- go to the ModelAdmin
- create the one object
- go to pages
- find the right page
- link the new object
That’s a lot of steps for one object.
One could argue it’s more convenient to just put everything on the page, but in a lot of cases that’s not a proper Object Oriented approach. This causes code mess and possible technical debt in the future.
For any developer, the words “Technical debt” make their hair raise (think bloodshot eyes of pure anger).
Still use the proper Object Oriented approach, but with HasOneField to reduce the hassle of linking everything together. This module creates a button on the Page that will easily let a CMS editor add the related object on the page itself. No more clicking around in the CMS until everything is prepared, just do it on the fly.
Sure, an optional ModelAdmin is still useful for cleaning up no-longer used objects, but there’s no need to go through all the steps anymore.
As per usual, installation is as easy as
composer require silvershop/silverstripe-hasonefield
The field itself is secretly a GridField, but only allows for one record to be in the gridfield, by changing the Add button to an Edit button once a record is added. Pretty clever!
So, let’s start with a Page type that has a Call to Action. A Call to Action is often just used on a single page and not re-used. I’m talking about landing pages kind of Call to Actions, not a generic multi-used one here.
A single button, to handle the single relation directly from the about-us page. A simple click of a button gives us
Now, we can add a single relationship easily, without having to go through the hoops of going through a ModelAdmin.
After hitting Create, the relation is saved back into it’s parent Page, which then looks like this
Yes! The relation is properly saved, and my Call to Action is there. Assuming you followed the instructions on GitHub, on how to create the button with the read-only field, you should be able to easily replicate this behaviour.
As you can see, the Add button is now an Edit button, which edits the existing Call to Action and not a new, empty one.
GridFieldAddExisting that respects the
has_many relations, with adding an option by default to hook in an existing one (instead of the default dropdown) if it is a one to many relation. It should be possible to do so already with adding a
GridFieldAddExisting button, but it should respect the
has_one relation back, which
AddExisting doesn’t do yet it seems.
If you have a
has_one relation that you’d like to edit from the parent, this module is quite handy!
As per usual, give it a try, contribute and enjoy!
If you want to stay updated about changes in the SilverStripe community, sign up to our SilverStripe community slack channel