SilverStripe is now my CMS of choice, I have a few SilverStripe projects under my belt I'm enjoying developing CMS driven websites and unlocking some of the power of Sapphire, the framework underpinning the SilverStripe CMS. There is a learning curve attached however, which led me to start documenting little snippets that make life a little easier.
Templates
Resize an image and get URL on the fly in template file:
<% control Image %> <% control SetSize(blah, blah) %> $FileName <% end_control %> <% end_control %>
Using GroupedBy to organise a listing of Pages or DataObjects:
<% control AllChildren.GroupedBy(Province) %> <p>$Province</p> <% control Children %> $Title $Content <% end_control %> <% end_control %>
Check page class in the template:
If on the home page do not show the SilverStripe navigator. <% if ClassName != HomePage %> $SilverStripeNavigator <% end_if %>
Using renderWith() from a DataObject to give the view access to the data and methods of that object:
//Fields and methods in the someObject class will be accessible to the view $content = $someObject->renderWith("SomePage");
You can also pass data to the template by using customise():
$someViewableDataObject->customise(array( "Data" => $someData ))->renderWith('SomeTemplate');
Return an array of data in a DataObjectSet for access in the template:
public function getAllProvinces() { //Get all the children for this page then pull out the provinces $currentPage = $this->data(); $pages = $currentPage->AllChildren(); $allProvinces = array(); $i = 0; foreach ($pages as $page) { $allProvinces[$i]['provinceID'] = $page->Province; $allProvinces[$i++]['provinceName'] = $page->strProvince; } return new DataObjectSet($allProvinces); }
Adding comments to template files that will not be rendered:
<%-- Comments marked like this will be excluded from the HTML output --%>
If you ever have the problem of sitetree_link ids appearing in your anchor tags like:it is likely because the content containing the link is passed as plain text rather than as an instance of HTMLText.
$content = new HTMLText(); $content->setValue('html with the anchor tag in it here');
DataObjects
Setting default values for database fields, the $defaults array in SilverStripe DataObjects makes all new objects created have the default, it does not alter already saved objects (rows in the database).
static $db = array( 'Mailto' => 'Varchar(100)' ); static $defaults = array( 'Mailto' => 'info@example.com' );
Accessing the model (Page) from the controller, in Page_Controller this will return the Page object.
$this->data();
Accessing a field in a DataObject
$this->getField("Field"); //or $this->Field; //or $this->dataRecord->MyField;
Sometimes its useful to access a field from a DataObject and return the object that represents this field
public static $db = array( 'Amount' => 'Money' ); //Elsewhere in DataObject: $this->dbObject("Amount");
Accessing a component in a DataObject such as a $has_one or $has_many
$this->Field(); //has_one relationship $this->Fields(); //has_many relationship
Require a field in the CMS area
getCMSValidator() { return new RequiredFields('FieldName'); }
Accessing getFunctionName() as $FunctionName in the view, you can drop the 'get' prefix of a function name to call the function in views. So if you have a scenario like:
class Page extends SiteTree { public static $db = array( "Foo" => "Text", ); } class Page_Controller extends ContentController { public function getFoo() { return 'Some value'; } }
Calling $Foo in your view will result in 'Some value'. If you want to access $Foo of the Page class rename the function getFoo(). You don't need to write getters for the db fields in the model (Page in this case) because $db fields become variables in the view and $has_x relationships become methods. Creating a multiple or 2 column key index:
static $indexes = array( 'KeyName' => array( 'type' => 'unique', 'value' => 'ColumnOne,ColumnTwo' ) );
Checking if writing a DataObject for the first time in the onAfterWrite() method:
class Something extends Page { private $firstWrite = false; function onBeforeWrite() { parent::onBeforeWrite(); if (!$this->ID) $this->firstWrite = true; } function onAfterWrite() { parent::onAfterWrite(); if ($this->firstWrite) echo 'New object'; } }
Controllers
Because I am always forgetting the syntax, how to include jQuery from Sapphire on SilverStripe 2.4
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery/jquery.js');
If you want to overload the index() method of a controller its often useful to return the Content and Form:
function index() { //Do something here return array( 'Content' => $this->Content, 'Form' => $this->Form ); }
CMS
Adding nested tabs to 3 or more levels deep can be achieved by adding a TabSet and then adding new Tabs to that tab set:
$fields->addFieldToTab("Root", new TabSet('Advertisements', new TabSet('LargeAds', new Tab('One'), new Tab('Two')), new Tab('SmallAds') )); $fields->addFieldToTab("Root.Advertisements.LargeAds.One", new TextField('LargeAdOneLink', 'URL address for advertisement')); //Or something like $fields->addFieldToTab("Root", new TabSet('Advertisements')); $fields->addFieldToTab("Root.Advertisements", new Tab('LargeAds'));
Debugging
Javascript files are concatenated and saved in the Assets folder. If you are having problems accessing the CMS due to Javascript errors check the permissions of the assets/ and perhaps also assets/_combinedfiles/ folders. When SilverStripe is in production mode javascript files will be concatenated and saved. In order to disable this add the following line to mysite/_config.php:
Requirements::set_combined_files_enabled(false);
Debugging SilverStripe issues, the most annoying problem is the blank white page. The blank white page can often be attributed to some syntax error in the template file. If no errors are being shown try adding: ?isDev=1 to the URL. Or looking in apache error logs for any related errors:
tail -f /var/logs/apache2/error.log
Setting a log for the application is also useful, in the mysite/_config.php file:
SS_Log::add_writer(new SS_LogFileWriter('/var/www/silverstripe/mysite/errors.log'));
Then can log errors specifically using something like:
SS_Log::log(new Exception('Some log message here'), SS_Log::NOTICE); //Or for objects/arrays SS_Log::log(new Exception(print_r($this, true)), SS_Log::NOTICE);
Admin splash / loading screen stuck? If you have a look in the firebug console and see a bunch of javascript errors its likely due to problems creating combinedfiles for the javascript that needs to be loaded for the CMS. This might be due to a permissions problem of your /assets/_combinedfiles/ folder, if changing permissions of this folder doesn't work and neither does changing the owner or turning off php_safe_mode then you can stop SilverStripe from combining files in your _config.php file:
Requirements::set_combined_files_enabled(false);
PHP: Warning: Unexpected character in input: ''' (ASCII=39) - this warning was related to a PHP parse error in one of my class files, (http://www.php.net/manual/en/function.token-get-all.php#79502). In my case it related to a poorly formed Enum string. If you get the warning: "File is not a valid upload" when trying to upload files to SilverStripe then you might want to view this ticket and apply one of the patches, you can also try turning off open_basedir.
Useful Documentation
I find myself hitting most of these pages often for reference:
- Page controls - what you can and can't do in the SilverStripe templates.
- SilverStripe templates - including template syntax, if and control blocks and Modulus/MultipleOf.
- Debugging - a must have for any CMS.
- Environment management - a cool technique to manage development and live environments for a SilverStripe project.
- Execution pipeline - the process of a page request from SilverStripe.
- Image controls - all those functions you can use on Images in SilverStripe templates.
- Text methods - all the functions you can use to manipulate text in templates.
- URL variable tools - very useful for development and testing a SilverStripe site
SilverStripe text books for reference:
- SilverStripe 2.4 reference book - this is the most recent SilverStripe book which I am currently reading and is very good.
- Original SilverStripe book - a good reference that helped me when I was getting started