Zero Dot Nine
By Fred Bird on Tuesday 30 October 2007, 14:10 - news - Permalink
If you take a look at the roadmap, you'll see some changes. A development branch has been started, numbered 0.9 (odd minor versions numbers will now be for development versions - even for stable ones). The 0.8 still live in the trunk for now. Milestones are set up to 0.14.
So what's new ?
- Services have disapperead and are replaced by Tools, which are accessed as Kits members.
- Storages are now Tools themselves, provided by webappkit/storages.
- Kits API have changed a bit. Most methods are static ones. Kits metadata and libraries are now loaded before Kit instance building, to allow some kits to override the generic webappkit class.
- PHP version range compatibility can be defined in Kits metadata.
The help file in the repository have been updated with new tutorials. I hope to release 0.10 rather quickly, has goals previously set for 0.9 have been sparsed over three milestones.
Here is the content of the updated help file :
Using a Kit
Unzip webappkit at the root of your web application. It's probably done as the file you're reading is part of it. It creates a webappkit/ folder. Before retrieving any Kit, put this line into your code :
/**
* getting webappkit core (only once call is necessary)
*/
include('webappkit/include-me.php');
When you need a Kit's resources, let's say ooxmlrpc, load it with :
/**
* loads a kit resources
*/
webappkit::getKit('ooxmlrpc');
If you need only a subkit, let's say http within databeans, get it with :
/**
* loads a subkit's resources
*/
webappkit::getKit('databeans/http');
In this exemple, databeans/http requires databeans/databean, but you don't have to take care about that.
webappkit::getkit($id) returns the kit instance. Always use this method to retrieve a kit, as Kits should be singletons.
Tools
Tools are named object instances taking their configuration data from the kit they belong to.
They are retrieved as kit members like this :
/**
* retrieving the kit instance.
*/
$kit=&webappkit::getKit('helloworld');
/**
* calling the method "bar" of the kit's tool named "foo"
*/
$kit->foo->bar();
Storages
Storages are specific Tools. They build and retrieve object instances stored within kits files.
You use them just as any other Tool, as a kit's member. For example, let's get a template from our sample kit :
/**
* retrieving the kit instance.
*/
$kit=&webappkit::getKit('helloworld');
/**
* getting the template from the storage, which is named "templates"
*/
$tpl=$kit->templates->getItem('help');
/**
* using the
*/
echo $tpl->render();
Building a Kit
Let's build a Kit named mykit, which will contain a couple of class definition files.
-
Create a folder named mykit.wak within your webappkit/ folder.
-
Put your code files inside, let's say myclass.class.php and mychildclass.class.php which is extending it.
-
Create an INI file at its root named wak.ini and edit it :
[kit] ; kit-wide meta informations version = "0.1" ; kit version. Will be used later. desc = "This is my first kit. It will rocks !" ; a short description. Single line to be INI compliant ! phpversion = "4.3-5.*" ; define which PHP versions range compatibility (optional) ; you can use a single version string with jokers, as 4.* [load_kits] ; kits to load before self resources, order will be preserved. ; n = "absolute kit id" 0 = "datapath" [load_files] ; self resources to load, order will be preserved. ; n = "relative/path/to/file" 0 = "myclass.class.php" 1 = "mychildclass.class.php"This file describe Kit's resources and dependancies. Kits and files will be loaded in the order you defined.
Here we're done with the main kit.
Please note that Kits are singletons and won't be instanciated twice. Hopefully.
PHP version auto-switch
You can have a library file for each PHP versions, and tell the kit to load the appropriate one upon the current PHP version running.
To do this, we will name our files with the specific extensions : .php4 and .php5 , and then edit the kit's INI as this :
[load_files]
; self resources to load, order will be preserved.
; n = "relative/path/to/file"
0 = "myclass.class.php*"
1 = "mychildclass.class.php*"
Using * at the end of the file name will trigger the load of .php4 or .php5, upon the current running PHP version.
Building a subkit
Kits can contain subkits, which can be either optional or loaded by their parent kit.
It will also require another kit, webappkit/datapath, and provide an extension as an optional subkit named mysubkit.
-
Into mykit.wak/, create a folder named mysubkit.wak
-
Put its own code files into it, for example anotherclass.php4 and anotherclass.php5, which are PHP4 and PHP5 versions of the same class as seen before.
-
Create its wak.ini file at its root :
[load_kits] ; kits to load before self resources, order will be preserved. ; n = "absolute kit id" 0 = "mykit" 1 = "pathnodes" [load_files] ; self resources to load, order will be preserved. ; n = "relative/path/to/file" 0 = "anotherclass.php*"As you see, this subkit requires its parent kit and another kit, pathnodes. It also requires datapath, but this dependancy is already defined by parent kit.
A subkit may contain itself a subkit and so on.
Subkits auto-loading
If we want the parent kit mykit to load its subkit when loaded itself, we can add this into mykit's wak.ini file :
[load_subkits]
; subkits to load after self resources, order will be preserved
; n = "relative subkit id"
0 = "mysubkit"
The subkit will be loaded after paren'ts kit dependancies and own files.
Adding Tools
Tools have to be declared within kit's wak.ini file :
[load_files]
0 = "worker.class.php"
[tools]
; name = "class"
bob = "worker"
Here we have declared a tool wich will be named bob within the kit and will be an instance of the class worker.
Tools classes have to extends wakTool class. Their definition file can be included within the providing kit or one of its dependencies. Here it's an included one. Let's look at its class definition :
class worker extends wakTool {
/**
* a Factory function : every Tool has to declare it
* @static
* @param string $kit kit's id
* @param string $name tool's name within kit
* @return object worker's instance
*/
function & factory($kit,$name) {
return new worker($kit,$name);
}
/**
* here is an useful function
* @return string hairs color
*/
function getHairs() {
return $this->cfg['hairs'];
}
/**
* @var array the default configuration values
*/
var $cfg=array('hairs'=>'red');
}
Now, we can get tool bob from our kit and it will have its default config :
$kit=&webappkit::getkit('mykit');
/**
* this will print 'red'
*/
echo $kit->bob->getHairs();
Borrowing tools
But our worker class can now be used in another kit, by declaring it in the kit's wak.ini file :
[kit]
desc = "this is another kit, providing a worker tool borrowed from mykit"
[load_kits]
0 = "mykit"
; we need its "worker" class for alice service
[tools]
alice = "worker"
And let's override its config. Create a file named alice.tool.ini at the anotherkit's root :
; this is the alice tool config file for anotherkit
hairs = "blue"
Let's look at our second tool instance :
$kit2=webappkit::getkit('anotherkit');
/**
* this will print "blue"
*/
echo $kit2->alice->getHairs();
And you can also have several instances of the same tool within the same kit, each with its own config.
Adding storages
Storages are just specific tools. Just like them, their definition file can be included within their providing kit, or they can just provide a config file for a tool class taken from an external kit dependancy.
They have to extend wakStorage class, which is provided by webappkit/storages kit.
Their function is to retrieve object instances stored in files within the kit.
Here we will get templates from our kit, using a storage class provided by djtpl template engine kit.
Here's our kit's wak.ini :
[load_kits]
; getting dependancies, including the storage class
0 = "djtpl"
; please note that djtpl kit itself require webappkit/storages
[tools]
; declaring storage, name = "class"
templates = "djtplstorage"
And now we override some storage config in templates.tool.ini :
; this is the templates storage config
search = "views/{{lang}}/{{id}}.{{type}}"
; here is the filename template for files search
[critera]
; the defaults values for search criteria
lang = "en"
type = "html"
This settings indicate that template files will be stored within a
views/ folder within our kit, having languages subfolders, and that
files are named by id.type. The default language is set to en, and
default type to html.
Now, let's get a template from our kit. First, we will change the language default value to fr. Then, we want the template having the home id.
/**
* changing a criteria's default value
*/
$kit->templates->setCriteria('lang','fr');
/**
* getting a template
* string criteria will be taken as 'id'
* or you can provide an associative array for more criteria
* missing criteria will be taken from current defaults
* this will build a template instance from views/fr/home.html
*/
$tpl=$kit->templates->getItem('home');
/**
* rendering the template
*/
echo $tpl->render();