Hi, I have created a ModelAdmin for let’s say a class called Library. Each Library has multiple Book instances. In the CMS I have a button in the left menu called Libraries. When I click on it, I will see a list of libraries, and when I click on a library, I can see a tab called Books which lists all the books. When I click on a book, I can edit/view details of a specific book. Quite a basic scenario.
What would be the most simplest way to generate the same URL to a specific Book page in PHP code? The link creating should be chainable so that it includes the URL for a library in the middle (and also makes it possible to extend the link even more if the books will have new relations in the future, for example pages).
So far I have created a new method called EditLink() for each of my DataObject and pasted the link there manually.
Here is a pseudo code which I haven’t tested but you get the idea what I’m talking about.
<?php
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\ORM\DataObject;
class Library extends DataObject
{
private static $table_name = 'Library';
private static $has_many = [
'Books' => Book::class,
];
public function EditLink($action = 'edit')
{
// This should be improved
$library_admin = new LibraryAdmin;
return $library_admin->Link('Library/EditForm/field/Library/item/' . $this->ID . '/' . $action);
}
}
class Book extends DataObject
{
private static $table_name = 'Book';
private static $has_one = [
'Library' => Library::class,
];
public function EditLink($action = 'edit')
{
// This should be improved
return $this->Library()->EditLink('ItemEditForm/field/Books/item/' . $this->ID . '/' . $action);
}
}
class LibraryAdmin extends ModelAdmin
{
private static $menu_title = 'Libraries';
private static $url_segment = 'libraries';
private static $managed_models = [
Library::class
];
}
Whoops, no it does not require “taitava/swiftmailer-imapsentfolder” :D. I copied composer.json from my another module and forgot to remove that one. I’m actually not surprised if there are some other weird things too - I made it very quickly and haven’t yet even used it anywhere. I’ll improve it in a few days I hope :).
in which class is CMSEditLink() defined? I couldn’t find anything relevant when searching for CMSEditLink methods in PhpStorm.
Or do you mean that I should define this method in my DataObject classes? In that case I don’t think it will solve the problem as I don’t know what to put in that method :).
I generally find you have to do this yourself, an example of getCMSEditLink that I have used is:
public function getCMSEditLink()
{
$admin = Injector::inst()->get(MyModelAdmin::class);
// Classname needs to be passeed as an action to ModelAdmin
$classname = str_replace('\\', '-', $this->ClassName);
return Controller::join_links(
$admin->Link($classname),
"EditForm",
"field",
$classname,
"item",
$this->ID,
"edit"
);
}
I’m starting to think about that this would make a good new module - although a rather small one for just a simple feature. Controller::join_links() is already a step towards a more cleaner solution than what I have been using so far. Now I just need to plan how to implement the “chaining” feature that I mentioned above (= I’ll think about the easiest way to define a kind of notation for "get URL for this Book via its Library"). Maybe I should also take a look at how GridField scaffolds links to editable records.
Thanks @sunnysideup! It took me a while to recall how far I got with this. It seems that I had started my own module, but if I remember correctly, it may have some bugs or other issues. Anyways my module is not very tested, but since it exists, I’ll put a link below just for the record. I’ll have to check your module too the next time I’m going to need this kind of functionality. I guess your module is more mature than mine :D.