Tutorials - Big bits of code to help you do more
Creating and deleting dataobjects from the front end
Tweet29 June 2012 | | | Supports v2.4
One of my clients wanted a clear interface from which he could easily attach downloadable files to some pages of his site. Instead of using modelAdmin and granting him an access to Silverstripe admin panel, I chose to create a front-end page showing a simple upload form, a list of the files previously uploaded to the server, and a delete button for each of them.
First steps
Creating the "Programme" page the uploaded files will be attached to, and the "Telechargement" dataobject for the uploaded file
mysite/code/Programme.php
Each "programme" can have many "telechargements" :
<?php
class Programme extends Page {
public static $has_many = array(
'Telechargements'=>'Telechargement'
);
}
mysite/code/Telechargement.php
Each "telechargement" can be attached to only one "programme" :
<?php
class Telechargement extends DataObject {
public static $db = array(
'Title'=>'Text'
);
static $has_one = array(
'MonProgramme' => 'Programme',
'Fichier' => 'File',
'MaPageTelechargement' => 'PageTelechargement'
);
}
themes/blackcandy/templates/Layout/Programme.ss
Shows a list of the downloadable files :
<h1>$Title</h1> $Content <% if Telechargements %> <p>Downloadable files :</p> <ul> <% control Telechargements %> <li><a href="<% control Fichier %>$Link<% end_control %>" target="_blank">$Title</a></li> <% end_control %> </ul> <% end_if %>
Second step
Creating the "PageTelechargement" page for the upload form
mysite/code/PageTelechargement.php
<?php
class PageTelechargement extends Page {
public static $has_many = array(
'Telechargements' => 'Telechargement'
);
}
class PageTelechargement_Controller extends Page_Controller {
public static $allowed_actions = array (
'UploadForm'
);
function UploadForm() {
// retrieve all the "Programme" pages
$myDoSet = DataObject::get("Programme","","Title ASC");
if($myDoSet){$map = $myDoSet->toDropDownMap();}
// form fields
$fields = new FieldSet(
new TextField('Title', 'File name :'),
new FileField('Fichier', 'Upload file :','','','','telechargements' ),
// The user can tick a radio button to choose the programme related to the uploaded file
new OptionsetField('MonProgrammeID','Related programme :', $map),
);
$actions = new FieldSet(
new FormAction('UploadFiles', 'Télécharger')
);
// all fields are required
$validator = new RequiredFields('Title', 'Fichier', 'MonProgrammeID');
// return form
$form = new Form($this, 'UploadForm', $fields, $actions, $validator);
return $form;
}
// write a new "Telechargement" dataobject into the database
function UploadFiles($data, $form) {
$transfert = new Telechargement();
$form->saveInto($transfert);
$transfert->write();
Director::redirectBack();
}
}
themes/blackcandy/templates/Layout/PageTelechargement.ss
Our template so far :
<h1>$Title</h1> $Content $UploadForm
Third step
Probably the most interesting part, which involves rules and actions : creating a function to delete a "Telechargement" dataobject previously created
mysite/code/PageTelechargement.php
<?php
class PageTelechargement extends Page {
...
}
class PageTelechargement_Controller extends Page_Controller {
public static $allowed_actions = array (
'UploadForm',
// allow a new action
'delete'
);
function UploadForm() {
...
}
function UploadFiles($data, $form) {
...
}
// create our delete function
function delete(){
// get the ID parameter in the URL
$Params = $this->getURLParams();
// get the dataobject corresponding to the ID
if ($downloadToDelete = DataObject::get_by_id('Telechargement', (int)$Params['ID']))
// delete the dataobject found and go back to the page
{$downloadToDelete->delete();}
Director::redirectBack();
}
}
mysite/_config.php
We now need to write our rule. URLs ending with ".../delete/ID" will be handled by the "PageTelechargement" controller and the delete function will be called :
mysite/_config.php
We now need to write our rule. URLs ending with ".../delete/ID" will be handled by the "PageTelechargement" controller and the delete function will be called :
Director::addRules(100, array( 'delete//$ID!' => 'PageTelechargement_Controller' ));
themes/blackcandy/templates/Layout/PageTelechargement.ss
That's it. Now, we can create a list showing the uploaded dataobjects in the template and add a link to delete each of them :
<h1>$Title</h1>
$Content
<ul>
<% control Telechargements %>
<li>
Name : $Title -
File : <% control Fichier %><a href="$Link">$Name</a><% end_control %> -
Programme : <% control MonProgramme %><a href="$Link">$Title</a><% end_control %> -
<a href="{$Top.Link}delete/$ID" title="">delete ?</a>
</li>
<% end_control %>
</ul>
$UploadForm
A simplified ComplexTableField for the front end !
13 Comments
RSS feed for comments on this page RSS feed for all comments
swaiba
03/07/2012 2:43pm (11 months ago)
Hi, Great article - I just wonder whether someone might have shown you https://github.com/chillu/silverstripe-genericviews
stallain
03/07/2012 3:13pm (11 months ago)
@ Swaiba - Thank you
I didn't know about this module before. It would probably have saved me time !
Bart van Irsel
03/07/2012 8:07pm (11 months ago)
Hi stallain, great article which explains the basic concepts of building a frontend editor of data-objects, thanks! I guess you limit access to this page in the CMS, so for example the delete method of the controller is not available for users which are not logged in.
stallain
04/10/2012 10:49pm (8 months ago)
@Lobek
Hi, I think you simply have to change this in the "delete" function :
$downloadToDelete->Image()->delete();
Stan
maksfeltrin
06/11/2012 12:26am (7 months ago)
Why using Director::addRules instead of PageTelechargement_Controller::url_handlers ?
stallain
06/11/2012 2:58am (7 months ago)
Hi, my method is to be used with SS 2.4.
But you're right : since SS3, it seems that you've got to use url_handlers or the routes.yml file instead.
Madan Sapkota
20/11/2012 10:40am (6 months ago)
Lol this all is fine. After I copy / Paste the code, what should I type in URL? http://example.com/programme or http://example.com/elechargement? both URL i tried an not working. Hope you all can help.
stallain
20/11/2012 11:16am (6 months ago)
@Madan
Simply go to the URL of the "PageTelechargement" you created in the CMS
Madan Sapkota
20/11/2012 2:05pm (6 months ago)
so you mean http://example.com/PageTelechargement? I am very confused in URL routing of SS can you paste me good reference if available.
stallain
20/11/2012 2:19pm (6 months ago)
http://doc.silverstripe.org/framework/en/ is a good start
Madan Sapkota
20/11/2012 3:20pm (6 months ago)
@Stallain I knew this URL. What I am asking is the specific reference to the URL I am also confused passing data from controller to Views (.ss files).
stallain
20/11/2012 3:36pm (6 months ago)
@Madan
If you use the full package (with cms), you simply have to create a new page in the site tree being of type "PageTelechargement" => you can define its URL through the admin
If you use only the framework (since SS3), you will have to add routes and define which controller has to be called with the URL of your choice (http://doc.silverstripe.com/framework/en/reference/director). If your controller's name is "MyController", just call your template "MyController.ss", and it should work (see http://doc.silverstripe.org/framework/en/reference/templates#calling-templates-from-php-code).
Be careful if you use SS3 : the templating language has changed a little (<% loop %> instead of <% control %>, etc.)
Madan Sapkota
20/11/2012 4:08pm (6 months ago)
:) thank you for the good information and links.
Post a comment ...
You cannot post comments until you have logged in. Login Here.