silverstripe / silverstripe-admin

Silverstripe Admin Component
BSD 3-Clause "New" or "Revised" License
25 stars 91 forks source link

LeftAndMain extension's templates only render properly in includes folder #529

Open mlewis-everley opened 6 years ago

mlewis-everley commented 6 years ago

I am opening this after a conversation over in slack (https://silverstripe-users.slack.com/archives/C36U3BDHN/p1526820688000056).

When I create a custom admin interface (extending LeftAndMain, the GridFields inside the admin interface work as expected, and if I click one of the records I get taken to the GridFieldDetailForm (as expected). If i then refresh the page, the view is lost, I just get a white screen with an empty fieldset.

This can be resolved by moving the two templates into an Includes folder) app/templates/App/Admin/Includes.

Basically (to replicate) I did the following:

  1. Create a new admin view (that extends LeftAndMain):
<?php

namespace App\Admin;

use App\Model\Events\Event;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FieldList;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\View\Requirements;
use SilverStripe\Forms\ReadonlyField;
use SilverStripe\Security\Permission;
use App\Forms\GridField\GridFieldWeekView;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\ToggleCompositeField;
use App\Forms\GridField\EventDetailForm_ItemRequest;
use SilverStripe\Forms\GridField\GridFieldButtonRow;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClass;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordViewer;

/**
 * Custom admin view to display the schedual of all designated fiters
 * 
 */
class ScheduleAdmin extends LeftAndMain
{
    private static $url_segment = 'schedule';
    private static $url_rule = '/$Action';
    private static $menu_title = 'Schedule';
    private static $menu_icon_class = 'font-icon-back-in-time';
    private static $menu_priority = 11;
    private static $url_handlers = array(
        '$Action' => 'handleAction'
    );

    public function getEditForm($id = null, $fields = null)
    {
        $fields = FieldList::create();
        $members = Permission::get_members_by_permission("EVENTS_HAS_CALENDAR");
        $new_data = [];

        foreach ($members as $member) {
            $field_name = "Fitter" . $member->ID . "_GridField";

            $fields->push(
                ToggleCompositeField::create(
                    "Fitter" . $member->ID,
                    $member->Name,
                    [
                        $field = GridField::create(
                            $field_name,
                            "",
                            $member->Events(),
                            GridFieldConfig_RecordEditor::create()
                        )
                    ]
                )
            );

            $new_data[$field_name] = [
                "url" => "",
                "field" => $field->ID(),
                "fitter" => $member->ID
            ];
        }

        $form = Form::create(
            $this,
            'EditForm',
            $fields,
            FieldList::create()
        )->setHTMLID('Form_EditForm');

        $form
            ->addExtraClass('cms-edit-form cms-panel-padded')
            ->addExtraClass('center flexbox-area-grow');

        $form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
        $form->setAttribute('data-pjax-fragment', 'CurrentForm');

        // Finally loop through setup fields and get their links
        foreach ($new_data as $field_name => $data) {
            $field = $fields->dataFieldByName($field_name);

            $new_data[$field_name]["url"] = $field->Link("item/new");
        }

        $new_data = json_encode($new_data);

        Requirements::customScript(
            <<<JS
            var gridfield_calendar_new = $new_data
JS
        );

        return $form;
    }
}
  1. Added template app/templates/App/Admin/ScheduleAdmin_Content.ss:
<div class="cms-content fill-height flexbox-area-grow cms-tabset center $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content">
    <div class="cms-content-header north">
        <div class="cms-content-header-info vertical-align-items flexbox-area-grow">
            <div class="breadcrumbs-wrapper">
                <span class="cms-panel-link crumb last">
                    <% if $SectionTitle %>
                        $SectionTitle
                    <% else %>
                        <%t SilverStripe\Admin\ModelAdmin.Title 'Data Models' %>
                    <% end_if %>
                </span>
            </div>
        </div>
    </div>

    <div class="cms-content-fields center ui-widget-content cms-panel-padded fill-height flexbox-area-grow" data-layout-type="border">
        <div class="cms-content-view">
            $EditForm
        </div>
    </div>
</div>
  1. Added template app/templates/App/Admin/ScheduleAdmin_EditForm.ss:

<% include SilverStripe/Forms/Form %>

I spent about 3 hours trying to trace why the templates need to be in Includes and didn't really get anywhere. For some reason, when the page is refreshed, if the templates are in not in Includes SS just doesn't see them...

@sminnee believed this might be a bug, the templates should not need to go in an Includes folder.

maxime-rainville commented 6 years ago

I've confirmed the behavior as explained.

I'm not sure if this is a bug or the expected behavior. Looking asset-admin and campaign-admin both of them put their templates in an Includes folder.

What's really confusing from the developer's point of view is the Controller will work correctly if you navigate to it, but not if you refresh the page.

mlewis-everley commented 6 years ago

Thanks for looking at this @maxime-rainville , From my discussions with @sminnee on slack, he was under the impression that the templates are currently in Includes for backwards compatibility, but they should also work the same way in other folders. Maybe he can pop up here to clarify?