Developing Using the Framework

Adding a new page

The Framework is entirely driven from the database so you have to add new pages using the Admin > Pages menu item as this will create the necessary database entries. You will normally chose either a Template or a Object page — all the other options are for redirecting to other URLS, either internally or externally. If the page is essentially static, that is it has no sub-pages or does no form handling, then you should chose Template, otherwise chose Object.

If your system has appropriate access permissions then adding a page, let's say called example, will create a file called twigs/content/example.twig. If you have chosen an Object type, then it will also create class/pages/example.php. If these files do not appear then you should create them yourself based on the structure contained in the files sample.txt that are in the class/pages/ and twigs/content/ directories. Remember to rename the class from Sample to whatever your page name is, and to fill in the various comment fields with relevant information.

Headers, footers etc.

The directory twigs/surround/ contains files that can contain page headers and footers that will appear by default on every page. These are distributed as empty so no footers or headers will appear. The file navbar.twig controls the content of the navigation bar that appears at the top of each page and this is where you should add new menu items. Be careful not to remove the Admin menu items!

Predefined Twig Variables

The Framework automatically sets up up some Twig variables containing useful values:

  • assets — use when linking to css files etc. : <link rel="stylesheet" href="{{assets}}/css/extra.css>
  • base — use when building local URLS : {{base}}/operation
  • context — the context object. Gives access to basic information e.g {{context.hasadmin}}
  • action — the action that triggered the current page i.e. the first part of the URL : /about => about
  • siteinfo — an object with utility methods to retrieve site related things e.g. all the users on the site {{siteinfo.users}}
  • ajax — see below
  • usebootbox — see below

If you are using the pagination features provided by the framework then there will be two more variables:

  • page — contains the index of the current "page". Note the index starts at 1 for user convenience
  • pagesize — contains the maximum number of elements that can appear on the page

If you wish to use pagination in your site, look at how various admin parts of the framework use it. There are functions that support pulling from the database in pagesized chunks.

If your page uses AJAX then the relevant twig file should contain
{% set ajax = TRUE %}
before any extend or include commands. This ensures that a suitable version of jQuery is included when the page loads.

By default the JavaScript for using the BootBox messaging package is included on every page. If you do not need it then you can stop it being included by adding
{% set usebootbox = FALSE %}
before any extend or include commands.

File uploading/downloading

The Framework provides you with a complete set of operations for handling file uploads and downloads should you chose to adopt them. There are two settings in the installer that will affect how these work: one that allows uploads that have no access control and one that enforces access control. No access control uloads are stored in the directory public in the assets directory, and access controlled files are stored in the directory private which is in the root of the framework. Both these directories need to be read and write accessible to your web server - the installer will ensure this but if you add these features later you will need to set permissions correctly.


When you are handling an upload, you need to use code similar to this:

$upl = \R::dispense('upload');
$upl->savefile($context, $fa, $acc, $user, $ix);


  • $context is the system context object
  • $fa is the file data retrieved from the input using either FAIterator or FormData
  • $acc is TRUE if the upload is not to be access controlled otherwise FALSE
  • $user is the user bean for the owner of the file
  • $ix is the index value if the upload is associated with an array (this is potentially only used if the addData facility is being used and you are wanting to access other form fields that are also arrays.


The Framework provides code that works with the public/private structure for downloading files. Go to the Admin > Pages menu item and a add a page called private of type Object with classname \Framework\Pages\GetFile and mark it as active. Then in your twig you can make a link to {{base}}/private/file/{{upload.getID}} where upload is the Upload bean associated with the file you want to download.

When a file gets downloaded using \Framework\Page\GetFile, it will call the method downloaded that is defined in class/modelextend/upload.php. In this method you can implement whatever you want, e.g. download counting.


There is a replace method for uploads defined in class/model/upload.php. This lets you replace the uploaded file with another file, without creating a new upload bean. updateData from class/modelextend/upload.php if there is anything special you need to do when an upload is replaced.


There is a delete method for uploads defined in class/modelextend/upload.php. This handles removing the file and does anything else that you want to add to this function. It does NOT delete the database entry. You have to do this yourself using the Redbean \R::trash function AFTER you have called the delete method. This delete method will also be called automatically if you delete an upload bean via the AJAX bean operation.


There are lots of ways you can approach debugging your code when using the Framework. If you have a mailer set up on your machine then, if an error is detected, you will be emailed a message about error. However, it is not always possible or easy to set up a mailer on a laptop so the message should also appear on the screen. Note that for some reason on some Windows machines and some browsers the 500 HTTP status code is translated into a screen that implies that the site is not reachable. If you see this, then it is very likely that an error has arisen. You can test if this happens on your system by using the "Fail" or "Throw" items on the Developer dropdown that allow testing of the error handling system. These should show you a message and a stack trace, if not then you may have the mis-feature.

If you do get an Internal Error message on the screen or in mail and you need more information, you can re-run the page with the query string ?fwtrace=1 - this will generate an on-screen stack dump as well as the message. You can adjust the depth of the stack trace by also specifying fwdepth=n in the query string.

If you want to trace through your code, you can use the PHP echo command to send output, or the var_dump function to dump the contents of variables. There are also PHP debugger extensions such as XDebug that you can install on your system. The Framework provides you with a Debug class that generates output that is saved into a file in the debug directory in the top level of your site. It can also generate an X-Debug HTTP response header that is sometimes a useful way of seeing debugging information if you are using the network monitoring features in a browser.