ExtBase Cookbook 6 - How to generate RSS Feeds with ExtBase
As I wanted to add Cooliris functionality to my gallery extension, I had to create a RSS-Feed. As this has not yet been done within the Blog-Extension, I wanted to show how I implemented this.
First of all, we create a new page type inside the 'Configuration/TypoScript/setup.txt' file:
xml = PAGE xml { typeNum = 100 10 = USER 10 { userFunc = tx_extbase_dispatcher->dispatch pluginName = Pi1 extensionName = Yag controller = Album switchableControllerActions { 1 { controller = Album actions = rss } } action = rss settings =< plugin.tx_yag.settings persistence =< plugin.tx_yag.persistence view =< plugin.tx_yag.view } config { disableAllHeaderCode = 1 additionalHeaders = Content-type:application/xml xhtml_cleaning = 0 admPanel = 0 } }
There is one other important line to add to your setup.txt in order to make persistence work. Without this line, I got an "Expected parameter 1 to be object, NULL given" exception:
plugin.tx_yag { settings { } view { templateRootPath = EXT:yag/Resources/Private/Templates/ partialRootPath = EXT:yag/Resources/Private/Partials/ layoutRootPath = EXT:yag/Resources/Private/Layouts/ } persistence { storagePid = 6 } }
We generate a new page type 100, which is responsible for showing our RSS XML. We use a USER object to register an ExtBase dispatcher that should handle the RSS Request. The next lines are taken from the 'Tx_Extbase_Utility_Extension' class, which is normally used to register ExtBase based extions as page contents. The last lines prevents rendering of headers by typo3.
I'm not sure, whether the next step is required, but I registered the RSS action for the controller inside 'ext_localconf.php':
Let's know create an action method inside the Album controller:
/** * Rss Feed Action rendering a RSS Feed of media * * @param Tx_Yag_Domain_Model_Album $album Album to generate rss feed for * @return string The rendered RSS Feed */ public function rssAction(Tx_Yag_Domain_Model_Album $album = null) { if ($album != null) { $this->view->assign('album', $album); return $this->view->render(); } else { return "Kein Album --> kein RSS!"; } }
Last but not least, we need a template for rendering the feed. Here's what I wrote for Cooliris plugin ('Resources/Private/Templates/Album/rss.html'):
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <f:for each="{album.images}" as="image"><item> <title>{image.title}</title> <media:description>{image.description}</media:description> <link>{image.single.filePath}</link> <media:thumbnail url="{image.thumb.filePath}"/> <media:content url="{image.single.filePath}"/> </item> </f:for></channel> </rss>
Here it is very important, that you spare the newline behind the '<f:section...>' tag, otherwise, the generated XML is not parsed by the browser!
YAG unterstützt jetzt Cooliris
Bis jetzt stand ja die Darstellung der Photos in meiner Gallery immer ganz oben auf der TODO-Liste. Dann bin ich heute durch Zufall wieder auf das Cooliris Plugin gestoßen und habe mich dann dran gemacht, den benötigten RSS-Feed mit in meine Gallery aufzunehmen.
Es war nicht ganz leicht, ExtBase einen RSS nach meinen Wünschen zu entlocken, schließlich habe ich es aber hingekriegt und es folgt morgen ein Cookbook-Eintrag dazu!
Hier ein erster Screenshot der Darstellung in Cooliris:
Fröhliche Weihnachten
Bevor's im väterlichen Gehäus' jetzt gleich so richtig weihnachtlich zur Sache geht und Pink Floyd der festlichen Musik weichen muss, möchte ich die Gelegenheit noch nutzen und euch allen fröhliche Weihnachten und besinnliche Feiertage zu wünschen. Zu diesem Anlass erschien mir das folgende Bild irgendwie passend :-)
ExtBase Cookbook 5 - How to make new domain objects persistent
Today I faced the problem, that I could not access a new-created object after redirect. Regard the following two actions inside a controller:
/** * Shows all images of a album * * @param Tx_Yag_Domain_Model_Album $album Album object to show images from * @param Tx_Yag_Domain_Model_Gallyer $gallery Gallery that holds album * @return string The rendered index action */ public function indexAction(Tx_Yag_Domain_Model_Album $album=NULL, Tx_Yag_Domain_Model_Gallery $gallery=NULL) { $this->view->assign('album', $album); $this->view->assign('gallery', $gallery); } /** * Adds a new album to repository * * @param Tx_Yag_Domain_Model_Album $newAlbum New album to add * @return string The rendered create action */ public function createAction(Tx_Yag_Domain_Model_Album $newAlbum, Tx_Yag_Domain_Model_Gallery $gallery = NULL) { $this->albumRepository->add($newAlbum); if ($gallery != NULL) { $gallery->addAlbum($newAlbum); } $this->flashMessages->add('Your new album was created.'); }
As I had to find out, this doesn't work. When redirecting from the "createAction" to the "indexAction" I always got an empty object for "album". So the trick is, to make this object persistent right after you created it from a form input:
$persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); /* @var $persistenceManager Tx_Extbase_Persistence_Manager */ $persistenceManager->persistAll();
So putting it together, the second method should look like that in order to work. Thanks to Robert Böttner for helping me out with that on the ExtBase Mailinglist!
/** * Adds a new album to repository * * @param Tx_Yag_Domain_Model_Album $newAlbum New album to add * @return string The rendered create action */ public function createAction(Tx_Yag_Domain_Model_Album $newAlbum, Tx_Yag_Domain_Model_Gallery $gallery = NULL) { $this->albumRepository->add($newAlbum); if ($gallery != NULL) { $gallery->addAlbum($newAlbum); } $this->flashMessages->add('Your new album was created.'); $persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); /* @var $persistenceManager Tx_Extbase_Persistence_Manager */ $persistenceManager->persistAll(); }
ExtBase Cookbook 4 - Accessing arguments from requests
The blog-example shows multiple ways to pass objects to controller actions from forms and links. It does not show how to access "normal" form parameters from within a controller's action, so here is a little tutorial on how to do that.
In your form you might have something like that:
<f:form method="post" controller="AlbumContent" action="addImages" name="addImages" arguments="{gallery : gallery, album : album}"> <f:form.textbox name="path" size="30" /><br /> <p>If you already have created thumbnails and single images, you can chose the sub-directories here:</p> <f:form.textbox name="thumbsDir" size="20" /><br /> <f:form.textbox name="singlesDir" size="20" /><br /> <f:form.submit class="submit" value="Submit"/> </f:form>
so there is no magic in generating "normal" form elements. Btw you can see how to "forward" further objects to the controller's action via the "arguments" attribute of your form viewhelper. You can now access your parameters in your controller's action via the following lines of code:
$path = $this->request->getArgument('path');
Everything is quite simple though you get an error, if a requested parameter is not available in the current request. So it's better to write code like that:
public function addImagesAction( Tx_Yag_Domain_Model_Gallery $gallery=NULL, Tx_Yag_Domain_Model_Album $newAlbum=NULL) { $path = $thumbsPath = $singlesPath = ''; if ($this->request->hasArgument('basePpath')) { $basePath = $this->request->getArgument('path'); } if ($this->request->hasArgument('thumbsPath')) { $thumbsPath = $this->request->getArgument('thumbsPath'); } if ($this->request->hasArgument('singlesPath')) { $singlesPath = $this->request->getArgument('singlesPath'); } $this->view->assign('gallery', $gallery); $this->view->assign('newAlbum', $newAlbum); }
to make things more simple, I decided to add a function to my controller that handles parameter access more simple:
protected function getParametersSafely($parameterName) { if ($this->request->hasArgument($parameterName)) { return $this->request->getArgument($parameterName) } return NULL }




