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 has_one
and 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).
The solution
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.
Installation
As per usual, installation is as easy as
composer require silvershop/silverstripe-hasonefield
Inner workings
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!
Usage
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.
Future improvements
Have a 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.
Conclusion
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
Post your comment
Comments
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments