Simple Example

The best way to introduce a framework is with simple example.

Example:

Here is the functional example included directly in the page. It by the way shows another neat feature of the framework - every piece of UI is just a component and components can by combined together in arbitrary manner.

I'm thinking a number from 1 to 10.

Source code:

The first file here is the PXML file Guess.pxml that describes user interface combining usual HTML tags with special Pexeso tags. The HTML tags are used mostly for layout purpose.

All string in curly braces are PHP expressions dynamically resolved at runtime where variable $self refers to the root component of the PXML file (instance of the Guess class).

There is another piece of PHP code written in the standard processing instructions element <?php … ?>. This code is executed at load time and in this case it loads implementation of the Guess class that is the root component of the PXML file.

examples/Guess.pxml
<?xml version="1.0" encoding="UTF-8"?>
<Guess xmlns:ex="examples"
	xmlns:h="http://www.w3.org/1999/xhtml"
	xmlns:px="http://pexeso-php.sourceforge.net/1.0"
	title="Guess Example"
	preExecute="{$self->preExecuteHandler()}">
	
	<?php require_once('examples/guess.php');?>
	
	<h:h3>{$self->message}</h:h3>
	
	<px:Form>
		<px:TextField name="guessField" 
			rendered="{$self->number != $self->guessField->value}"/>
		<px:Button click="{$self->guessButtonHandler($event)}" label="Guess"
			rendered="{$self->number != $self->guessField->value}"/>
		<px:Button click="{$self->number = rand(1,10)}" label="New guess"
			rendered="{$self->number == $self->guessField->value}"/>
	</px:Form>
	
</Guess>

Next file is the implementation of the Guess class. It extends Component class with necessary properties and event handlers referenced from PXML file. The code is pretty simple although the properties are implemented using getter and setter methods. Especially setter is important for properties which state needs to be saved among multiple user interactions as they need to dispatch PropertyChangeEvent when changed.

examples/guess.php
<?php
use px\view\Component;

use px\controls\MouseEvent;

/**
 * Guess component implementation.
 *
 * @author javol
 */
class Guess extends Component
{
	/**
	 * Pre-execute handler of the view.
	 */
	public function preExecuteHandler()
	{
		// if the number is not restored from state then we generate new one
		if ($this->number == NULL) {
			$this->setNumber(rand(1,10));
		}
	}
	
	/**
	 * @var number
	 */
	private $number;
	
	/**
	 * Get random number to be guessed.
	 * @return number
	 */
	public function getNumber()
	{
		return $this->number;
	}
	
	/**
	 * Set random number to be guessed.
	 * @return number
	 */
	public function setNumber($value)
	{
		// use this helper method to save the property on the state when changed
		$this->changeProperty($this->number, $value, "number");
	}
	
	/**
	 * @var string
	 */
	private $message = "I'm thinking a number from 1 to 10.";
	
	/**
	 * Get message for the user.
	 * 
	 * @return string
	 */
	public function getMessage()
	{
		return $this->message;
	}
	
	/**
	 * Guess button click event handler.
	 * 
	 * @param MouseEvent $event mouse click event
	 */
	public function guessButtonHandler(MouseEvent $event)
	{
		$guessed = intval($this->guessField->value);
		if ($guessed < 1 || $guessed > 10) {
			$this->message = "The entered number must be between 1 to 10.";
		}
		else if ($guessed < $this->number) {
			$this->message = "Not bad guess but give it a little more.";
		}
		else if ($guessed > $this->number) {
			$this->message = "You are aiming too high.";
		}
		else {
			$this->message = "That's it, you got it. It was ".$this->number.".";
		}
	}
}

?>

The last file guessExample.php is just a bootstrap code that loads, executes and displays the component specified above. Url of this file is then used to display the component in the browser.

examples/guessExample.php
<?php
use px\core\QName;

use px\view\Application;

// put pexeso framework on path
set_include_path(get_include_path().PATH_SEPARATOR.'../../pexeso'.PATH_SEPARATOR."../");

// include class autoloading code
require_once 'classExists.php';
spl_autoload_register(classExists);

// create view from component and execute it
$app = Application::getApplication();
$view = $app->getViewForComponent(new QName("Guess","examples"));
$view->execute();

?>

Having 3 files for such a simple application may seem too much and actually it is too much but in most cases it is not necessary. More often you combine the latter two files containing PHP code together while keeping the XML user interface definition separate.