3
votes

I've recently learned to create custom CMS sections in the back-end using class ModelAdmin and linking them using private static $managed_models = array('Contact'); to a DataObject named Contact.

My goal is to create a new section named "Contact" which holds a few contact details (phone, email etc). These are singular fields, not multiple records.

Unfortunately this setup (linking to dataobject) creates a sort of GridField in the back-end that creates multiple "Contact" records with the fields Phone, Email etc.

How can I create a custom CMS section that holds a singular entity of given Fields?

2
you can prevent creation of further DO with permissions like canCreate docs.silverstripe.org/en/3.3/developer_guides/… ...but probable you also could just add it to a Tab in SiteConfig docs.silverstripe.org/en/3.3/developer_guides/configuration/… - munomono

2 Answers

4
votes

This is not what ModelAdmins are for. They are meant to manage your dataobjects.
That said, I could only think of two solutions:

Filtering the gridfield and limiting it to one datarecord.

Your dataobject

class Contact extends DataObject
{
    private static $db = [
        'Name' => 'Varchar',
        'Phone' => 'Varchar',
        'Email' => 'Varchar'
        // etc, etc
    ];
}

Your ModelAdmin

class ContactModelAdmin extends ModelAdmin
{
    private static $managed_models = array(
        'Contact'
    );

    private static $url_segment = 'contact';

    private static $menu_title = 'My Contact Admin';

    public function getList()
    {
        $list = parent::getList();

        $list = $list->filter('Name', 'EagleEye')->limit(1);

        return $list;
    }
}

Or you might just wanna get rid of the gridfield and create some formfields, which you can populate.

class ContactModelAdmin extends ModelAdmin
{
    private static $managed_models = array(
        'Contact'
    );

    private static $url_segment = 'contact';

    private static $menu_title = 'My Contact Admin';

    public function getEditForm($id = null, $fields = null) {

        $form = parent::getEditForm($id, $fields);

        $gridFieldName = $this->sanitiseClassName($this->modelClass);
        $form->Fields()->removeByName($gridFieldName);

        $form->Fields()->push(
            TextField::create('Name', 'Name', 'EagleEye')
                ->performReadonlyTransformation()
        );
        $form->Fields()->push(
            TextField::create('Phone', 'Phone', '0123456789')
                ->performReadonlyTransformation()
        );
        $form->Fields()->push(
            TextField::create('Email', 'Email', '[email protected]')
                ->performReadonlyTransformation()
        );

        return $form;
    }
}

I hope this was what you were looking for.

2
votes

Instead of adding a single Client DataObject we can store these variables in the site settings using a SiteConfig extension.

To do this we create a SiteConfig extension with the variables and fields we would like:

mysite/code/extensions/CustomSiteConfig.php

class CustomSiteConfig extends DataExtension {

    private static $db = array(
        'Phone' => 'Varchar(255)',
        'Email' => 'Varchar(255)',
        'Address' => 'Varchar(255)'
    );

    public function updateCMSFields(FieldList $fields) {
        $fields->addFieldToTab('Root.Contact', TextField::create('Phone'));
        $fields->addFieldToTab('Root.Contact', TextField::create('Email'));
        $fields->addFieldToTab('Root.Contact', TextField::create('Address'));
    }
}

We activate the extension:

mysite/_config/config.yml

SiteConfig:
  extensions:
    - CustomSiteConfig

We can now use the the variables in any of our templates:

<% if $SiteConfig.Phone %>$SiteConfig.Phone<% end_if %>
<% if $SiteConfig.Email %>$SiteConfig.Email<% end_if %>
<% if $SiteConfig.Address %>$SiteConfig.Address<% end_if %>