2. Structure

2.1. Files and directories

Directory listing from root directory of henkari shows the following.

bash$ cd /dir/where/you/extracted/henkari
bash$ ls -la
drwxr-sr-x    7 terotil  users        4096 Jul  1 13:08 .
drwsr-sr-x    8 terotil  users        4096 Jun 25 13:39 ..
-rw-r--r--    1 terotil  users       17983 Jul  1 11:10 COPYING
drwxr-sr-x    5 terotil  users        4096 Jul  1 14:07 doc
-rw-r--r--    1 terotil  users          85 Jun 24 18:53 example.htaccess
-rw-r--r--    1 terotil  users        1378 Jul 30 15:29 index.php
drwxr-sr-x    3 terotil  users        4096 Jul  1 11:41 lib
drwxr-sr-x    5 terotil  users        4096 Jun 25 11:05 root
-rw-r--r--    1 terotil  users         952 Jul  1 13:08 TODO
bash$

COPYING contains license and TODO describes the road ahead. Documentation is found from doc/, program code from lib/ and website from root/. index.php is entrypoint script to Henkari. example.htaccess contains an example of Apache (mod_rewrite) configuration to hide index.php from url. There may be something else too, but you need to know only these.

2.2. How does it work (by example)

Henkari works recursively starting from it's root web-directory (default is root/ under entrypoint) and ending to requested file/directory. On each step forward along the request path (when there's still path left) a decision is made: Who handles the the next step? Configuration files placed on directories that are examined during a single request can have effect on the result. For example they can change the rules which provide answer to the previously presented question.

Let's have an example. Assume Henkari's entrypoint script index.php in /entry/point/dir/ which is seen as http://www.somesite.net/somepath/ by J. Random Surfer. Now in default Henkari configuration the website is located in /entry/point/dir/root/. Assume we have there a configfile /entry/point/dir/root/.henkari

 <?php

 // Get singleton instance of handlerFactory.
 $hf =& handlerFactory::getInstance();

 // Register a handler for html-files.
 $hf->registerHandler('text/html', 'htmlHandler');

 ?>

a template /entry/point/dir/root/_template.html

 <html>
   <head><title>{title}</title></head>
   <body>
     <div style="width: 65em">
 {content}
     </div>
   </body>
 </html>

and a webpage /entry/point/dir/root/random/page.html

 <html><head><title>Footitle</title></head>
 <body>
   <p>This is a foopage.</p>
 </body></html>

Now when request is made to retrieve the assumed page, url looks (without any server-side tricks) like this: http://www.somesite.net/somepath/index.php/random/page.html. This causes webserver to execute entrypoint script http://www.somesite.net/somepath/index.php, which (when caching is on) checks if the page has been requested before and saved to page cache. If it's not, it parses remaining path /random/page.html to array ("random", "page.html"). Then it asks handlerFactory to return a proper handler for /entry/point/dir/root/, gives the previously parsed array to the returned handler and calls it's handle() -function.

Handlers share common interface and are instantiated by handlerFactory. It decides which handler gets instantiated for which file. The decision is made upon file's type (is it a directory, symlink, regular file, etc.) and name.

Because /entry/point/dir/root/ is a directory handlerFactory instantiates a dirHandler. First dirHandler searches "current directory" (/entry/point/dir/root/) for configuration files and template. Configuration file .henkari (See Section 3.3.3) is found and evaluated as php-code. It tells handlerFactory which handlers to use with files of certain mimetype. Template (/entry/point/dir/root/_template.html) is found too and user interface (an instance of UI) is ordered to use the newly found template. Then handler searches current directory for entries not beginning with dot or underscore and not ending with tilde and adds them to TOC. In this case there's only directory random/ (See Section 3.3.2). Next thing dirHandler does is to check if there still is path left to travel. It pops "random" from the left end of ("random", "page.html") and thus reduces the array to ("page.html"). Then it appends popped "random" to "current directory" resulting /entry/point/dir/root/random/, asks handlerFactory a handler for it and passes control to returned handler along with remaining path ("page.html").

/entry/point/dir/root/random/ is directory too, so handlerFactory instantiated and returned dirHandler and the same procedure starts again. Configuration files and template are searched, but not found. Directory is listed and page.html is added to TOC as child of random/. Then handler pops "page.html" from path, appends it to "current directory" resulting /entry/point/dir/root/random/page.html. Handler gives it to handlerFactory, requests a new handler and passes control to it.

File /entry/point/dir/root/random/page.html is recognized by Henkari to be of type "text/html". Evaluation of configuration file /entry/point/dir/root/.henkari registered htmlHandler to be responsible of mimetype "text/html". So handlerFactory instantiates htmlHandler and control is passed to it. Handler reads /entry/point/dir/root/random/page.html, extracts the contents of <title> and <body> and tells the UI to append them to page title and page content.

Handler recursion ends to htmlHandler and control passes back to entrypoint script, which commands UI to send page. UI uses data passed to it to render page.

 <html>
   <head><title>Footitle</title></head>
   <body>
     <div style="width: 65em">
 
   <p>This is a foopage.</p>
 
     </div>
   </body>
 </html>

Then (if no handler opted out caching) it saves the result with optional http-headers to page cache, sends it to browser of J. Random Surfer and exits.