Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, Ed, biapar, Willr, Ingo, swaiba

[SOLVED] write a xml file - OnAfterWrite

Go to End

19 Posts   6751 Views


Community Member, 267 Posts

18 March 2011 at 2:26am

Edited: 18/03/2011 2:27am

@Banal, i will check your method in a sec..

for now it is solved. I didnt used the template because it was not working. and when viewing online (with the public function) <img> tags were closed by a slash <img height="567" />
this was illegal for the xml, so another reason to NOT use a template for xml.

example can be found here (temporary):

for the people who wan to know how i did it:

class Flyer extends Page {
	static $has_many = array (
		'FlyerPaginas' => 'FlyerPagina'
	public function getCMSFields() {
    $fields = parent::getCMSFields();
    $manager = new FileDataObjectManager(
      'FlyerPaginas', // relation name
      'FlyerPagina', // class name of the DataObject
      'Image', // name of the file relation in the DataObject
			 'Title' => 'Title',
			// 'Comment' => 'Comment',
	 	), // headings
      'getCMSFields_forPopup' // name of the function for the popup fields
	$fields->addFieldToTab('Root.Content.Images', $manager);
    return $fields;

	public function onAfterWrite(){
		$dom = new DomDocument('1.0'); 
		$implementation = new DOMImplementation();
		$dtd = $implementation->createDocumentType('xml',
				'DOCTYPE book SYSTEM',
		$dom = $implementation->createDocument('', '', $dtd);
		$book            = $dom->appendChild($dom->createElement('book'));
		$plugins         = $book->appendChild($dom->createAttribute('plugins')); 
		$plugins2        = $plugins->appendChild($dom->createTextNode('zoom, keyboardnavigation, navigationbar, swfaddress')); 
		$pagewidth       = $book->appendChild($dom->createAttribute('pagewidth')); 
		$pagewidth2      = $pagewidth->appendChild($dom->createTextNode('567')); 
		$pageheight      = $book->appendChild($dom->createAttribute('pageheight')); 
		$pageheight2     = $pageheight->appendChild($dom->createTextNode('567')); 
		$lang            = $book->appendChild($dom->createAttribute('lang')); 
		$lang2           = $lang->appendChild($dom->createTextNode('en')); 
		$zoomminscale    = $book->appendChild($dom->createAttribute('zoomminscale')); 
		$zoomminscale2   = $zoomminscale->appendChild($dom->createTextNode('0.5')); 
		$zoommaxscale    = $book->appendChild($dom->createAttribute('zoommaxscale')); 
		$zoommaxscale2   = $zoommaxscale->appendChild($dom->createTextNode('2.0')); 
		$zoomsnap        = $book->appendChild($dom->createAttribute('zoomsnap')); 
		$zoomsnap2       = $zoomsnap->appendChild($dom->createTextNode('0.5, 1.0, 1.5, 2.0')); 
		$zoomsteps       = $book->appendChild($dom->createAttribute('zoomsteps')); 
		$zoomsteps2      = $zoomsteps->appendChild($dom->createTextNode('0.5')); 
		$dragrange       = $book->appendChild($dom->createAttribute('dragrange')); 
		$dragrange2      = $dragrange->appendChild($dom->createTextNode('20')); 
		$qualitycontrol  = $book->appendChild($dom->createAttribute('qualitycontrol')); 
		$qualitycontrol2 = $qualitycontrol->appendChild($dom->createTextNode('true')); 
		$thumbscale      = $book->appendChild($dom->createAttribute('thumbscale')); 
		$thumbscale2     = $thumbscale->appendChild($dom->createTextNode('0.35')); 
		$cornerhint      = $book->appendChild($dom->createAttribute('cornerhint')); 
		$cornerhint2     = $cornerhint->appendChild($dom->createTextNode('true')); 
		$pagethickness   = $book->appendChild($dom->createAttribute('pagethickness')); 
		$pagethickness2  = $pagethickness->appendChild($dom->createTextNode('0.1')); 
		$shadows 		 = $book->appendChild($dom->createAttribute('shadows')); 
		$shadows2 		 = $shadows->appendChild($dom->createTextNode('0.3')); 
		$startpage  	 = $book->appendChild($dom->createAttribute('startpage')); 
		$startpage2 	 = $startpage->appendChild($dom->createTextNode('1')); 
		$centercovers  	 = $book->appendChild($dom->createAttribute('centercovers')); 
		$centercovers2	 = $centercovers->appendChild($dom->createTextNode('false')); 
		$pageoffset 	 = $book->appendChild($dom->createAttribute('pageoffset')); 
		$pageoffset2	 = $pageoffset->appendChild($dom->createTextNode('0')); 

		$chapter   = $book->appendChild($dom->createElement('chapter'));
		foreach($this->FlyerPaginas() as $FlyerPagina) {
			$page    = $chapter->appendChild($dom->createElement('page')); 
			$img     = $page->appendChild($dom->createElement('img')); 
			$width   = $img->appendChild($dom->createAttribute('width')); 
			$width2  = $width->appendChild($dom->createTextNode('567')); 
			$height  = $img->appendChild($dom->createAttribute('height')); 
			$height2 = $height->appendChild($dom->createTextNode('567')); 
			//Zoom level 0,5
			$src1      = $img->appendChild($dom->createElement('src')); 
			$scaleA    = $src1->appendChild($dom->createAttribute('scale')); 
			$scaleB    = $scaleA->appendChild($dom->createTextNode('0.5')); 
			$src1 ->appendChild(
			//Zoom level 0,75
			$src5      = $img->appendChild($dom->createElement('src')); 
			$scaleX    = $src5->appendChild($dom->createAttribute('scale')); 
			$scaleY    = $scaleX->appendChild($dom->createTextNode('0.75')); 
			$src5 ->appendChild(
			//Zoom level 1,0
			$src2      = $img->appendChild($dom->createElement('src')); 
			$scaleC    = $src2->appendChild($dom->createAttribute('scale')); 
			$scaleD    = $scaleC->appendChild($dom->createTextNode('1.0')); 
			$src2 ->appendChild(
			//Zoom level 1,5
			$src3      = $img->appendChild($dom->createElement('src')); 
			$scaleE    = $src3->appendChild($dom->createAttribute('scale')); 
			$scaleF    = $scaleE->appendChild($dom->createTextNode('1.5')); 
			$src3 ->appendChild(
			//Zoom level 2,0
			$src4      = $img->appendChild($dom->createElement('src')); 
			$scaleG    = $src4->appendChild($dom->createAttribute('scale')); 
			$scaleH    = $scaleG->appendChild($dom->createTextNode('2.0')); 
			$src4 ->appendChild(

		//generate xml 
		$dom->formatOutput = true; // set the formatOutput attribute of 
								// domDocument to true 
		// save XML as string or file 
		$test1 = $dom->saveXML(); // put string in test1 
		$dom->save('megazine.mz3'); // save as file - add absolute path

class Flyer_Controller extends Page_Controller {

class FlyerPagina extends DataObject {
	static $db = array (
		'Title' => 'Text',
	//	'Comment' => 'HTMLText',
	static $has_one = array (
		'Image' => 'Image',
		'Flyer' => 'Flyer'
	public function getCMSFields_forPopup() {
		$fields = new FieldSet();
		$fields->push(new TextField('Title'));
		//$fields->push(new SimpleTinyMCEField('Comment'));
		$fields->push(new FileUploadField('Image','Upload files'));
		return $fields;


Community Member, 904 Posts

18 March 2011 at 2:59am

I use templates to output XML code all the time. You can create valid image tags yourself and use $Image.Link to just get the src part..

Also writing to files never was an issue... here's a flash page that's driven by SilverStripe and uses exactly this (templates for xml generation and caching to files):


Community Member, 1 Post

9 July 2011 at 10:12pm

I managed to do something similar to what you wanted to do originally through onAfterWrite(). Since your onAfterWrite() is in the FlyerPagina DataObject, when $this->renderWith() is called, the FlyerPagina object is the the root object. This means that <% control FlyerPagina %> attempts to descend into the FlyerPagina object when it is already at that object level. Instead, <% control Me %> needs to be used in place of <% control FlyerPagina %> so the control stays at the top level. From there the FlyerPagina object variables are accessible using the $ prefix as with any other template. This fix also applies to DataObjectSets that call renderWith(), which is what I ended up using to save a file containing data from all the DataObjects with that class type.

What I find odd is that I needed to force a theme setting in the onAfterWrite() method in the DataObject I have using SSViewer::set_theme(). Without it, SilverStripe throws an "[User Warning] None of these templates can be found in theme" error, and calling SSViewer::current_theme() in onAfterWrite() returns null. Any ideas on this behavior?

Go to Top