Archive for Jun. 2011

Best practice for using the PHP 5.3 Ternary operator

The Ternary Operator is very useful for short expressions.
I use it as sample very often to check GET or POST Variables, and give them in empty-cases a default-value.

Instead of making an examination of variables in an if statement, which is a lot of typing…

if(empty($_POST['action'])) {
    $varToUse = 'varIsEmpty';
} 
else {
    $varToUse = $_GET['varToUse'];
}

 
You can do the same with a Ternary Operator, with a much less of typing:

$varToUse = (!empty($_GET['varToUse'])) ? $_GET['varToUse'] : "varIsEmpty";

 
Since PHP 5.3 it is possible, to do this even faster. Just leave out the middle part of the ternary operator, as sample:

$varIsEmpty = (empty($_GET['varToUse'])) ?: false;

 
So you can save a much of typing, to take a simple check 😉

Create a Typo3 Menu/Navigation and include it in a Fluid-Template

TIPP: Um noch leichter TYPO3 Fluid-Templates erstellen, verwalten und wiederverwenden zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Notice: This Post is the fifth part of Create a complete Typo3 website by using the Fluid Template Engine

After creating a few more sites, includes some CSS-Files and designing the main frame, we will create a main-menu for our site.

1. Navigate into ‚WEB‘->’List‘, select the root-site within the tree and create a new sub-template by clicking on the New-Icon on your main-template. (show image)
2. Enter a name and save the new sub-template. (show image)
3. Be sure that the new sub-template is listed under the main-template and edit the main-template. (show image)
4. Open the Inlcudes-tab and search in the Include Basis Template Area for your sub-template, then include it (show image) and save the changes. (show image)
5. Open the new sub-template for creating the menu-TypoScript. (show image)
The mainNavi TypoScript could look like (show image) :

lib.mainNavi = HMENU
lib.mainNavi.entryLevel=0
lib.mainNavi.1 = TMENU
lib.mainNavi.1 {
  wrap = <ul id="mainNavi">|</ul>
  expAll = 0
  NO.allWrap = <li class="mainNaviItem">|</li>
  RO < .NO
  RO = 1
  CUR < .NO
  CUR = 1
  CUR.allWrap = <li class="mainNaviItemActive">|</li>
  ACT < .CUR
}

 

6.
Now we just have to include the mainNavi TypoScript objectpath into our Fluid-Template. Therefore we navigate into ‚FILE‘->’Filelist‘ and edit the fileadmin/templates/layouts/main.html and add the f:cObject on the needed position (show image) :

  <f:cObject typoscriptObjectPath="lib.mainNavi" />

 
Our Fluid-Template now looks like:

<div id="header">
  <div id="header-top-border"></div>
  <div id="header-area"></div>
  <f:cObject typoscriptObjectPath="lib.mainNavi" />
  <div id="header-line-dark"></div>
  <div id="header-line"></div>
</div>
<div id="content"><f:render section="content" /></div>
<div id="footer">
  <div id="footer-line"></div>
  <div id="footer-text">
    <div id="footer-text-left"></div>
    <div id="footer-text-right"></div>
  </div>
  <div id="footer-bottom-border"></div>
</div>

 
Notice: Don’t forget to clear the Typo3-Cache after editing the Fluid-Template. 😉

Include CSS files by using page.includeCSS under TypoScript

TIPP: Um noch leichter mit CSS unter Verwendung von LESS TYPO3 Fluid-Templates erstellen zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

CSS-Dateien über TYPOScript einzubinden ist sehr einfach. Verwende dazu einfach das page.includeCSS. Hier ein kleines Beispiel:

page.includeCSS { 
  file1 = fileadmin/templates/css/style.css 
  file1.title = Default CSS
  file1.media = screen
  
  file2 = fileadmin/templates/css/print.css 
  file2.title = Print CSS
  file2.media = print
}

Configure the Fluid TypoScript and create Backend-Templates

TIPP: Um noch leichter TYPO3 Fluid-Templates erstellen, verwalten und wiederverwenden zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Notice: This Post is the fourth part of Create a complete Typo3 website by using the Fluid Template Engine Before we can actually see the first result on the screen , we have to configure the TypoScript template. We do this again step by step 😉 1. Navigate to the ‚WEB‘->’Page‘ module and click on the Typo3-Icon in the frame next to the modules list („tree area“) and create a new site. (show image) 2. Enter a name for the Root-Site of your website (show image) 3. Navigate on the Access-tab and remove the Disable-Checkbox and save the changes subsequently. (show image) 4. Navigate into the ‚WEB‘->’Template‘ module, and create a new Template by clicking on ‚Create template for a site‘ (show image) 5. After that, click on ‚Edit the whole template record‘ (show image) 6. Enter a name for the Template and write the first TypoScript code, that will define the page (show image):

# Create and configure our site
page = PAGE
page.typeNum = 0
page.meta.DESCRIPTION = My Site
page.meta.KEYWORDS = Internet, Homepage, Typo3

7. Navigate to the Includes-tab and include the ‚CSS Styled Content‘ in the Include-static Area and then save the complete template. (show image) 8. Now we proceed to create the Backend-Templates. The Backend-Templates define the backend view, so the editor(s) can only see the content areas that are present in each template. In our default case, a Backend-Template with three columns and an alternative template with only one content area. Navigate to ‚WEB‘->’List‘ and click above the main-frame on the New-Icon, then click on ‚Backend Layout‘. (show image) 9. Enter a name for the Backend-Template and click the Edit-icon in the config-area to start the Wizard. (show image) 10. In the Wizard-Popup we create for example the Three-Column Layout. To achieve this start by clicking on the right side twice on the Plus-Icon. (show image 1, image 2) 11. Then click on each Layout-Column on the Edit-Icon an give the columns a name and a column number. (show image) In our case the columns will have the following column-numbers: Left=1, Center= 0, Right= 2. (show image)The resulting config for the threeColumnTemplate would look like this:

backend_layout {
  colCount = 3
  rowCount = 1
  rows {
    1 {
      columns {
        1 {
          name = leftColumn
          colPos = 1
        }
        2 {
          name = mainColumn
          colPos = 0
        }
        3 {
          name = rightColumn
          colPos = 2
        }
      }
    }
  }
}

The resulting config for a fullSize Template would look like this:

backend_layout {
  colCount = 1
  rowCount = 1
  rows {
    1 {
      columns {
        1 {
          name = mainColumn
          colPos = 0
        }
      }
    }
  }
}

Notice: After creating the Backend-Templates, look for the respective Template-ID. You will find the ID at the right bottom corner, and it would look like ‚Backend Layout [2]‘. My threeColumTemplate has the ID 2, the fullSizeTemplate the ID 3. We will need the respective ID when producing the required TypoScript code. (show image) 11. Now we will write the required TypoScript code for our site. For this purpose we navigate back to ‚WEB‘->’Template‘, click on our root-site and then edit the Setup. (show image) First of all, we will assign the Typo3-Columns with the Fluid-Templates: (show image)

# Create a Fluid Template
page.10 = FLUIDTEMPLATE
page.10 {
  # Set the Template Pathes
  partialRootPath = fileadmin/templates/partials/
  layoutRootPath = fileadmin/templates/layouts/
  variables {
    # Assign the main column with our {content}-destination
    content < styles.content.get
    # Assign the left column with our {content_left}-destination
    content_left < styles.content.get
    content_left.select.where = colPos = 1
    # Assign the right column with our {content_right}-destination
    content_right < styles.content.get
    content_right.select.where = colPos = 2
  }
}

After that we assign the Backend-Template, so that we can select it later when creating pages (show image):

# Assign the Template files with the Fluid Backend-Template
page.10.file.stdWrap.cObject = CASE
page.10.file.stdWrap.cObject {
  key.data = levelfield:-1, backend_layout_next_level, slide
  key.override.field = backend_layout

  # Set the default Template, our 3 column Template
  default = TEXT
  default.value = fileadmin/templates/threeColumn.html

  # Set also the first [2] Template, our 3 column Template
  2 = TEXT
  2.value = fileadmin/templates/threeColumn.html

  # Set a second [3] Template, our full size Template
  3 = TEXT
  3.value = fileadmin/templates/fullSize.html
}

12. At the end we want to create some pages to test the result of our configuration. We do this under ‚WEB‘->’Functions‘, as we will need several pages. Navigate to this module and click once again on the „New“-icon above the main frame. There we enter the name(s) of our new site(s) and click ‚Create pages‘. (show image) When the dialogue ‚You’re about to create many new pages. Are you sure you want to continue?‘ pops up, click ‚Yes‘. 13. After that we can modify our Root-Site to become a shortcut. Just click within the tree-area on the root-page icon and click edit. (show image) Select on the General-tab the Type ‚Shortcut‘ and the Shortcut Mode ‚First subpage of current page‘. (show image) 14. Now you only need to select the required Template for your pages and create page contents… and that’s about it. Edit for example the start-site and navigate to the Appearance-tab, there we select the threeColumnTemplate as Backend Layout (this page only) and Backend Layout (subpages of this page). (show image) A Backend-Page for our threeColumntemplate could now look like this: (show image) So now I’m going to create my Fluid HTML-Template in detail 🙂 I’ll be back soon and then we’ll see how to create some navigation menus and so on.. 😉 Read here the next step: Create a Typo3 Menu/Navigation and include it in a Fluid-Template

Create base HTML Fluid Templates for Typo3 4.5

TIPP: Um noch leichter TYPO3 Fluid-Templates erstellen, verwalten und wiederverwenden zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Notice: This Post is the third part of Creating a complete Typo3 website by using the Fluid Template Engine

Here we come to the next few steps for creating a base HTML Fluid Template, just do it point by point.
1. Navigate into the Typo3 Backend ‘FILE’->’Filelist’ Module and click on the ‘fileadmin’ tree node.
2. Click on New-Icon above the main-frame and create a folder named ‘templates’. Here you will store all your template files.
3. Navigate by using the file-tree into the new ‘templates’ directory, and create two directories named ‘layouts’ and ‘partials’. The ‘layouts’ directory is destined for the main templates, wherein the partial templates will be later included. The ‘partials’ directory will store the part templates, like the navigation, the subnavigation and so on.(show image)
4. Now, after we finish the creation of our directory structure, we create our first main-template file named ‘main.html’. Therefore we navigate into the ‘layouts’ directory and click again the New-Icon above the main frame, to create the file. (show image)
5. To edit our new template file, click on the file-icon on the left and click further on ‚Edit‘ (show image)
6. Within the editor your are now able to write the first template code. Just create a main-border-structure (show image), where are later your content templates are placed in:

<div id="header">header</div>
<div id="content"><f:render section="content" /></div>
<div id="footer">footer</div>

 

7. For our website we would create two seperate content templates. A first default content template that will have three columns, and a second template that will have the full size of the content. Therefore we create in the ‚templates‘ directory two files, a ‚threeColumn.html‘ for our default template and a ‚fullSize.html‘ as an alternative template. (show image)
Notice: If you have a fault by naming between the template files and the TypoScript, there are no references shown in the last column from the last sample image.

8. Now we will write the content templates. First, we edit the ‚threeColumn.html‘ template by click on his File-Icon. (show image)
The name of the f:layout must have the name of our in step 6 created template file, that means ‘main’. We could also create several content templates, that use different main-border-structures (as sample for style switches, or complete different website areas) that we assign to the f:layout name attribute.
The f:section defines that these templare is placed in the f:render section=”content” within the assigned main-border-structure template.

<f:layout name="main" />
<f:section name="content">
  <div id="content_left">
    <f:format.html>{content_left}</f:format.html>
  </div>
  <div id="content_main">
    <f:format.html>{content}</f:format.html>
  </div>
  <div id="content_right">
    <f:format.html>{content_right}</f:format.html>
  </div>
</f:section>

 

Our alternative content template could look like:

<f:layout name="main" />
<f:section name="content">
  <div id="content_main_full">
    <f:format.html>{content}</f:format.html>
  </div>
</f:section>

That’s it for now, from the HTML Fluid templates. 😉

Do you have understand every point?! If not, feel free to write me a comment 🙂

Read here the next step: Configure the Fluid TypoScript and create Backend-Templates

Import the ExtBase and the Fluid Template Engine into Typo3 4.5

TIPP: Um noch leichter TYPO3 Fluid-Templates erstellen, verwalten und wiederverwenden zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Notice: This Post are the second part of Create a complete Typo3 website by using the Fluid Template Engine

To be able to use Fluid within Typo3 4.5, we must install the Extension named ‚fluid‘. ‚fluid‘ itself is dependent on the Extension ‚extbase‘, so we must install the ‚extbase‘ Extension first.

In order for that we have to do the following steps within the Typo3 Backend:
1. Navigate to „ADMIN TOOLS‘ -> ‚Extension Manager‘ (show image)
2. Navigate in the topmost select box to ‚Import Extensions‘
3. Search about ‚extbase‘ (show image)
4. Install the ‚extbase‘ by clicking on the brick stone (show image)
5. In the next step, click ‚make all updates‘

So, if you become the message ‚The extension „extbase“ has been installed.‘ we can continue with the fluid extension:
7. Navigate once again in the topmost select box to ‚Import Extensions‘
8. Search about ‚fluid‘ (show image)
9. Install the ‚fluid‘ by clicking on the brick stone (show image)

That’s it. If you become again the message ‚The extension „fluid“ has been installed.‘ you have successfully integrate the Fluid Template Engine. 😉

Read here the next step: Create fluid base templates

Create a complete Typo3 website by using the Fluid Template Engine

TIPP: Um noch leichter TYPO3 Fluid-Templates erstellen, verwalten und wiederverwenden zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Heute möchte ich einmal die neue Template-Engine Fluid ausprobieren, welche die Standard Template-Engine im Typo3 5 werden soll.

Aber warum Fluid? In der fünften Version von Typo3 wird noch mehr Trennung zwischen Logik und Darstellung angestrebt, dafür haben die Typo3-Entwickler das System von Grund auf überarbeitet.
So wird bspw. ein Model-View-Controller-System integriert das viel mehr leisten kann, als das relativ statisches System, wie das der herkömmliche Sub-Templates und Marker.

Da ich eh gerade eine komplett neue Typo3 Website zu entwickeln habe, wollten wir alle zu erledigende Punkte von Anfang an durchführen. 😉
Als erstes teilen wir dieses Projekt in ein paar Teilprojekte:

 
Wir beginnen mit dem Download des aktuellen Typo3 Quellcodes von der Seite http://typo3.org/download/, entpacken den Quellcode dann und laden Ihn auf den Ziel-Server.

Wenn der Upload abgeschlossen ist, erstellen wir eine Datei namens ‘ENABLE_INSTALL_TOOL’ und kopieren diese ebenfalls auf den Webspace in das Verzeichnis ‘typo3conf’.

Danach navigiere mit einem Browser zu Typo3-Installtool:

http://your-domain.com/typo3/install/index.php

 
Die erste Nachricht die ich erhalte ist:

Error
TYPO3 Fatal Error: /var/www/virtual/***/dev/htdocs/typo3conf/localconf.php is not writable!

 
Ok…Ich gebe dieser Datei ein wenig mehr Rechte und probiere es noch einmal 😉

Des weiteren passe ich folgend noch die Rechte der Verzeichnisse ‚typo3conf‘ und ‚typo3temp‘ an.
Jetzt sollte das Installtool angezeigt werden und wir können die folgenden Schritte durchführen:

 
1. Gebe die Datenbank-Zugangsdaten ein

 
2. Erstelle oder wähle eine Datenbank aus

 
3. Wenn das ‚fileadmin‘ und das ‚uploads‘ Verzeichnis noch nicht die erforderlichen Zugriffsrechte hat, setze diese

 
4. Wähle das leere Paket, weil wir diese Standard-Konfiguration nicht brauchen

 

Das war’s, schon haben wir unsere Typo3-Installation abgeschlossen

 

Zu Einloggen in das Typo3 Backend navigiere einfach zur folgenden Seite:

http://your-domain.com/typo3/


 
Dort kann man sich dann mit dem Standard-Login anmelden, der wie folgt lautet:
Name: admin
Password: password

Jetzt wo du eingeloggt bist sollte die erste Aktion die Änderung des Passworts sein. Danach vergesse aber auch nicht, das Passwort des Installtools zu verändern 😉

Lese hier wie es weiter geht: ExtBase Extension und die Fluid Template Engine in Typo3 4.5 integrieren

Create a webcam face detection within OpenLaszlo by using ActionScript3

Today i found a smart script for a webcam face detection on www.quasimondo.com.
Now i will try to do this within OpenLaszlo, thus post based also on this sample.. 😉

Click here for a quick demo 😉

First of all, we have to download the sourcecode in the Marilena_mod10.zip from www.quasimondo.com and extract it.

To be able to use the source code, we have to compile the ActionScript files into a SWC file. Therefore we need a Flex SDK. If you not already installed it, read here how do you do this under Ubuntu Linux.
When you have the Flex SDK available, navigate into the src directory from the extracted sourcecode and compile the SWC with the following action:

compc -source-path ./ -include-sources ./ -optimize -output ../faceDetection.swc

 
The result is the faceDetection.swc file, which must now be provided to OpenLaszlo. How you can do this, read it here in detail. In short, copy it into your flexlib directory within your OpenLaszlo WEB-INF directory.

Now you can import the required base libaries into a self implemented class by using a passthrough tag:

<class name="faceDetector" width="480" height="640">
	
	<switch>
		<unless property="$as3">
			<handler name="oninit">
			<![CDATA[
				Debug.error("ActionScript 3 required");
			]]>
			</handler>				
		</unless>
		<otherwise>
			<passthrough>
				import com.quasimondo.bitmapdata.CameraBitmap;
				import jp.maaash.ObjectDetection.ObjectDetector;
				import jp.maaash.ObjectDetection.ObjectDetectorEvent;
				import jp.maaash.ObjectDetection.ObjectDetectorOptions;
				...
			</passthrough>

			...

 
The first great step is now done and we will further implement a complete class for using the face detection, so that we in future just have include a tag for using it.
We will do this also on our base sample. The result is a port to OpenLaszlo of these, with just a few differences:

<!---	Object Variables -->
<attribute name="detector" type="expression"/>
<attribute name="camera" type="expression"/>
<attribute name="faceRectContainer" type="expression"/>
<attribute name="detectionMap" type="expression"/>
<attribute name="drawMatrix" type="expression"/>

<!---	Scale factor of the image -->
<attribute name="scaleFactor" type="number" value="4"/>

<!---	Is currently a face detected?! -->
<attribute name="faceDetected" type="boolean" value="false" />
	
<!---	Weight of the face rect -->
<attribute name="rectLineWeight" type="number" value="2"/>

<!---	Starting the initiation -->
<handler name="oninit">
<![CDATA[

	if(this.scaleFactor==0) {
		Debug.error("scaleFactor must be greater 0");
	}

	this.initUI();
	this.initDetector();
]]>
</handler>				

<!---	Init the UI -->
<method name="initUI" args="" returns="void">
<![CDATA[
	var view = new Sprite();
	this.getDisplayObject().addChild(view);

	this.camera = new CameraBitmap(this.width, this.height, 15);
	this.camera.addEventListener(Event.RENDER, this.cameraReadyHandler);
	view.addChild( new Bitmap(this.camera.bitmapData) );
			
	this.detectionMap = new BitmapData(this.width/this.scaleFactor, this.height/this.scaleFactor, false, 0);
	this.drawMatrix = new Matrix(1/this.scaleFactor, 0, 0, 1/this.scaleFactor);
		
	this.faceRectContainer = new Sprite();
	view.addChild(this.faceRectContainer);
]]>
</method>


<!---	Is called when the camera is ready -->
<method name="cameraReadyHandler" args="event:Event" returns="void">
<![CDATA[
	this.detectionMap.draw(this.camera.bitmapData, this.drawMatrix, null, "normal", null, true);
	this.detector.detect(this.detectionMap);
]]>
</method>


<!---	Init the detector -->
<method name="initDetector" args="" returns="void">
<![CDATA[

	// Creat a new ObjectDetector
	this.detector = new ObjectDetector();
	
	// ..and give them the required options 
	var options:ObjectDetectorOptions = new ObjectDetectorOptions();
	options.min_size  = 30;
	this.detector.options = options;
	this.detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, this.detectionHandler);
]]>
</method>


<!---	Is called at every detection -->
<method name="detectionHandler" args="e:ObjectDetectorEvent" returns="void">
<![CDATA[				

	var g :Graphics = this.faceRectContainer.graphics;
	g.clear();
	if(e.rects) {
		g.lineStyle(this.rectLineWeight);
		e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
			
			// Set face detected
			if(!faceDetector.faceDetected) faceDetector.setAttribute("faceDetected", true);
										
			// Timer when face deteced is reset
			if(typeof this.resetDetectionDelegate == "undefined") {
				this.resetDetectionDelegate = new LzDelegate(faceDetector, "resetDetection");
				lz.Timer.addTimer(this.resetDetectionDelegate, 500);
			}
			else {
				lz.Timer.resetTimer(this.resetDetectionDelegate, 500);
			}
			g.drawRect( r.x * faceDetector.scaleFactor, r.y * faceDetector.scaleFactor, r.width * faceDetector.scaleFactor, r.height * faceDetector.scaleFactor );
		});
	}
						
]]>
</method>

<!---	Is called when no face is anymore detected -->
<method name="resetDetection" args="something" returns="void">
<![CDATA[
	if(this.faceDetected) this.setAttribute("faceDetected", false);
]]>
</method>	

 
After finishing the impĺementation of the face detection class, just have to include the new class and place the tag on the required target. We do the as sample in the source code from the snapShot article i have written some days ago:

<simplelayout axis="y" spacing="0" />
<view name="videoView" width="$once{canvas.imageWidth*2}" height="$once{canvas.imageHeight}">
	<simplelayout axis="x" spacing="0" />
	<view name="videoView" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
		<faceDetector name="faceDetector" id="faceDetector" scaleFactor="2" rectLineWeight="1"
					  width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
			<handler name="onfaceDetected">
			<![CDATA[
				Debug.write(this, "onfaceDetected("+this.faceDetected+")")
			]]>
			</handler>
		</faceDetector>
	</view>
	
	<view name="snapshot" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}" />
</view>
			
<view layout="axis: x; spacing:0">
	<button text="Take a snapshot" onclick="canvas.takeSnapshot();" width="$once{canvas.imageWidth}" enabled="${faceDetector.faceDetected}" />
	<button text="Save snapshot" onclick="canvas.saveImage();" width="$once{canvas.imageWidth}" enabled="${canvas.shotAvailable}" />		
</view>	

 
How you see, we just exchange the videoview-tag with the faceDetection-tag, and add the faceDetected-constraint to the enabled attribute of the snapshot button.
This was very easy, or?! And the result pretty nice.. 🙂
Thanks in this place to Mario Klingemann and all other they have optimize and work on this code.

Click here for a demo 😉

Sourcecode: OpenLaszlo - FaceDetection.zip (1621)

If you found some bugs or have some Tips, please contact me.

Read and write files from local filesystem with OpenLaszlo by using ActionScript3

Today i will try to read and write local files from a local storage. After a few searches with google, i found several similar samples. Now i integrate these with the sample from www.mikechambers.com within my OpenLaszlo code. For both, reading and writing files, we need the usual main structure, with a runtime switch and passthrough for the actionscript libraries.

Click here for a quick demo 😉

At first, we have look at the reading of a file. For that we create a few small functions, some of them act as an event handler.
 
1. The function that invokes the loading. Here we instantiate a FileReference object, register the required eventlistener and open the browser window for selecting a file. Further you will find here the fileFilterValue variable, within you are able to restrict the allowed file types for selecting.

<!---	called when the user clicks the load file button -->
<method name="loadFile" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for when they select a file
	this.fr.addEventListener(Event.SELECT, this.onFileSelect);

	// listen for when then cancel out of the browse dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// open a native browse dialog that filters for text files
	this.fr.browse([new FileFilter(this.fileFilterValue, this.fileFilterValue)]);
								
]]>
</method>

 
2. The function that is called, when the user has selected a file. Here we register two further eventlistener, the onLoadError and onLoadComplete eventlistener, and starting the loading progress.

<!---	called when the user selects a file this.from the browse dialog -->
<method name="onFileSelect" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onFileSelect()");

	// listen for when the file has loaded
	this.fr.addEventListener(Event.COMPLETE, this.onLoadComplete);

	// listen for any errors reading the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onLoadError);

	// load the content of the file
	this.fr.load();						
]]>
</method>

 
3. The onLoadComplete function is called, when the file is transferred to the flash application. Here we receive the file contents and clean up the FileReference instance.

<!---	called when the file has completed loading -->
<method name="onLoadComplete" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onLoadComplete()");

	// get the data this.from the file as a ByteArray
	var data:ByteArray = this.fr.data;

	// Get the file content
	this.setAttribute("fileContent", data.readUTFBytes(data.bytesAvailable));
	
	// clean up the FileReference instance	
	this.fr = null;					
]]>
</method>

 
4. The onLoadError function will be called in case of a transfer-error.

<!---	called if an error occurs while loading the file -->
<method name="onLoadError" args="e:IOErrorEvent" returns="void">
<![CDATA[
	Debug.error(this, "->onLoadError(): " + e.text);					
]]>
</method>

 
5. The onCancel function is used of both, the reading and writing action, and is just called when the user aborts the file selecting browser window or file saving browser window.

<!---	called if the user cancels out of the file save dialog -->
<method name="onCancel" args="e:Event">
<![CDATA[
	Debug.write(this, "->onCancel()");
	this.fr = null;						
]]>
</method>

 
For the writing of files you need just the three following functions, some of that are also act as a event handler.

1. The saveFile function invokes the saving action. Here we instantiate again a FileReference object, register the requiered eventlistener and open the browser window for selecting the destination for the file.

<!---	called when the user clicks the save file button -->
<method name="saveFile" args="fileContent ='', fileName ='test.txt'" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for the file has been saved
	this.fr.addEventListener(Event.COMPLETE, this.onFileSave);

	// listen for when then cancel out of the save dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// listen for any errors that occur while writing the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onSaveError);

	// open a native save file dialog, using the default file name
	this.fr.save(fileContent, fileName);
								
]]>
</method>

 
2. The onSaveError function will be called in case of an error while saving.

<!---	called if an error occurs while saving the file -->
<method name="onSaveError" args="e:IOErrorEvent">
<![CDATA[
	Debug.write(this, "->onSaveError(): ", e.text);
	this.fr = null;								
]]>
</method>				

 
3. The onFileSave function will be called when the file is successfully saved.

<!---	called once the file has been saved -->
<method name="onFileSave" args="e:Event">
<![CDATA[
	Debug.write(this, "->onFileSave()");
	this.fr = null;							
]]>
</method>

 
All these functions are capsuled in a class, that is extends the node object.

<class name="readAndWriteFileReference" extends="node">

	<passthrough>
		import flash.net.FileReference;
		import flash.net.FileFilter;
		import flash.events.IOErrorEvent;
		import flash.events.Event;
		import flash.utils.ByteArray;
	</passthrough>

	<!---	FileReference -->
	<attribute name="fr" type="expression" />

	...

Is this class implemented, you will only need to create an instance of that and bind an eventlistener with it. Now you are able to load and write file contents, just by calling the load and save function. A canvas could look like:

<canvas name="readAndWriteFileReference" width="800" height="550">
	
	<include href="./readAndWriteFileReference.lzx" />
		
	<attribute name="columnWidth" type="number" value="400"/>
	<attribute name="textHeight" type="number" value="${canvas.height-canvas.buttonBar.height}"/>
	
	<readAndWriteFileReference name="readAndWriteFile">
		<handler name="onfileContent">
		<![CDATA[				
			canvas.textView.textLoad.setAttribute("text", this.fileContent);
		]]>
		</handler>				
	</readAndWriteFileReference>		
		
	<simplelayout axis="y" spacing="0" />
	<view name="textView" width="$once{canvas.columnWidth*2}" height="$once{canvas.textHeight}">
		<simplelayout axis="x" spacing="0" />
		<edittext name="textSave" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
		<edittext name="textLoad" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
	</view>
				
	<view name="buttonBar" layout="axis: x; spacing:0" height="27">
		<button text="Save file" onclick="canvas.readAndWriteFile.saveFile(canvas.textView.textSave.text, 'test.txt');" width="$once{canvas.columnWidth}" />
		<button text="Load file" onclick="canvas.readAndWriteFile.loadFile();" width="$once{canvas.columnWidth}" />		
	</view>	
				
</canvas>

And now, happy loading and saving 😉

Click here for a quick demo 😉

Sourcecode: OpenLaszlo - ReadAndWriteFileReference.zip (1084)

If you found some bugs or have some Tips, please contact me.

How to track OpenLaszlo Websites with Google-Analytics

Some time ago, i had to integrate a google analytics tracking into a OpenLaszlo website, compiled to flash or DHTML/HTML5.

How to do this!?
At first, we need a google account and additional a google analytics tracking code, registrated for the site to track.
After a little bit of searching, i have a summary of collected script snippets that we need.

In the HTML file, that’s embed our OpenLaszlo Website, we have to integrate the google analytics tracking code with a little JavaScript snippet:

<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-XXXXXXXX-1']);
	_gaq.push(['_setDomainName', 'none']);
	_gaq.push(['_setAllowLinker', true]);
	_gaq.push(['_trackPageview']);

	(function() {
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	})();
</script>

After that, it is necessary to call a google analytics javascript function at every site switch. A call could be look like:

<method name="switchSite" args="menu='startsite', site='startsite', siteType='site', content='undefined'">
<![CDATA[
	// Google-Analytics
	lz.Browser.callJS("_gaq.push(['_trackPageview', '/"+menu+"/"+site+"/"+siteType+"/"+content+".html'])");
	...

If now a visitor navigate through your site, the _gaq.push function sends a page call like ‚/menu/site/siteType/content.html‘ to google analytics. So you’re able to follow your visitors, see which pages they find interessting or where they exit your page… 😉