SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Adding a CMS action

SSBcmsaction

If like me you cannot figure out how on earth to use the updateCMSActions() function in a decorator and you also can't get the getCMSActions() function to find your custom method inside the controller then here is a way to make it work, which will allow you to create custom actions and buttons to trigger those actions within the CMS.

So let's jump strait in, first thing we need to do is add the form action to our page using the getCMSActions() function. So inside your page model we add this:

	function getCMSActions(){
		
		$actions = parent::getCMSActions();
		
		$Action = new FormAction(
			   "doAction",
			   "Do something different"
			);
		$actions->push($Action);
		
		return $actions;
	} 

 

Decorating CMSMain

Now we have our button you might have though adding the doAction() function would be a simple case of sticking it into our controller. Unfortunately not, this will give you an error because when viewing a page in the CMS the edit form does not have access to the functions in our controller. So instead we are going to add our function to the same place as the other CMS actions:  inside CMSMain. However to avoid having to edit the core files we will use the LeftAndMainDecorator to do this. This works in exactly the same way as the DataObjectDecorator but, you guessed it, decorates LeftAndMain, which is the code class that controlls much of the CMS interface.

So create a new file inside mysite/code called CMSActionDecorator.php and put this code in it:

<?php
class CMSActionDecorator extends LeftAndMainDecorator {
	
	function doAction(){
		FormResponse::status_message(sprintf('All good!'),'good');
		return FormResponse::respond();
	}	
}

 

So all our doAction() function is going to do when run is show a green 'All good!' message at the bottom of the page. You can however put anything you like in here.

Something a little more useful

At this point you may be wondering how much use this is without having the currently selected pages ID. Well by adding $id = (int)$_REQUEST['ID'];  to the top of this function we can then use DataObject::get_by_id() or similar to get the current page and work on it. For example say I wanted to create a button that deleted all the DataObjects attached to the current page I could change my doAction() function to something like this:

	function doAction(){
		
		$id = (int)$_REQUEST['ID'];	
		
		$DataObjects = DataObject::get('SomeObject', 'PageID=' . $id);
		
		foreach($DataObjects as $DataObject){
			$DataObject->Delete();
		}
		
		FormResponse::status_message(sprintf('Deleted all objects' ),'good');
		return FormResponse::respond();
	}	

 

Config settings

Finally we need to tell SilverStripe that we have extended CMSMain by adding this line to our mysite/_config.php:

Object::add_extension('CMSMain', 'CMSActionDecorator');

 

And there you have it, the slightly hacky but still usable way to add form actions to your CMS pages.

Aram Balakjian avatar

Aram Balakjian

Aram is a web developer running London based agency Aab Web. He has a strong passion for developing attractive, usable sites around the SilverStripe CMS.

  • FullWebService
    22/01/2011 12:58pm (4 years ago)

    Two questions:

    Is it possible to add any Javascript to these actions?

    Is it possible to add buttons to the left of the default actions? A prepend instead of push sort of thing.

  • FullWebService
    23/01/2011 11:48am (4 years ago)

    I found the prepend thing: insertFirst()

  • VRoxane
    26/05/2011 5:42pm (3 years ago)

    Hi Aram !
    Great job as usual :) I was wondering : "how to add a new Action to a ModelAdmin Managed model ?"

    I did this :
    Object::add_extension('ModelAdmin', 'MAActionDecorator');
    Created the MAActionDecorator.php and pnd put the code you gave in my DataObject. The button shows but nothing happens when I click it. No green 'All good!' message shows up :(
    Any idea ?

  • Aram Balakjian
    26/05/2011 5:51pm (3 years ago)

    Hi Roxanne,

    It's slightly different for ModelAdmin, luckily I have written a tutorial for that one too :)

    http://www.ssbits.com/tutorials/2011/add-a-duplicate-button-to-model-admin/

    Let me know how you get on.

    Aram

  • VRoxane
    27/05/2011 7:05pm (3 years ago)

    Of course you DID write another wonderful tutorial !
    And after little struggle with my Dowhat Iwant function.... I did it !

    Thank you Aram :) !!!

  • comonox
    06/07/2012 11:29am (2 years ago)

    Hi, i extended the DataObjectDecorator, added
    Object::add_extension("SiteTree", "MyDecorator"); to _config.php and added the following method to my decorator:

    public function updateCMSActions(&$actions){
    $Action = new FormAction(
    "doAction",
    "Do something different"
    );

    $actions->push($Action);
    }
    this worked for me, and i don't have to change pageclasses over getCMSActions()

    Chris

  • Tate
    13/09/2012 3:37am (2 years ago)

    Sorry about posting on an old topic but I am looking for this same feature in SS3 but am having trouble getting there.
    Is there an easy way to create this feature in Silverstripe 3.

  • Aram Balakjian
    13/09/2012 8:37am (2 years ago)

    @Tate - Hmm, not tried this is SS3, but the principles should be the same, what problems are you having?

  • g4b0
    19/10/2012 8:12am (2 years ago)

    We too are having problems using that feature on SS 3.0.2? Could it be a SS3 regression?

    Thanks a lot for your great job writing tutorial/snippet on SS

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image Matt Clegg
10 article image dalesaurus

View full leaderboard


Advertisement