Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Customising the CMS

SS3 (3.02) Display of DataObjects in the CMS/How to edit DataObjects in the CMS


Reply

2 Posts   634 Views

Avatar
nantoga

10 November 2012 at 1:50am (Last edited: 10 November 2012 10:05am), Community Member, 6 Posts

I have just started with Silverstripe and I am quite surprised how fast I could almost complete my website. Almost, because I got stuck in the last piece and after long hours of researching I have to confess that I can't make my way through it:

I am creating a website for my portfolio.

Therefore I have a

ProjectHolder Class extends Page // holder page to display summaries of all projects
ProjectPage Class extends Page // project page
ProjectCategories Class extends DataObject // contains different categories such as book design, wayfinding systems, etc.

Database relationships:

-----
ProjectPage:

   public static $has_one = array(
      'Category' => 'ProjectCategories' // every Project can have one Categoy
   );

-----
ProjectCategories:

   public static $has_many = array(
      'Project' => 'ProjectPage' // every Category can contain many Projects
   );
------

------
ProjectHolder
   static $allowed_children = array('ProjectPage');
------

########
SO HERE IT COMES:
What I would like to do is to show a table in the CMS in the ProjectHolder Page to add/edit/delete my ProjectCategories. I would like to make it work with gridfields

Actually, I just can't work it out how to achieve this at all.

Your help will be very appreciated!

PS: Of course, I have read
http://doc.silverstripe.org/framework/en/tutorials/5-dataobject-relationship-management
But this doesn't help as I need the gridfield on the Holder Page

Probably I just need somebody pointing me in the right direction...
#########

Below are all Classes in detail:

class ProjectPage extends Page {

   public static $db = array(
      'Year' => 'Date',
      'Title' => 'Varchar',
      'Summary' => 'HTMLText'
   );

   
   public static $has_many = array(
      'Photo' => 'Image'
   );
   
   public static $has_one = array(
      'Category' => 'ProjectCategories'
   );
   
public function getCMSFields() {
$fields = parent::getCMSFields();
$dateField = new DateField('Year');
$dateField->setConfig('showcalendar', true);
$dateField->setConfig('dateformat', 'YYYY');
$fields->addFieldToTab('Root.Main', $dateField, 'Content');
$fields->addFieldToTab('Root.Main', new TextField('Title'), 'Content');
$fields->addFieldToTab('Root.Main', new HtmlEditorField('Summary'), 'Content',5);
$fields->addFieldToTab("Root.Images", new UploadField('Photo'));
return $fields;
}

}

class ProjectCategories extends DataObject {

   public static $db = array(
      'Category' => 'Varchar'
   );
   
   public static $has_many = array(
      'Project' => 'ProjectPage'
   );
   
   static $singular_name = 'Category';
   static $plural_name = 'Categories';
   
   

}

class ProjectHolder extends Page {

   static $allowed_children = array('ProjectPage');

   public static $db = array(

   );

   public static $has_one = array(
   );

}

Avatar
nantoga

10 November 2012 at 11:30am (Last edited: 10 November 2012 12:36pm), Community Member, 6 Posts

Ok, I tried the following which works but it is not exactly what I intended. I will write it down because there is not much documentation about the gridfield and hopefully it will help someone else who starts with Silverstripe

Version 3.02

First, I couldn't access the Database linked to ProjectPage from ProjectHolder. Therefore I created a relation from ProjectHolder to the ProjectCategories as well. (Actually that makes sense, because I could have different ProjectHolder Pages on my website and each ProjectHolder Page could contain its own Categories)

class ProjectHolder extends Page {

   static $allowed_children = array('ProjectPage');

   public static $db = array(

   );

   public static $has_one = array(
   );

   public static $has_many = array(
      'Categories'=>'ProjectCategories'
   );

public function getCMSFields() {
$fields = parent::getCMSFields();
      
      // Konfiguration GridField: Daten aus relationaler Datenbank
      $config = GridFieldConfig_RelationEditor::create();
      // Welche Spalten sollen angezeigt werden
      $config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
'Category' => 'Category'
));
// Zusätzliche Komponenten ergänzen
$config->addComponents(
   new GridFieldDeleteAction(false) // Löscht den Eintrag und nicht nur den Link aufheben
);
// Grid Field anlegen: Name, Überschrift im CMS, Welche Daten, Griedfield-Konfiguaration
      $gridField = new GridField('Categories', 'Categories', $this->Categories(), $config);
      
      
      $fields->addFieldToTab("Root.Categories", $gridField);
return $fields;
}

}

class ProjectCategories extends DataObject {

   public static $db = array(
      'Category' => 'Varchar'
   );
   
   public static $has_many = array(
      'Project' => 'ProjectPage'
   );
   
   
   public static $has_one = array(
      'ProjectHolder' => 'ProjectHolder'
   );

   
   static $singular_name = 'Category';
   static $plural_name = 'Categories';
   
   

}

#### Explanation Usage Grid Field:

$config = GridFieldConfig_RelationEditor::create();
http://api.silverstripe.org/3.0/framework/GridFieldConfig.html

Here you set up the kind of GridField you want to use. In this case it is a grid field to access data in a relational database (more types see documentation)

$config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
'Category' => 'Category'
));

Next you need to define which columns need to be shown in the grid field. Otherwise you receive just an empty grid field with only the id column. In my particular case I have only the Category column defined in my ProjectCategories Class.

$config->addComponents(
   new GridFieldDeleteAction(false) // Löscht den Eintrag und nicht nur den Link aufheben
);

Of course, you want to be able to delete entries as well. Otherwise you have only the opportunity to unlink

That is my basic setup for the gridfield. It would be very nice if there were a page in the documentation where all possible actions etc. are listed. The way I found out about this action was to actually look at the source code which can be found at:
/framework/forms/gridfield
The naming seems arbitrary... Unfortunately you have to open the files to find out what the classes can do. It would be more logical if all Actions are named GridFieldAction_NameofTheAction or whatever... Anyway...

      $gridField = new GridField('Categories', 'Categories', $this->Categories(), $config);
      
This actually creates the gridField
Parameters: Name, Name in the CMS, SS_List = Link to the Database you want to display, GridFieldConfiguration

      $fields->addFieldToTab("Root.Categories", $gridField);
Adds a new tab in the CMS called »Categories« to display the GridField

####
I could get it running but I am still curious how I could include the GridField from the ProjectHolder Page without creating a database relationship. Because this relationship is (indirectly) set up by declaring
static $allowed_children = array('ProjectPage');

Somebody knows how to do it?
####