The Graph-IT Web-Toolkit (giwt) library provides a small Web-Framework.
We use this toolkit to have an easy and coherent way to deverlop web applications.
A giwt-application typically consists of four folders
and the 'composer.json'-file (see: composer-schema) which contains the package description and dependencies.
To get a better understanding of giwt let's start with a small 'Hello World'-example project to see how to use giwt.
Without going into detail let's start with a 'Hello World'-project. The application we create here returns a html page which shows 'Hello World!' or 'Hello PERSON!', depending on whether the request path container a parameter or not.
So /
will return 'Hello World!' and /Nicht der Sebi
will return 'Hello 'Nicht der Sebi'!'.
Having that in mind we start with the composer.json of the package.
{
"name" : "graphit/giwt-helloworld",
"description": "The 'Hello World'-project!",
"type": "project",
"authors": [
{
"name": "Graph-IT",
"email": "info@graph-it.com"
}
],
"license": "proprietary",
"require": {
"graphit/giwt": "dev-master"
},
"autoload": {
"psr-4": { "Graphit\\Examples\\": "src/" }
}
}
Inside the composer.json-file we specify the general information (see: composer-properties) of the project, it's dependencies and the autoloader configuration.
/
, here graphit/helloworld
. (see: composer-name)"graphit/giwt": "dev-master"
. (see: composer-require)
Note: Each required package is listed with it's name and it's composer-version-constraints."Graphit\\Examples\\": "src/"
to specify that anything inside the 'src'-folder belongs to the 'Graphit\Examples' namespace. (see: composer-autoload)Now that we have a composer.json-file we look at the config-folder.
A config-folder always contains at least three files:
The app.json
{
"include": [ "routes", "services" ]
}
lists the files to include. This should always list "routes", "services"
and nothing more.
Looking at the routes.json (see: routes.json)
{
"routes": {
"index": {
"pattern": "/",
"default": {
"_controller": "Graphit\\Examples\\Hello:index"
},
"requirements": {
"_method": "GET"
}
},
"named": {
"pattern": "/{person}",
"default": {
"_controller": "Graphit\\Examples\\Hello:named"
},
"requirements": {
"_method": "GET"
}
}
}
}
two routes ("index" and "named) are specified through a bunch of values:
/
for the "index"-route and /{person}
for the "named"-route. The pattern for the "named"-route indicates that if /
is followed by an argument like 'Nicht der Sebi', this argument will be send to the controller as $person.
Since the patterns of the two routes overlap their order ('index' before 'named') is important. With the given order the "index"-route will be used when no argument is given and the "named"-route will be used whenever a single argument is given.
$person
. So unless the the method had a default value for that argument the call would fail!.Graphit\\Examples\\Hello:index
) and for the "named"-route the 'namedAction'-method (Graphit\\Examples\\Hello:named
) of the 'Graph\Examples\HelloController'-class will be called.
Now that the routes of the project are specified, it's time to look at the services.
Looking at the services.json (see: services.json)
{
"router": {
"type": "service",
"class": "Graphit\\Core\\Router",
"config": [
{ "method": "addRoutes",
"args": [
{ "type": "service", "name": "routes" }
]
}
]
},
"twig": {
"type": "service",
"class": "Graphit\\Core\\Twig"
}
}
only two services are listed. A 'router'-service, which handles the routes and a 'twig' service, which is needed to evaluate '.twig'-files. We use the 'twig'-service here since we normally use it, but if you don't use Twig, this service is not needed.
router: The router-service is used to handle all routing.
Kernel
and thus available inside any 'Controller'-class (see: Controller) using $this->get('router')
.twig: (see: Twig)
Kernel
and thus available inside any 'Controller'-class using $this->get('router')
.The 'src'-folder contains all the source files. (see: src)
In this example the 'src'-folder just contains a HelloController.php-file which contains the Controller
.
<?php
namespace Graphit\Examples;
use Graphit\Core\Controller;
class HelloController extends Controller
{
public function indexAction()
{
return $this->renderHtml('index.twig', ['person' => 'World']);
}
public function namedAction($person)
{
return $this->renderHtml('index.twig', ['person' => '\''.urldecode($person).'\'']);
}
}
A Controller
contains the methods that should be executed by the router based on the defined routes. (see: graphit/giwt/Controller.md)
A few things are important for a controller:
Graphit\Core\Controller
.Graphit\Core\Response
(see: Response).
In this example both methods call the 'Controller->renderHtml'-method to specify a variable 'person' for the 'index.twig' Twig-template. The only difference is that 'indexAction' accepts no method parameters and always sets 'person' to 'World', where as 'namedAction' accepts a parameter named $person
, urldecodes it and adds ticks around it.
When ever Twig-templates are used they get placed inside the 'views'-folder. Here's how the index.twig-file looks like in this example project.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello Example</title>
</head>
<body>
<p>Hello {{ person }}!</p>
</body>
</html>
The above template represents a simple html-page which will show "Hello PERSON!", where PERSON is the argument given to the renderHtml-method of the Controller-class.
The web-folder contains the index.php and any additional needed web-ressources like .js, .css or image files. All these type of files should be put in separate subfolders (.js-files in a 'js'-subfolder,...).
Since we got no additional web ressources the web-folder of this example only includes a single index.php-file.
<?php
require_once __DIR__.'/../vendor/autoload.php';
define('APP_BASE_PATH', realpath(__DIR__).'/..'); // set application path
Graphit\Core\Dispatcher::dispatch('app', true); // dispatcher(NAME_DER_CONFIG, DEBUG)
Inside the index.php-file we:
Assuming you read the tools and infra structure-page, the rest of this page and the Internals-page, we recommend to start with the 'Hello World'-example project and expand and change it.
You also should:
Side note: For testing an application on a system without a webserver it is often helpful to use PHPs own webserver for testing.
cd web
php -S localhost:8000
will start a local web server which can be accessed through http://localhost:8000. (see: PHPs built-in web server)