<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.invenzzia.org/en/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Invenzzia... in English - Open Power Forms</title>
  <link>http://blog.invenzzia.org/en/</link>
  <atom:link href="http://blog.invenzzia.org/en/feed/category/Projects/Open-Power-Forms/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>en</language>
  <pubDate>Fri, 10 May 2013 13:58:34 +0100</pubDate>
  <copyright>Copyright &amp;copy; Invenzzia</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>A closer look at Open Power Forms</title>
    <link>http://blog.invenzzia.org/en/post/A-closer-look-at-Open-Power-Forms</link>
    <guid isPermaLink="false">urn:md5:d3f5a8ee17b8d1b9903e02f85a0c1875</guid>
    <pubDate>Sun, 06 Sep 2009 09:20:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Forms</category>
        <category>development</category><category>OPF</category>    
    <description>&lt;p&gt;After releasing the first stable version of Open Power Template, we gained an opportunity to focus on other Invenzzia projects as well. One of the new enterprises is a form processing library which has been given a name Open Power Forms. In the last days, I managed to implement the basic functionality and run the first test files and I would like to introduce you in the new project. From this entry, you are going to get to know, what OPF actually is, what are its benefits and main goals and what has been implemented so far.&lt;/p&gt;    &lt;h2&gt;Open Power Forms&lt;/h2&gt;


&lt;p&gt;Open Power Forms is a form processing library. It manages the logic behind the forms and allows the programmer to create them with a set of simpler rules. He simply defines what he would like to see there and waits for the input data. The complete task list of a form processor can be found below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Providing a system to define the content of a form and its behaviour: validation rules, data filters, information messages etc.&lt;/li&gt;
&lt;li&gt;Rendering the form in the HTML format.&lt;/li&gt;
&lt;li&gt;Validating the input data and filtering them in order to prepare them to be processed by the application logic layer.&lt;/li&gt;
&lt;li&gt;Validation error handling and informing the user about the problems.&lt;/li&gt;
&lt;li&gt;Managing the form layout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, form processors play an important role in a web application. Most of the communications between the user and the script passes through forms and having a good management system for this element should be necessary. We get the unified set of rules and behaviours which speeds up the development process and eases the mainternance.&lt;/p&gt;


&lt;h2&gt;The goal&lt;/h2&gt;


&lt;p&gt;The web frameworks usually introduce their own form processing system, but sometimes is too simplified to satisfy the requirements. An example of such framework is Kohana, where we have validators, view helpers and nothing more - it is our task to build and implement the whole logic, using these elementary blocks. The other ones provide a convenient API, but lack of the more advanced features, such as multi-page forms or offer a limited choice of widgets, validators and filters. In this group the best example is Zend_Form, a part of Zend Framework. The last important problem concerns the rendering system. It is very easy to display a form, but hard to customize it. Zend_Form forces us to use massive OOP and design patterns in order to customize the HTML code which can easily break the MVC pattern by moving the view tasks to the logic or controller layer. At the same time, sfForm from Symfony provides a concept of &lt;em&gt;template templates&lt;/em&gt;, small files written in PHP that are compiled by the extra compiler to build the form layout. Anyway, if we want to customize the look, we have to be prepared to lots of coding in PHP. The main disadvantage is that the developers of freamework-based solutions usually have no time to provide a more generalized solution which leads to wheel reinvention and the problems with code refactoring.&lt;/p&gt;


&lt;p&gt;And we want to create a general-purpose form processing library free of those disadvantages.&lt;/p&gt;


&lt;h2&gt;OPF features&lt;/h2&gt;


&lt;p&gt;The key features of Open Power Forms are the form management logical model and the rendering algorithm. We begin with focusing on the first issue. Most of the form processors treat the form as a list of atomic fields, sometimes grouped. It is very easy to implement such a form processor, but it cannot handle more advanced forms. Let's imagine the column insertion form in phpMyAdmin. It allows the administrator to add several columns at the same time by multiplying the same form several times in the table rows. Other web applications may use multi-step forms, where the user fills the form called &quot;Step 1&quot;, then goes to &quot;Step 2&quot; and so on. The entire data are processed after filling in the final step. What is more, some steps may be activated only if the user made a certain choice in the previous ones. The better model to represent such situations is to unify the concepts of a form and a form field. Open Power Forms formally makes no difference between them. We are allowed to append one form as a field of the other form, guaranteed the library will recognize our intentions.&lt;/p&gt;


&lt;p&gt;If we are talking about not-reinventing-the-wheel in the form rendering issue, we must throw away all the ideas that do not work in the other libraries. They rely on PHP and they fail, but we already have a great template language provided by Open Power Template. It offers us some brilliant features, very useful in the form rendering, that is &lt;em&gt;components&lt;/em&gt; and &lt;em&gt;snippets&lt;/em&gt;. The component system has been designed especially for forms - we work there with components, which are various form widgets, such as input fields, select lists, radio buttons etc. Components separate the field logic (managing the labels, IDs, attributes, errors etc.) from their presentation. The field logic is implemented in a PHP class, and the presentation with a component port in a template. A sample port looks like this:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;opt:inputComponent name=&amp;quot;foo&amp;quot;&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;label parse:for=&amp;quot;$system.component.id&amp;quot;&amp;gt;{$system.component.label}&amp;lt;/label&amp;gt;
    &amp;lt;opt:display /&amp;gt;
    &amp;lt;opt:onEvent name=&amp;quot;error&amp;quot;&amp;gt;
       &amp;lt;p class=&amp;quot;error&amp;quot;&amp;gt;{$system.component.error}&amp;lt;/p&amp;gt;
    &amp;lt;/opt:onEvent&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/opt:inputComponent&amp;gt;
&lt;/pre&gt;


&lt;p&gt;In the example above, we create a statically deployed port, where the template automatically creates a component object for it, using the tag name (&lt;code&gt;opt:inputComponent&lt;/code&gt;). But we have also standalone ports, where we load the component from a template variable, and the component itself may be created with a script. In both cases, the content of the XML tag remains the same. What is more, we can use snippets to save the form layout in one place and simply insert it in all the ports of all the forms we have:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;opt:snippet name=&amp;quot;fieldLayout&amp;quot;&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;label parse:for=&amp;quot;$system.component.id&amp;quot;&amp;gt;{$system.component.label}&amp;lt;/label&amp;gt;
    &amp;lt;opt:display /&amp;gt;
    &amp;lt;opt:onEvent name=&amp;quot;error&amp;quot;&amp;gt;
       &amp;lt;p class=&amp;quot;error&amp;quot;&amp;gt;{$system.component.error}&amp;lt;/p&amp;gt;
    &amp;lt;/opt:onEvent&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/opt:snippet&amp;gt;

&amp;lt;opt:component from=&amp;quot;$variable&amp;quot; template=&amp;quot;fieldLayout&amp;quot;&amp;gt;
  &amp;lt;!-- we can set some attributes here --&amp;gt;
&amp;lt;/opt:component&amp;gt;
&lt;/pre&gt;


&lt;p&gt;At any time, we may decide, whether to implement a field-specific layout for particular components or use the default ones. Moreover, we operate on simple HTML with some extra tags without the need to create hundreds of files and deal with the implementation details, as OPT hides the unncecessary logic from us.&lt;/p&gt;


&lt;p&gt;Open Power Forms is going to provide a set of OPT-compatible components integrated with the form processing system, plus some extra tags, data formats and functions for designing forms and managing their layouts. Below, we can see a working template that uses the new features:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;
&amp;lt;opt:extend file=&amp;quot;base.tpl&amp;quot;&amp;gt;
  &amp;lt;opt:snippet name=&amp;quot;title&amp;quot;&amp;gt;Situation 1&amp;lt;/opt:snippet&amp;gt;
  
  &amp;lt;opt:snippet name=&amp;quot;content&amp;quot;&amp;gt;
	&amp;lt;!-- configure CSS styles for the elements --&amp;gt;
	{$design.form.valid is 'form'}
	{$design.field.valid is 'row'}
	{$design.field.invalid is 'row row-error'}
	{$design.input is 'inputText'}
	
	&amp;lt;!-- display a form --&amp;gt;
	&amp;lt;opf:form name=&amp;quot;form1&amp;quot;&amp;gt;
		&amp;lt;div class=&amp;quot;errors&amp;quot; opt:if=&amp;quot;not $system.form.valid&amp;quot;&amp;gt;&amp;lt;p&amp;gt;The form is invalid.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
	 
	 	&amp;lt;!-- load the components assigned to the &amp;quot;default&amp;quot; placeholders --&amp;gt;
		&amp;lt;opt:section name=&amp;quot;default&amp;quot;&amp;gt;
 			&amp;lt;opt:component from=&amp;quot;$default.component&amp;quot; template=&amp;quot;widget&amp;quot;&amp;gt;
			&amp;lt;/opt:component&amp;gt;
		&amp;lt;/opt:section
		
		&amp;lt;!-- some final stuff --&amp;gt;
		&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot; /&amp;gt;
	&amp;lt;/opf:form&amp;gt;
  &amp;lt;/opt:snippet&amp;gt;
&amp;lt;/opt:extend&amp;gt;
&lt;/pre&gt;


&lt;p&gt;And here is the PHP part of the form:&lt;/p&gt;

&lt;pre&gt;
class My_Form extends Opf_Form
{
	// An event
	public function onInit()
	{
		$item = $this-&amp;gt;itemFactory('title');
		$item-&amp;gt;setRequired(true);
		$item-&amp;gt;addValidator(new Opf_Validator_Length(5), 'The length is invalid');
		$item-&amp;gt;setWidget(new Opf_Widget_Input)
			-&amp;gt;setLabel('Title');

		$item = $this-&amp;gt;itemFactory('countries');
		$item-&amp;gt;setRequired(true);
		$item-&amp;gt;addValidator(new Opf_Validator_Type(Opf_Validator_Type::INTEGER), 'The field type is invalid.');
		$item-&amp;gt;setWidget(new Opf_Widget_Select)
			-&amp;gt;setLabel('Countries');
	} // end onInit();

	// An event
	public function onRender()
	{
		$view = $this-&amp;gt;getView();
		
		$item = $this-&amp;gt;itemFactory('countries');
		$item-&amp;gt;getWidget()-&amp;gt;setOptions(array(0 =&amp;gt;
			'China',
			'France',
			'Germany',
			'Great Britain',
			'Poland',
			'Russia',
			'Spain',
			'United States'
		));
	} // end onRender();

	// An event
	public function onAccept()
	{
		$view = $this-&amp;gt;getView();
		$view-&amp;gt;setTemplate('results.tpl');
		$results = array();
		foreach($this-&amp;gt;getValue() as $name =&amp;gt; $value)
		{
			$results[] = array('name' =&amp;gt; $name, 'value' =&amp;gt; $value);
		}
		$view-&amp;gt;results = $results;
	} // end onAccept();
} // end MyForm;
&lt;/pre&gt;


&lt;p&gt;The list of core features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexible design - the forms can be constructed either by extending the base form class or by configuring the bare form object and responding on the events.&lt;/li&gt;
&lt;li&gt;Event listeners - they can be used to implement the logic of common form parts by extending the initialization or rendering events. The concept is similar to event listeners and behaviours in Doctrine ORM.&lt;/li&gt;
&lt;li&gt;AJAX support - the AJAX requests could be implemented as ordinary form events and the library will set up the entire communication process.&lt;/li&gt;
&lt;li&gt;Huge (and useful) set of widgets, validators and filters.&lt;/li&gt;
&lt;li&gt;Web Forms 2.0 support.&lt;/li&gt;
&lt;li&gt;CSRF attack protection.&lt;/li&gt;
&lt;li&gt;Support for complex forms: multi-step forms or forms built of smaller forms.&lt;/li&gt;
&lt;li&gt;Doctrine ORM support out-of-the-box.&lt;/li&gt;
&lt;li&gt;Full integration with Open Power Template library.&lt;/li&gt;
&lt;li&gt;Internationalization support.&lt;/li&gt;
&lt;li&gt;Integration with Zend Framework thanks to the already available OPL port for Zend Framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Current status&lt;/h2&gt;


&lt;p&gt;The library currently implements the most important core features, such as data validation, error reporting and form rendering and is able to process simple forms. We are currently working on extending the logical model in order to support more complex forms and their proper rendering. In the very near future, the first development version will be released. We would appreciate any suggestions and ideas.&lt;/p&gt;


&lt;h2&gt;Conclusion&lt;/h2&gt;


&lt;p&gt;The goal of Open Power Libs project is to develop innovative PHP libraries. The success of Open Power Template has shown us that there exists a demand for solutions that break the stereotypes and give the programmers a fresh point of view of the well-known issues. Open Power Forms is a next step towards satisfying them and developing a complete presentation layer for web applications.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/en/post/A-closer-look-at-Open-Power-Forms#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/en/post/A-closer-look-at-Open-Power-Forms#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/en/feed/atom/comments/63</wfw:commentRss>
      </item>
    
</channel>
</rss>