sorry for bumping this old thread, but i want to share how i solved my problem.
sadly i don't get it done without a plugin. to be able to add multiple subclasses to one gridview, i use silverstripe-gridfieldextensions this collection of gridfield extensions also includes one to sort the entries. ([Nobrainer Web] uses the same plugin in his solution)
<?php
class BaseModule extends DataObject{
static $db = array(
'Sort' => 'Int',
);
static $has_one = array('Page'=>'Page');
static $default_sort = '"Sort"';
function getCMSfields(){
$fields = parent::getCMSfields();
$fields->removeByName("Sort");
$fields->removeByName("PageID"); // get automatic value for current page
return $fields;
}
function getContent(){
return $this->renderWith($this->getClassName());
}
function getType(){
return $this->getClassName();
}
function getShort(){ // not really necessary, but nice to have
return "";
}
}
class ImagesModule extends BaseModule{ // example module 1
static $db = array(
'Headline' => 'VarChar',
);
static $has_many = array(
"Images" => "Image"
);
function getCMSfields(){
$fields = parent::getCMSfields();
$images = new UploadField(
"Images",
"Images",
$this->Images()
);
$fields->addFieldToTab("Root.Main", $images);
return $fields;
}
function getShort(){
return $this->getField('Headline');
}
}
class TextModule extends BaseModule{ // example module 2
static $db = array(
'Headline' => 'VarChar',
'Text' => 'HTMLText',
);
function getShort(){
return $this->getField('Headline');
}
}
class Page extends SiteTree{
static $has_many = array(
"Modules" => 'BaseModule',
);
function getCMSfields(){
$gf_config = GridFieldConfig_RecordEditor::create();
$gf_config->removeComponentsByType('GridFieldAddNewButton');
$gf_config->getComponentByType('GridFieldDataColumns')
->setDisplayFields(array('Type' => 'Type', 'Short' => 'Content'));
$gf_config->addComponents(
new GridFieldAddNewMultiClass(),
new GridFieldOrderableRows()
);
$moduleField = new GridField(
'Modules',
'Modules',
$this->Modules(),
$gf_config
);
$fields = parent::getCMSfields();
$fields->removeByName("Content");
$fields->addFieldToTab("Root.Main", $moduleField, "Metadata");
return $fields;
}
}
class Page_Controller extends ContentController {
}
to see the output add this statement to Page.ss
<% loop Modules %>
$Content
<% end_loop %>
and create the templates for the modules (e.g. TextModule.ss) in the Layout-folder.
i'm still new to silverstripe, so perhaps there is a shorter/better/more simple solution.