<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		
		<title>typo3-media.com: Latest TYPO3 Blog News</title>
		<link>http://www.typo3-media.com/</link>
		<description>Latest News of the TYPO3 Blog</description>
		<language>en</language>
		<image>
			<title>typo3-media.com: Latest TYPO3 Blog News</title>
			<url>http://www.typo3-media.com/fileadmin/tt_news_article.gif</url>
			<link>http://www.typo3-media.com/</link>
			<width></width>
			<height></height>
			<description>Latest News of the TYPO3 Blog</description>
		</image>
		<generator>TYPO3 - get.content.right</generator>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		
		
		
		<lastBuildDate>Sun, 23 May 2010 13:41:00 +0200</lastBuildDate>
		
		
		<item>
			<title>Dependency Injection Container - TYPO3 4.3</title>
			<link>http://www.typo3-media.com/blog/dependency-injection-container-typo3.html</link>
			<description>


(updated on 3.6.2010)
Today I uploaded a initial version of the &quot;container&quot;...</description>
			<content:encoded><![CDATA[<b></b>
<b></b>
<b></b>
(updated on 3.6.2010)
Today I uploaded a initial version of the &quot;container&quot; extension to forge. This extension has a simple Dependency Injection Container with a Feature subset of the FLOW3 DI Framework - and some special TYPO3 4.x Features.
<h2>Dependency Injection</h2>
There are a lot of explanations on different websites (e.g. <link http://de.wikipedia.org/wiki/Dependency_Injection _blank external-link>Wikipedia</link>, <link http://flow3.typo3.org/documentation/manuals/flow3/flow3.objectframework/ _blank external-link>FLOW3</link>). <br />In general DI is a Pattern that simply means, that  a class that requires other objects for its work, does not instanciate these objects itself: Instead the class asks for this dependencies. <br />The easiest way of doing this, is to require this objects in the constructor:<br /><i>public function __construct(Tx_Blog_Blog $blog)</i><br />This is called &quot;Constructor Injection&quot; and should be used for mandatory dependencies. 
Another way of asking for dependencies is in using setter methods:<br /><i>public function setBlog(Tx_Blog_Blog $blog)<br /></i>This is called &quot;setter injection&quot;.
Other Objects are not the only dependencies a class could have, there are also configurations or other settings a class would need. Therefore a class using DI would also expect this settings to be injected from the outside.
Its a good practice that a class does not ask for a concrete class but for a Interface or an abstract class, because that gives the class a greater usage flexibility.
Using DI is essential for writing good Unit-Test, because than it is easy to test the class in isolation by Injecting Mocks, Stubs or Fakeobjects to the class.
<h2>DI Container</h2>
Using DI does not require a container, however it is a common pattern when it comes to Dependency Injection. A container knows how to build instances of a class. For example this is a container:
<pre>class myContainer {<br /><br />   public function getDomainBlog() {<br />     return new Tx_Blog_Domain_Blog(new Tx_Blog_System_Persitence('user','password'));<br />   }<br /><br />   public function getDomainWebsite() {<br />     return new TX_Blog_Domain_Website($this-&gt;getDomainBlog());<br />   }<br /><br />}</pre>
Of course a typical DI Container embedded in a framework is not hardcoded, but detects and resolves dependencys of classes automatically.
<h2>Container for TYPO3 4.3</h2>
As said you can find a DI container for TYPO3 4.3 here:
<b><link https://svn.typo3.org/TYPO3v4/Extensions/container>https://svn.typo3.org/TYPO3v4/Extensions/container</link> </b>
It offers the following features:
<ul><li>Constructor injection detection</li><li>Setter injection detection via annotation or &quot;inject*&quot; Name</li><li>Settings injection for extension settings (ext_conf_template)</li><li>Singleton support via &quot;t3lib_Singleton&quot;</li><li>Support for manual registration of implementations</li><li>XClass awareness&nbsp;</li><li>Able to resolve cyclic dependencys with setter Injection</li><li>First and Second Level reflection cache for the matter of speed</li></ul>

<h3>Introduction</h3>
Instead of calling new or &quot;makeInstance&quot; to get the object you need, you expect the object instance to be injected by the outside. Therefore you will &quot;ask&quot; for the Objects you need in the constructor of your class or you expect them to be setted by some setter methods.<br /><br />For initial startup you can request a container with:<br /><br /><i>Tx_Container_Container::getContainer()</i>

<h3>Constructor Injection</h3>
You just have to write your constructor and you will get the dependencys:
<pre>class tx_container_tests_amixed_string {<br />     public function __construct(tx_container_tests_b $b, tx_container_tests_c $c, $myvalue='test') {<br />        <br />     }   <br /> }</pre>
Use this to get Dependencys that are required for your class to do the job.<br /><br /><br />
<h3>Setter Injection</h3>
Can be used by annotation &quot;@inject&quot; or by naming a method &quot;inject*&quot;:
<pre>class tx_container_tests_injectmethods {<br />    public $b;<br />    public $bchild;<br />   <br />    public function injectClassB(tx_container_tests_b $o) {<br />        $this-&gt;b = $o;<br />    }<br />   <br />    /**<br />     * @inject<br />     * @param tx_container_tests_b $o<br />     */<br />    public function setClassBChild(tx_container_tests_b_child $o) {<br />        $this-&gt;bchild = $o;<br />    }<br />}</pre>
<h3>Settings Injection</h3>
You can also inject the ext_conf_template Settings by simple using a method &quot;injectExtensionSettings&quot;:<br /><br /><i>&nbsp;public function injectExtensionSettings(array $settings) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;settings = $settings;<br />&nbsp;&nbsp;&nbsp; }</i>
<h3>Singletons</h3>
Per default all objects are prototypes, if you want them to be singletons, just implememt t3lib_Singleton<br /><br /><i>&nbsp;class tx_container_tests_singleton implements t3lib_Singleton {<br />&nbsp;&nbsp;&nbsp; <br />}</i>
<h3>Interfaces and Abstract Classes</h3>
The container is not aware of the available implementations of and interface or abstract class. 
Therefore you need to let him know in the ext_localconf.php:<br /><br /><i>Tx_Container_Container::getContainer()-&gt;registerImplementation('tx_container_tests_someinterface', 'tx_container_tests_someimplementation');</i>
<br /><br />
<h3>What if I need to call new?</h3>
You need a container if you need to create new objects (e.g. in a factory), normally very few classes needs to do this, so only very few classes actually need to know the container.<br /><br />You should call a container to give you a new object if you need to. The container is aware of building the object with the dependencies.<br /><br />If your class needs a container you should inject it (see above) like other dependencies.
<h2>Upcoming</h2>
There are some new features planned:
<ul><li>Extension context aware dependency resolving</li><li>TypoScript Configuration Injection</li></ul>
<b></b>]]></content:encoded>
			<category>development</category>
			
			
			<pubDate>Sun, 23 May 2010 13:41:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>Zend Studio and Unit Tests</title>
			<link>http://www.typo3-media.com/blog/zend-studio-unit-tests.html</link>
			<description>I just want to share how the Zend-Studio Feature &quot;Run as &gt; PHP Unittest&quot; can be...</description>
			<content:encoded><![CDATA[I just want to share how the Zend-Studio Feature &quot;Run as &gt; PHP Unittest&quot; can be used.&nbsp;
<h3>1 Include PHPUnit</h3>
Zend Studio ships with PHPUnit 3.x and you can set the PHPUnit library as Include Path.
Therefore use a right click on your project and select &quot;Include Path&quot; &gt; &quot;Configure Include Path&quot;. Then select the Tab &quot;Libraries&quot; in the dialog window. When you click the button &quot;Add Library&quot; you should see the &quot;PHPUnit 3.x&quot; Library.
<img clickenlarge="1" src="uploads/RTEmagicC_zend-test.jpg.jpg" width="535" height="375" alt="" />
Maybe its required to build your project again. (Project &gt; Clean)
<h3>2 Run your Tests in Zend Studio</h3>
If everything went well you should be able to open one of your Test files and see the correct Outline as well as a nice code completion for your Tests:
<ul><li>for the outline right click on the class-name in the editor and select &quot;Open Type Hierarchy&quot;. You should see the PHPUnit classes somewhere there.</li><li>For autosuggestion just click in one of your testmethods and start typing &quot;$this-&gt;&quot; now you should see all assert* methods as suggestion.</li></ul>
If that works you should be able to select &quot;Run as &gt; PHPUnit Test&quot; and see the testresults as well as a code coverage.
<img src="uploads/RTEmagicC_zend-test1a.jpg.jpg" width="529" height="317" alt="" />&nbsp;
<img src="uploads/RTEmagicC_zend-test1b.jpg.jpg" width="527" height="365" alt="" />

<img src="uploads/RTEmagicC_zend-test2.jpg.jpg" width="526" height="289" alt="" />
There is also a nice feature when you want to start writing a new test: you could use &quot;New &gt; PHP Unit TestCase&quot; and in the dialog you can enter the name of the class you are going to test. Zend Studio will create a TestCase class with dummies for all methods in the class you are going to test.

]]></content:encoded>
			<category>development</category>
			
			
			<pubDate>Sun, 28 Feb 2010 22:24:00 +0100</pubDate>
			
		</item>
		
		<item>
			<title>IPC Talks</title>
			<link>http://www.typo3-media.com/blog/ipc-talks-metrics.html</link>
			<description>Some links to interesting talks on the #IPC09</description>
			<content:encoded><![CDATA[The IPC09 was realy inspiring. Here some links to the slides:<br />
<ul><li>Nice slides explaining software metrics: http://manuel-pichler.de/archives/65-Softwaremetriken-verstehen-und-nutzen.html</li><li>The state of QA Tools for PHP: http://www.slideshare.net/sebastian_bergmann/the-state-of-quality-assurance-tools-for-php </li><li>http://www.slideshare.net/sebastian_bergmann/analysing-php-code</li><li>http://www.slideshare.net/sebastian_bergmann/continuous-inspection-and-integration-of-php-projects</li><li>http://www.slideshare.net/sebastian_bergmann/cool-objects-sleep-on-the-couch</li><li>Stress free Deloyment: http://akrabat.com/talks/#sfd</li><li><link http://kore-nordmann.de/talks/09_11_ipc_charsets_encodings.pdf>Charsets &amp; Encodings</link> (via http://kore-nordmann.de/portfolio.html)</li><li><link http://kore-nordmann.de/talks/09_11_ipc_couchdb.pdf>CouchDB, PHPillow &amp; PHP</link> (via http://kore-nordmann.de/portfolio.html)</li></ul>]]></content:encoded>
			<category>news</category>
			
			
			<pubDate>Sun, 22 Nov 2009 14:06:00 +0100</pubDate>
			
		</item>
		
		<item>
			<title>Catching browser back</title>
			<link>http://www.typo3-media.com/blog/catching-browser-back.html</link>
			<description>Today we searched for a solution to catch the browser back button.
The problem is, that the...</description>
			<content:encoded><![CDATA[Today we searched for a solution to catch the browser back button.
The problem is, that the browser per default has no way to catch the back and forward actions. Also the browser does not allow to modify the browser history.
But there are two things you can do:
<ol><li>call location.replace to load a diffrent url and replace the history of the current page.</li><li>add a hash (like its used for anchor links) to the url with location.hash='hash'</li></ol>
Basically the idea was to add a hash when the page is loaded. When the user then clicks the browser back button, the url just changes back to the url without the hash. Then all you need to do is to detect that url change and react like you want (e.g. set a new location.href)
<br />Here is the <link fileadmin/files/examples/history.html _blank>example</link>

<pre>$(function(){<br />			<br />	var lastjavascripthash='';<br />			<br />	//if the current url has a hash on dom ready - than the user loads this url directly in browser<br />	if (location.hash) {<br />		alert('you navigated to this link using the browser address!');<br />		lastjavascripthash=location.hash;<br />	}<br />	//just add a dummy hash:<br />	lastjavascripthash=location.hash='#loaded';	<br />	<br />	//optional - when clicking the links append the hash to the url:<br />	$('#tostep1').click(function() {<br />			lastjavascripthash=location.hash='#step1';					<br />		});		<br />	<br />	//do regular check if the hash in the location still fits the last hash that was set via a valid javascript call<br />	// if not it means someone else modified the hash - typically the browser back<br />	setInterval(function() {<br />			if (location.hash != lastjavascripthash) {<br />				alert('you navigated to this link using the browser back!');<br />				lastjavascripthash=location.hash;<br />			}<br />		}, 300);<br />}</pre>
Since the loaction.hash declaration is not interpreted by all browsers, a better way is to use one of the history javascript plugins.
This is the case in this modified <link fileadmin/files/examples/history2.html>example</link><br />(using jquery.history.js Links:   http://plugins.jquery.com/project/history; http://nix.lv/history/)<link fileadmin/files/examples/history2.html _blank><br /><br /></link>
<pre>var browserback = {<br />        lastjavascripthash: '',<br /><br />        setLastHash: function(hash) {            <br />            browserback.lastjavascripthash=hash;<br />        },    <br />        historyChangeHandler: function(hash) {<br />        	if (browserback.lastjavascripthash != hash) {<br />        		alert('you propably used browser back!');<br />        		browserback.setLastHash(hash);<br />        	}		<br />        },<br /><br />        disableBrowserBack: function() {<br />        	$.history.init(this.historyChangeHandler);<br />        	var hash=new Date().getTime()+ Math.floor(Math.random()*1000)<br />        	browserback.setLastHash(hash);<br />        	$.history.load(hash);		<br />        }<br />}<br /><br /><br />$(function(){			<br />	browserback.disableBrowserBack();<br />}<br /> </pre>]]></content:encoded>
			<category>news</category>
			
			
			<pubDate>Wed, 21 Oct 2009 21:44:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>Automatic testing with Selenium</title>
			<link>http://www.typo3-media.com/blog/testing-selenium-qa.html</link>
			<description>Quality Assurance: Automatic testing of web applications with Selenium
 
Introduction
Every...</description>
			<content:encoded><![CDATA[<h1><span lang="EN-US">Quality Assurance: Automatic testing of web applications with Selenium</span></h1>
<p class="MsoNormal">&nbsp;</p>
<h2><span lang="EN-US">Introduction</span></h2>
<p class="MsoNormal">Every web application needs proper testing to ensure that it works like expected. Therefore you should have a set of test-cases, that verify the functionality of the application. For large applications you often need a separate test planning phase, where many test cases are designed – there can be &nbsp;many hundreds of them. </p>
<p class="MsoNormal">A proper design of stable and useful test-cases is required – but that’s not part of this article. But at least we can say that:</p>
<ul><li><span style="font-family: Symbol;"></span>Most of the test-cases should focus on a single feature or requirement</li><li><span style="font-family: Symbol;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span>In order to keep the overview test cases should have speaking names</li><li><span style="font-family: Symbol;"></span>test-cases should be grouped in test suites</li></ul>
<p class="MsoNormal">Before a new release of a website or web-application is released, the test cases should be executed to ensure the quality of the application. For business critical websites, this phase is even more important! It’s obvious that this process can take a lot of time and effort. If you want to keep up with your competitors you do not only need a robust and high quality application - but you also need a short release cycles that adds new innovations and features to your website. </p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The key to solve both requirements, short release cycles and proper quality assurance, is <b>automated frontend testing</b>. Automated tests for web applications are furthermore also very useful in agile development processes: In an optimal way they can be used together with continuous integration, to provide early feedback for changes in the source.</p>
<h2><span lang="EN-US">Getting started with Selenium</span></h2>
<p class="MsoNormal">Selenium is a suite of tools to automate web application testing across many platforms. The easiest way to start with it, is to <link http://release.openqa.org/selenium-ide/1.0.2/selenium-ide-1.0.2.xpi>install the Firefox add-on Selenium IDE.</link> With this IDE you have an easy way to record and edit your test cases. </p>
<p class="MsoNormal"><img src="uploads/RTEmagicC_selenium_ide.jpg.jpg" height="206" width="368" alt="" /></p>
<p class="MsoNormal">Let’s start with a simple test:</p>
<p class="MsoListParagraphCxSpFirst">1)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Open your IDE and select &quot;new&quot; &gt; &quot;testsuite&quot;. A new test suite is created, with a first empty test-case.</p>
<p class="MsoListParagraphCxSpMiddle">2)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Now just click the red record button and switch to your browser window.</p>
<p class="MsoListParagraphCxSpMiddle">3)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Open <link http://www.google.de>www.google.de</link></p>
<p class="MsoListParagraphCxSpMiddle">4)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Do a search for &quot;typo3&quot;.</p>
<p class="MsoListParagraphCxSpMiddle">5)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>On the result page highlight the website &quot;typo3.org&quot; and click the left mouse button. Select &quot;assertTextPresent&quot; from the context menu. (screenshot)</p>
<p class="MsoListParagraphCxSpMiddle">6)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Now save your test and give it the name &quot;can search for typo3.org&quot;. </p>
<p class="MsoListParagraphCxSpLast">7)<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Save your test suite and give it the name &quot;google search&quot;.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Every time you want to check if google still can search for typo3 and returns the expected result &quot;typo3.org&quot; you can run this test case. Do this by clicking the play button in the IDE.</p>
<h2><span><br /></span><span lang="EN-US"></span></h2>
<h2><span lang="EN-US">Speaking Selenese</span></h2>
<p class="MsoNormal">If you have a closer look at your test case, you see that it consist of a list of commands. The Selenium IDE records your actions in the browser and adds the correct commands to the test-case. All commands support one or two parameters. </p>
<p class="MsoNormal">In fact the commands create a testing language - and they are often referred to as &quot;<b>selenese</b>&quot;. For having robust test cases, it’s often necessary to tune your test case commands after recording them with the Selenium IDE. Robust means that the test cases are stable against small changes in the markup. Also while running a test case, selenium executes the commands faster than a human&nbsp; - that might cause unexpected behavior, of course a test case or the application should be insensible against this too.</p>
<p class="MsoNormal">Therefore let’s have a closer look at the commands. In general commands are divided into actions, accessors and assertions. As mentioned commands can have 1 or 2 parameters. In most cases the first parameter is a locator to a specific UI element and the second parameter is a text pattern.</p>
<p class="MsoNormal"><b>Actions</b> do something in the browser, like clicking (command <i>click</i>) a link or selecting some Selectbox entry (command <i>select</i>). Mostly it is necessary that your test-case will wait after an action, until the web application is ready doing something. Most of the action commands can be used with the suffix &quot;<b>AndWait</b>&quot;. That means that Selenium waits till the server has send back the response for the action. (See below for an example how to deal with ajax)</p>
<p class="MsoNormal"><b>Assertions</b> are mainly the <i>verification*</i> or <i>assert*</i> commands (Like <i>verifyTextPresent</i>). The difference between assert and verify is, that a failed assert ends the test case and a verification only marks the test case as failed - but the following commands are still executed.</p>
<h3><span lang="EN-US">Simple Selenium test case example</span></h3>
<p class="MsoNormal">Let’s have a look at a simple test-case example</p>
<table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0" height="133" width="423">  <tbody><tr style="height: 12.7pt;">   <td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">1</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">open</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">/download/</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">2</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">assertTitle</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">Downloads</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 12.7pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">3</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">verifyText</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">//h2</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">Downloads</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">4</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">clickAndWait</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">link=next</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 12.7pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">5</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">assertText</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">showing*page 2</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">6</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr> </tbody></table>
In this testcase we start to open the url &quot;/download/&quot; (btw. the test case can be executed on different base Urls). The next commands checks that the title of the page is really &quot;Downloads&quot; (2) and that a text &quot;Download&quot; is somewhere in a H&quot; Tag on the website(3). After that the link with the text &quot;next&quot; is clicked (4), and after the page is reloaded we assert that somewhere on the website a text &quot;showing*page 2&quot; is present. (Where the asterix is a wildcard).
<h4><span lang="EN-US">A more advanced selenese example</span></h4>
<p class="MsoNormal">Let’s have a look at a more advanced example:</p>
<table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0" height="260" width="643">  <tbody><tr style="height: 12.7pt;">   <td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">1</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">open</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">/ ajaxtest /</span></p>   </td>   <td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">2</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">assertTitle</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">*ajax*</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 12.7pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">3</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">click</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">link=glob:*ajax</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">4</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">waitForElementPresent</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">//div[@id=&quot;ajaxresult&quot;]/span[contains(@class,   'activated')]</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>  </tr>  <tr style="height: 12.7pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 12.7pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">5</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">pause</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">1000</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 12.7pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">showing*page 2</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">6</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">store</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">javascript{'test_'+ new   Date().getTime()+ Math.floor(Math.random()*1000)}</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">$userName</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">7</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">echo</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">generated Username:   ${$userName}</span></p>   </td>  </tr>  <tr style="height: 13.15pt;">   <td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 18.2pt; height: 13.15pt;" valign="top" width="24">   <p class="MsoNormal"><span lang="EN-US">8</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.5pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">type</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">id=login</span></p>   </td>   <td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 94.55pt; height: 13.15pt;" valign="top" width="126">   <p class="MsoNormal"><span lang="EN-US">${$userName}</span></p>   </td>  </tr> </tbody></table>
<p class="MsoNormal">Again we start with opening some URL. Than a click action is performed on a link that has a text ending with &quot;ajax&quot; (3). In AJAX applications you cannot use the &quot;*AndWait&quot; actions, since the website is not reloaded. Here it is better to place a seperate WaitFor* command after the action command. That’s what we did on line (4), we expect that after the Ajax Response is finished when a &quot;span&quot; element with a class &quot;activated&quot; is present. The &quot;pause&quot; command right after a waitFor* command tends to be useful to have a better robustness of the test case.</p>
<p class="MsoNormal">The next commands show what else is possible. In line (6) a random value is stored in the variable $userName. This variable is used in the echo command on line (7) and then an inputfield with the id &quot;login&quot; is filled with this value (8).</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Interesting are the possibilities of the different locators. Here some examples:</p>
<ul><li><span style="font-family: Symbol;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span>Using the identifier locator like: “identifier=loginForm” &nbsp;(identifier prefix is optional)</li><li><span style="font-family: Symbol;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span>Using CSS Selectors: “css=.content div.grid”</li><li><span style="font-family: Symbol;"></span>Selecting a link with a special text: “link=my link”</li><li><span style="font-family: Symbol;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span>DOM Selektors: “dom=document.forms[0].username”</li><li><span style="font-family: Symbol;"></span>Using XPath Selektors: “xpath=//form[@id='loginForm']” (xpath prefix is optional, a “//” is sufficient)</li></ul>
<h2><span lang="EN-US">Whats next</span></h2>
<p class="MsoNormal">If you want to run your tests in other browser you can use Selenium Core. Selenium Core comes with a HTML based Test-Suite Runner that can simply be called from other browsers too:</p>
<p class="MsoNormal">&nbsp;<img src="uploads/RTEmagicC_selenium-core.jpg.jpg" height="126" width="519" alt="" /></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">There are more useful Selenium Tools. First to be mentioned is the Selenium RC Server. This is a Java based Server, that can run tests on multiple platforms and browsers. The cool thing is that you can connect to this server from other applications. So it is possible to run Unit Tests that use Selenese to test your web application.</p>
<h2><span lang="EN-US">The TYPO3 extension “selenium”</span></h2>
<p class="MsoNormal">The TYPO3 extension “selenium” can help to build Selenium Tests for TYPO3 extensions. It has:</p>
<ul><li><span style="font-family: Symbol;"></span>A backendmodul that scans for *TestSuite*.html files inside “tests/selenium” folders and links them with the Selenium Core Runner. So you can easily start Selenium tests from the backend of TYPO3.</li><li><span style="font-family: Symbol;"></span>In the extension configuration you can configure a Selenium RC Server (default port 4444) and you can use this in your phpunit tests.</li><li><span style="font-family: Symbol;"></span>Therefore two abstract testsuite classes are provided.<ul><li><span style="font-family: &quot;Courier New&quot;;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span>tx_selenium_phpunittestcase: Uses the Selenium Testcase class that is part of phpunit.</li><li><span style="font-family: &quot;Courier New&quot;;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;</span></span>tx_selenium_testcase: Uses the PHP selenium Driver, that is part of the Selenium RC package.</li><li><span style="font-family: &quot;Courier New&quot;;"><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span>Each of this classes has a method initializeSelenium($browser,$url) that instanciates the $this-&gt;selenium based on the configured RC Server.</li></ul></li></ul>
<p class="MsoNormal"></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">&nbsp;<img src="uploads/RTEmagicC_selenium-phpunit.jpg.jpg" height="331" width="430" alt="" /></p>
<p class="MsoNormal">&nbsp;</p>
<h2><span lang="EN-US">Links</span></h2>
<p class="MsoNormal"><link http://seleniumhq.org/>http://seleniumhq.org/</link></p>
<p class="MsoNormal"><link http://seleniumhq.org/docs/>http://seleniumhq.org/docs/</link> </p>
]]></content:encoded>
			<category>agile</category>
			
			
			<pubDate>Tue, 06 Oct 2009 16:11:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>Crawler 3.0 released</title>
			<link>http://www.typo3-media.com/blog/crawler-30-released.html</link>
			<description>A new version of the famous crawler extension - initially maintained by Kasper - was released today...</description>
			<content:encoded><![CDATA[<br />A new version of the famous crawler extension - initially maintained by Kasper - was released today by AOEmedia. The new version ships with lot's of improvements and bugfixes.<br />Added by Tolleiv Nietsch about 8 hours ago<br /><br />Especially the performance improvements and the enhancements for the configuration of the crawler are the most remarkable parts of the new version.<br /><br />Regarding the performance improvements we've implemented a full multi-process crawling-model for the crawler. This allows to scale up performance of the crawler with your hardware and push through urgent jobs very quick.<br /><br />The configuration improvements enable a more flexible way to configure your crawl-jobs through configuration-records instead of TSConfig.<br /><br />Even though all the changes happened with backwards compatibility in our minds so all your old settings should still work as supposed.<br /><br />Big kudus for all the good work goes to Timo Schmidt and Fabrizio Branca for AOEmedia.<br /><br />]]></content:encoded>
			<category>news</category>
			
			
			<pubDate>Fri, 11 Sep 2009 17:30:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>small Javascript Objects example</title>
			<link>http://www.typo3-media.com/blog/javascript-objects-example.html</link>
			<description>In addition to article &quot;Javascript object notation&quot; I still have a small example lieing...</description>
			<content:encoded><![CDATA[In addition to article &quot;<link record:tt_news:106>Javascript object notation</link>&quot; I still have a small example lieing around.
Its just a simple table element that is bind to a javascript object that is responsible for controlling the actions related to this table widget - the widgets with its javascript controller part are independend from each other. In theory they could delegate the actions in that widget to a coresponding controller on the server.
<b><link fileadmin/files/examples/javascript-objects.html _blank>To the example</link> </b>
There is one &quot;trick&quot; to mention. We need a way to bind the html element &quot;table&quot; to the object that should control this widget. With jQuery you can do this with the &quot;.data&quot; method - it allows you to bind any stuff to a html element.
So in this case - to ensure that on a click on the  &quot;change color&quot; link  the correct object answers - we just bind the object itself to the link element:
<pre id="line1">// register for clicks on the &quot;change color Link&quot;<br />this.registerEvents=function() { 				<br />	$('#'+this.id+' .click').data('object',this).click(function(event) { $(this).data('object').clickColorAction(); });<br />};</pre>]]></content:encoded>
			<category>pattern</category>
			<category>development</category>
			
			
			<pubDate>Sat, 16 May 2009 09:53:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>MVC - Part 2: &quot;TYPO3 mvcnews example&quot;</title>
			<link>http://www.typo3-media.com/blog/mvc-news-example.html</link>
			<description>We have T3DD and its time to publish the new release of the &quot;mvc&quot; extension together with...</description>
			<content:encoded><![CDATA[We have T3DD and its time to publish the new release of the <link http://typo3.org/extensions/repository/view/mvc/current/ _blank>&quot;mvc&quot; extension</link> together with a first version of an <link http://forge.typo3.org/projects/show/extension-mvcnews _blank>example extension</link>. <br /> 
<h3> Introducing the example:</h3>
 The extension &quot;mvcnews&quot; is planned as a normal news application with articles and categorys, articles can have comments and there can be downloads attached to the article. <br /> <br /> The requirements to the frontend are common: We need a article overview with the features: searchform, pagination and resultlist. Also we need a detailview of an article. That should be all for now.
<h3>Model</h3>
 So the domain model is pretty simple (only relevant parts are shown for now)
<img src="uploads/RTEmagicC_uml-mvcnews-ddd.jpg.jpg" height="297" width="300" alt="" /><br /> 
<h3> Controller</h3>
 Like explained above we need two frontend outputs: a listview and a detailview. We put this both in one controller, that has two actions: &quot;showlistAction()&quot; and &quot;showdetailAction()&quot;. Because the controller needs to access articles, it needs at least the articleRepository. With dependency injection its the best to let the articleRepository inject into the controller.<br /> <br /> With that its pretty easy to fill the showdetailAction with live: Its straight forward: 1. ask the repository for the article that should be displayed <br />2. pass it to the view, and return the view result.
<pre>/**<br />* detail action shows the single view of an object, if a detail view of an object is<br />* requested.<br />*<br />* @return string<br />*/<br />public function showdetailAction() {<br />   if (empty ( $this-&gt;arguments ['id'] )) {<br />    throw new InvalidArgumentsExcepton('no valid id given');<br />   }<br />   $this-&gt;view-&gt;setArticle ( $this-&gt;articleRepository-&gt;findById ( $this-&gt;arguments ['id'] ) );<br />   return $this-&gt;view-&gt;render ();<br />}</pre>
<h3>The detail view</h3>
Like shown above there needs to be a view that is able to render an article. And the view - of course - has to know the article it should render. Therefore the view has a &quot;setArticle&quot; method to set the article the view should render. 
Our detail view actually implements the phpTemplateView, so a template that belongs to that view can look like that:
<pre><br /><br />&lt;div id=&quot;objects&quot;&gt;<br /> &lt;h2&gt;&lt;?php echo $this-&gt;article-&gt;getTitle();&nbsp; ?&gt;&lt;/h2&gt;<br /> &lt;p&gt;&lt;small&gt;&lt;?php echo<br />$this-&gt;labels-&gt;get('field_category'); ?&gt;:&lt;?php echo<br />$this-&gt;article-&gt;getCategory()-&gt;getTitle();<br />?&gt;&lt;/small&gt;&lt;/p&gt;<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />&nbsp;&lt;p&gt;&lt;small&gt;&lt;?php echo<br />$this-&gt;labels-&gt;get('field_date'); ?&gt;:&lt;?php echo<br />$this-&gt;article-&gt;getDate(); ?&gt;&lt;/small&gt;&lt;/p&gt;<br />  &lt;div class=&quot;image&quot;&gt;<br />    &lt;?php &nbsp;&nbsp; &nbsp;echo $this-&gt;article-&gt;getImage();&nbsp;&nbsp; ?&gt;<br />  &lt;/div&gt;<br />  &lt;?php &nbsp;&nbsp; &nbsp;echo $this-&gt;article-&gt;getDescription();&nbsp;&nbsp; ?&gt;<br />&lt;/div&gt;<br /><br /></pre>
 There is one thing thats not perfect: In the view I expect that the getImage returns a Imagetag, and that the description is processed by the TYPO3 parseFunc_RTE stuff.&nbsp; There are two ways to solve that:
<ol><li>we could use viewhelpers (like $this-&gt;fieldRenderer-&gt;asImage(...)) to transform the imagepath to a imagetag for example.</li><li>we can use a presentationmodel and do the transformation of fields for the view there.</li></ol>
 (Btw.: we should not add logic to the domain model, because a imagetag is purely view related and has no meaning in the domain)<br /> <br /> We decide to go with version 2 - just because we might need this transformation in the listview again. 
The mvc framework offers a TCA <b>presentationmodel</b>, that does most of the transformations magic with the help of the TCA informations, so we just need to wrap a presentationmodel around our article object:
<pre>new tx_mvcnews_presentation_articlePresentationModel ( $this-&gt;articleRepository-&gt;findById ( $this-&gt;arguments ['id'] ), $this-&gt;configuration-&gt;get ( 'presentationModel.article.' ), 'tx_mvcnews_article' );</pre>
<h3> The showlistAction and the listview:</h3>
 For the listview we need to find a clean and flexible solution to:
<ol><li>get the correct collection of articles, that matches the search</li><li>render the output with: searchform, pagination and actual results.<br />   </li></ol>
 For the first problem we use a seperate <i>searchCriteriaObject</i>, that has all the informations for the current search - this object is build from the current arguments. Then we pass the <i>searchCriteria</i> to the articleRepository-&gt;findByCriteria method and all the application-specific searchlogic has to be part of this repository. So the call sequenz&nbsp; looks something like this:<br /> <img src="uploads/RTEmagicC_uml-mvcnews-sequenz.jpg.jpg" height="211" width="463" alt="" /><br /> <br /> For the second problem we use the pattern <i>compositeView</i>. Thats mainly a view that consits of other views - and just like the requirements say: we have three subviews: pagination, searchform and list. Of course all of this subviews require a model that they can render:
<ul><li>the paginationSubView has setter methods to provide the required informations for the pagination</li><li>the searchformSubView - well it needs a formmodel. The formmodel tells the searchForm which formelements it can render. The seperate formmodel is also greate to validate the users input before doing anything.</li><li>and finaly the listSubView needs the collection of articles that it should render.<br />   </li></ul>
 The main advantage of splitting your view into subviews is that you can reuse the views. So imagine you need the searchform as a standalone form, or you might need just the list of lastest articles -&gt; you can reuse the existing views.
<br /> This is how the class diagramm of the listview looks like:<br /> <img src="uploads/RTEmagicC_uml-mvcnews-views.jpg.jpg" height="247" width="300" alt="" /><br /> <br /> And finaly this is the output:<br /> <img src="uploads/RTEmagicC_mvcnews-listview.jpg.jpg" height="239" width="367" alt="" /><br /> <br /> 
<h3> Whats next?</h3>
 You can have a look in the example extension and see yourself how it works.
By now the example &quot;mvcnews&quot; has just a basic output without any advanced features, here is whats planned next:
<ul><li> add AJAX loading for searching and paginating</li><li>add more features like commenting and rating, that propably results in a richer domain model and more action methods in the controller.<br />   </li></ul>]]></content:encoded>
			<category>pattern</category>
			
			
			<pubDate>Fri, 15 May 2009 09:59:00 +0200</pubDate>
			
		</item>
		
		<item>
			<title>MVC - Part1: &quot;Introduction and History&quot;</title>
			<link>http://www.typo3-media.com/blog/mvc-mvp-typo3-introduction.html</link>
			<description>
Everybody speaks about MVC - the de facto standard for building modern application. Here is a...</description>
			<content:encoded><![CDATA[
Everybody speaks about MVC - the de facto standard for building modern application. Here is a short article to the basics and history of MVC.
<h3>Short introduction to Model View Controller</h3>
MVC intention is to build applications in a modular way, where we have 3 general parts responsible for creating the output and allowing the interaction&nbsp; with the user: 
<h4> Model: </h4>
 In the context of the MVC the model has the data that is required to render things in the view. So it represents the data that are required for rendering. It also takes over the operation related to the domain.The model is used to do something and get the data. 
<h4> View:</h4>
 takes over the display of the applications state. A view takes care of „rendering the pixels on the screen“ and should be as dump as possible. Typically a view class understands one or more model(s) and outputs the information of that model. ( A view is not allowed to write in the model.) So the view is aware of the model and knows how to read the data out of it – but never the model should know something about the view!
<h4> Controller: </h4>
 It glues together Model and View, it controls the user interaction with the model and the view. (Its a thin layer that connects models with there views)<br /> <br /> 
<h3>The historic basic &quot;smalltalks-80&quot; classical MVC:</h3>
One of the first MVC framework was the smalltalks-80 MVC implementation in the 80s. Smalltalk is a pure objectoriented programming language, and the MVC concept was a key feature.<br /><img src="uploads/RTEmagicC_classical-mvc.jpg.jpg" height="204" width="230" alt="" /><br />It was designed for Desktopapplications and the main idea is to seperate the presentation from the domainmodel.<br />Controller and view do not know each other. Instead the view updates itself through observing the relevant model. Therefore the models needs to implement the observer pattern. Controller handles the userinputs and delegates the useractions to methodcalls in the models.<br /><br />A complete screen can be understand as a collection of widgets - each widgetelement consit of its own View and Controllerobject. 
<h4>Downsides of the smalltalks 80 MVC concept:</h4>
Usage of the Observer Pattern: You dont know whats going on by reading the code.<br />Complex Screens get really complex because of a hierarchie of widgets with own View and Controller part. Specially if you have the requirement to know about a user action in more controllers. <br /><br />Problem of handling logic that is only related to presentation =&gt; that is put into the view - so the view gets some logic which is not optimal.<br /><br />This MVC concept is not really relevant for typical Webapplications!<br /><br />
<h3>MVP vs MVC</h3>
The smalltalk developers recognized the downsides of the classical MVC concept and introduced a simelar concept called MVP (Model View Presenter).
<img src="uploads/RTEmagicC_mvp.jpg.jpg" height="276" width="300" alt="" />
The role of the presenter within MVP is to interpret the events and gestures initiated by the user and provide the business logic that maps them onto the appropriate commands for manipulating the model in the intended fashion. <br />While it is the view’s responsibility to display model data it is the presenter that governs how the model can be manipulated and changed by the user interface. This is where the heart of an application's behaviour resides. 
In many ways, a MVP presenter is equivalent to the MVC controller.<br />The main difference is that a presenter is directly linked to its associated view so that the two can closely collaborate in their roles of supplying the user interface for a particular model. This can be very handy at times and is one of the most obvious benefits over MVC where the application model only has an indirect link to its associated view. 
However the shortcut &quot;MVP&quot; is not so common like &quot;MVC&quot; but most of the MVC frameworks you find for webapplications follows more the MVP concept.
<h3>MVC for Webapplications</h3>
The concepts above were initialy developed for desktop applications. In desktop applications you have a direct connect between UI components and the responsible controller or presenter. In webapplications you normally dont have this: The HTML for a complete screen is sended to the browser. If the user do some actions in the UI a request is send to the webserver - this request has to be interpreted and normally the complete (updated) screen needs to be sended to the browser again.
<img src="uploads/RTEmagicC_mvc-for-web.jpg.jpg" height="122" width="300" alt="" />
The HTML for the complete screen can be understand as a set of widgets (or subviews). For example it can contain a &quot;mainmenu&quot;, a &quot;newslist&quot;, a &quot;basket&quot; etc. The webserver always needs to generate the complete view with all its subviews. 
A MVC Framework for webapplications therefore normally works this way:
<ul><li>The request that is send from the browser to the webserver is send to a front controller. This front controller builds a request object and starts the processing of this request.</li><li>That means Controller Objects are called (normally action methods in the controller that belongs the current request. This process is called &quot;dispatching&quot;) and this controllers are responsible to return the correct response. Like normal controllers they do:<ul><li>The controller loads/modify model objects</li><li>Pass the model to a view</li><li>calls the view &quot;render()&quot; method to get the response.</li></ul></li><li>Normally the view that is returned to the browser consist of a hierarchie of subviews and/or widgets.</li></ul>
<b>MVC Frameworks for webappications:</b>
<ul><li>http://flow3.typo3.org - the upcoming framework for TYPO3 5.0</li><li>http://typo3.org/extensions/repository/view/mvc/current/ - extension enables MVC based plugin on top of the CMS TYPO3 4.x</li><li>http://framework.zend.com/ - powerful collection of PHP5 classes and modules, includes also a full featured MVC framework</li></ul>]]></content:encoded>
			<category>news</category>
			<category>pattern</category>
			
			
			<pubDate>Sun, 15 Mar 2009 12:21:00 +0100</pubDate>
			
		</item>
		
		<item>
			<title>running FLOW3 with PHP 5.3.0 on mac (up)</title>
			<link>http://www.typo3-media.com/blog/flow3-on-mac.html</link>
			<description>Just some small notes about how to run FLOW3 on a mac.</description>
			<content:encoded><![CDATA[Just some small notes about how to run FLOW3 on a mac.
<h3>Installing PHP 5.3.0beta1</h3>
FLOW3 requires PHP 5.3 in the current version. Macport is a greate tool (like apt*) for compiling and upgrading software. So the first thing you need to do is download: http://www.macports.org/.
After downloading and installing macport you can use the port commands to download and install new software with its dependencies. For PHP 5.3 you can use this commands:
<pre>cd /opt/local/bin<br />sudo ./port selfupdate -f<br />sudo ./port search php5<br />sudo ./port variants php5-devel<br />sudo ./port install php5-devel +apache2 +macosx +mysql5 +sqlite</pre>
More details on <link http://guide.macports.org/.>http://guide.macports.org/.</link> 
<h3>Installing FLOW3</h3>
You can get the current version from SVN: svn co https://svn.typo3.org/FLOW3/Distribution/trunk/.
<h3>Update (18.10.2009)</h3>
Since php 5.3 is released its now available with the port &quot;php5&quot;:
<pre>( sudo ./port installed )<br />sudo ./port uninstall php5-devel<br />sudo ./port install php5 +apache2 +macosx +mysql5 +sqlite</pre>]]></content:encoded>
			<category>news</category>
			
			
			<pubDate>Sat, 28 Feb 2009 08:21:00 +0100</pubDate>
			
		</item>
		
	</channel>
</rss>