# Widgets Module [![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-widgets.png?branch=master)](http://travis-ci.org/silverstripe/silverstripe-widgets) ## Introduction [Widgets](http://silverstripe.org/widgets) are small pieces of functionality such as showing the latest comments or Flickr photos. They normally display on the sidebar of your website. To check out a what a [Widget](http://silverstripe.org/widgets) can do watch the [Widget video](http://silverstripe.com/assets/screencasts/SilverStripe-Blog-DragDrop-Widgets.swf) and try out the [demo site](http://demo.silverstripe.org/) ## Requirements * SilverStripe 3.0 ### Installation Install the module through [composer](http://getcomposer.org): composer require silverstripe/widgets Widgets are essentially database relations to other models, mostly page types. By default, they're not added to any of your own models. The easiest and most common way to get started would be to create a single collection of widgets under the name "SideBar" on your `Page` class. This is handled by an extension which you can enable through your `config.yml`: :::yml Page: extensions: - WidgetPageExtension Run a `dev/build`, and adjust your templates to include the resulting sidebar view. The placeholder is called `$SideBarView`, and loops through all widgets assigned to the current page. Alternatively, you can add one or more widget collections to your own page types. Here's an example on how to just add widgets to a `MyPage` type, and call it `MyWidgetArea` instead. :::php class MyPage extends Page { // ... static $has_one = array( "MyWidgetArea" => "WidgetArea", ); public function getCMSFields() { $fields = parent::getCMSFields(); $fields->addFieldToTab("Root.Widgets", new WidgetAreaEditor("MyWidgetArea")); return $fields; } } In this case, you need to alter your templates to include the `$MyWidgetArea` placeholder. ## Writing your own widgets To create a Widget you need at least three files - a php file containing the class, a template file of the same name and a config file called *_config.php* (if you dont need any config options for the widget to work then you can make it blank). Each widget should be in its own folder like widgets_widgetName/ After installing or creating a new widget, **make sure to run db/build?flush=1** at the end of the URL, *before* attempting to use it. The class should extend the Widget class, and must specify three static variables - $title, the title that will appear in the rendered widget (eg Photos), $cmsTitle, a more descriptive title that will appear in the cms editor (eg Flickr Photos), and $description, a short description that will appear in the cms editor (eg This widget shows photos from Flickr). The class may also specify functions to be used in the template like a page type can. If a Widget has configurable options, then it can specify a number of database fields to store these options in via the static $db array, and also specify a getCMSFields function that returns a !FieldList, much the same way as a page type does. An example widget is below: **FlickrWidget.php** :::php "Varchar", "Photoset" => "Varchar", "Tags" => "Varchar", "NumberToShow" => "Int" ); static $defaults = array( "NumberToShow" => 8 ); static $title = "Photos"; static $cmsTitle = "Flickr Photos"; static $description = "Shows flickr photos."; public function Photos() { Requirements::javascript(THIRDPARTY_DIR . "/prototype/prototype.js"); Requirements::javascript(THIRDPARTY_DIR . "/scriptaculous/effects.js"); Requirements::javascript("mashups/javascript/lightbox.js"); Requirements::css("mashups/css/lightbox.css"); $flickr = new FlickrService(); if($this->Photoset == "") { $photos = $flickr->getPhotos($this->Tags, $this->User, $this->NumberToShow, 1); } else { $photos = $flickr->getPhotoSet($this->Photoset, $this->User, $this->NumberToShow, 1); } $output = new ArrayList(); foreach($photos->PhotoItems as $photo) { $output->push(new ArrayData(array( "Title" => $photo->title, "Link" => "http://farm1.static.flickr.com/" . $photo->image_path .".jpg", "Image" => "http://farm1.static.flickr.com/" .$photo->image_path. "_s.jpg" ))); } return $output; } public function getCMSFields() { return new FieldList( new TextField("User", "User"), new TextField("PhotoSet", "Photo Set"), new TextField("Tags", "Tags"), new NumericField("NumberToShow", "Number to Show") ); } } **FlickrWidget.ss** :::ss <% control Photos %> <% end_control %> ## Extending and Customizing ### Rendering a $Widget Individually To call a single Widget in a page - without adding a widget area in the CMS for you to add / delete the widgets, you can define a merge variable in the Page Controller and include it in the Page Template. This example creates an RSSWidget with the SilverStripe blog feed. :::php public function SilverStripeFeed() { $widget = new RSSWidget(); $widget->RssUrl = "http://feeds.feedburner.com/silverstripe-blog"; return $widget->renderWith("WidgetHolder"); } To render the widget, simply include $SilverStripeFeed in your template: $SilverStripeFeed As directed in the definition of SilverStripeFeed(), the Widget will be rendered through the WidgetHolder template. This is pre-defined at `framework/templates/WidgetHolder.ss` and simply consists of: :::ss