Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elemental Area can't easily be added to a non-Page DataObject and edited in a ModelAdmin #871

Closed
3 tasks done
maxime-rainville opened this issue Feb 1, 2021 · 6 comments

Comments

@maxime-rainville
Copy link
Contributor

maxime-rainville commented Feb 1, 2021

BaseElement::CMSEditLink assumes that blocks are attached to an Object with a CMSEditLink wethod. So when an ElementalArea is added to a DataObject edited via a ModelAdmin, you'll get this error Object->__call(): the method 'CMSEditLink' does not exist on 'SilverStripe\\FrameworkTest\\Model\\Company'

Acceptance Criteria

  • Elemental Area can be added to DataObjects that are not sub classes of SiteTree
  • Proper guidance is given to developers on how to add an Elemental Area to a plain DataObject
  • Either developers have to define their own CMSEditLink method or we come with a way to "guess" the edit link

Stretch goal

  • Create a generic reusable API to define what ModelAdmin should be use to edit a DataObject and create the CMSEditLink from that.

Notes

There was some recent work to allow previews to be added to ModelAdmin. Ideally, tho solution to this card should work with tho preview as well.

PRs

@maxime-rainville
Copy link
Contributor Author

Off the top of my head, I'm thinking we could

  • update BaseElement::CMSEditLink to return null when the ElementalArea is attached to an object without a CMSEditLink` method.
  • Implement a way for a DataObject to explicitly say, "go through this ModelAdmin to edit me"

@maxime-rainville maxime-rainville changed the title "method 'CMSEditLink' does not exist" when tryng to edit block though ModenAdmin "method 'CMSEditLink' does not exist" when trying to edit block though ModenAdmin Feb 1, 2021
@brynwhyman
Copy link

Related/ duplicate: #718

@maxime-rainville maxime-rainville changed the title "method 'CMSEditLink' does not exist" when trying to edit block though ModenAdmin "method 'CMSEditLink' does not exist" when trying to edit block though ModelAdmin Mar 2, 2021
@maxime-rainville maxime-rainville changed the title "method 'CMSEditLink' does not exist" when trying to edit block though ModelAdmin Elemental Area can be added to a non-Page DataObject and edited in a ModelAdmin Mar 21, 2022
@GuySartorelli
Copy link
Member

Possibly related: #965

@sabina-talipova sabina-talipova self-assigned this Apr 4, 2022
@sabina-talipova
Copy link
Contributor

sabina-talipova commented Apr 19, 2022

I suggest to add a few changes in the CMSEditLink() method in class BaseElement.

        if (!$page instanceof SiteTree) { 
            if (method_exists($page, 'CMSEditLink')) {
                $link = Controller::join_links($page->CMSEditLink(), 'ItemEditForm');
            } else {
                $link = null;
                $this->extend('updateCMSEditLink', $link);
                return $link;
            }
        } else {
            $link = $page->CMSEditLink();
        }
  1. Move checking existing CMSEditLink method in separate "IF condition".
  2. If method doesn't exist return null. Effect of this approach "Page not found", since CMS user didn't override method. Since if we check method if (!$page instanceof SiteTree && method_exists($page, 'CMSEditLink')) and evoke method in "ELSE condition", it trows the error that is not displayed on screen (available only in browser console), so CMS user cannot understands what happens.
  3. Other solution, we don't change this block and leave as it is. But CMS user has to define CMSEditLink in his Model class or implement CMSPreviewable interface and must have CMSEditLink in this case.

Other block of code, that I suggest to improve:

        if (!$this->inlineEditable() || $directLink) {
            if (!$page instanceof SiteTree) {
                $link = Controller::join_links($link,
                    'field',
                    $relationName,
                    'item',
                    $this->ID,
                    'edit'
                );
            } else {
                $link = Controller::join_links(
                    singleton(CMSPageEditController::class)->Link('EditForm'),
                    $page->ID,
                    'field/' . $relationName . '/item/',
                    $this->ID,
                    'edit'
                );
            }
        }     
  1. Add checking that $page is not a Page instance. That will allow to define the special link for Element in ElementalArea in DataObject and load Element edit page. I've done tests. This works with ElementalContent, Elemental UserForm and Custom elements.

@sabina-talipova
Copy link
Contributor

sabina-talipova commented Apr 19, 2022

I'm going to provide an instruction how to use Elemental Area in DataObject and how to display these Elements on a Page in section "Model and DataBases. How To's " in Developer Guides

@maxime-rainville
Copy link
Contributor Author

Looks good ... I think those suggested improvement are a nice touch. When checking if a object has a method, use ClassInfo::hasMethod instead of the native method_exists PHP method. ClassInfo::hasMethod will account for things like extensions and so on.

@GuySartorelli GuySartorelli changed the title Elemental Area can be added to a non-Page DataObject and edited in a ModelAdmin Elemental Area can't easily be added to a non-Page DataObject and edited in a ModelAdmin May 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment