Debugging
The previous two chapters explained the Ariadne template system. Combined with the content tree it allows you to create complex websites or web applications. But Ariadne itself is a complex system and it can become difficult to trace bugs to their origin. Fortunately there are a number of tools to help you find them.
You can install Xdebug and add breakpoints and step through the code in Ariadne, but you will find that this is not optimal. The code you are interested in is probably in a template and this means that it is almost impossible to set the breakpoint. Templates are loaded from the Ariadne store and run as anonymous methods — so it’s hard to set a breakpoint at the correct spot. But there are other tools that will help you find and isolate bugs.
The first part is finding the problem. A page in an Ariadne website is generally built by a combination of templates. These templates can be loaded from many different libraries, so finding the template that causes the problem can be difficult. For this reason Ariadne has a setting that adds comments to the generated output with the path of each object called, the name of the template and its location and the name of the library. Just add the following code to your view.html template:
<pinp>
ar::putvar('ARShowTemplateBorders', true);
</pinp>
This will add the following comments to the html output:
<!-- arTemplateStart
Data: psite /projects/demo/demo/
Template: /projects/demo/system/layout/default/ psite.view.title.html.any
Library:current --> <h1>
<a href="http://site ... demo/demo/">Demo Site</a></h1>
<h2>This is your demo site's tagline</h2>
<!-- arTemplateEnd -->
Now you can pinpoint the culprit and focus your debugging on the template that causes the problems. The problem itself may hide somewhere else ofcourse. Sometimes you need to inspect the properties of specific objects. There is no dialog builtin to Ariadne that allows this, but a very simple debugging template suffices:
pobject::printr.html
<pre><pinp>
var_dump($this);
$properties = load_properties();
var_dump($properties);
</pinp></pre>
Now you can call the printr.html template on any object and see which variables and properties are set for that object. Remember to remove this template or unload its library when you are done, since this may give too much info.
Sometimes the problem is that an object or template isn’t called where it should. The problem is finding out why. One main culprit is the language settings. Ariadne is a multiple language system, so (almost) every object can have different information for different languages. Ariadne figures out what the correct language setting is for each request, based on the URL in the original request. If the language for this request is for example ‘en’ or English, by default only objects with information in english will be used in the remainder of the request. Objects without a name in english will automatically be skipped by Ariadne’s store layer, unless you tell it otherwise.
<pinp>
ar::putvar('allnls', true);
ar::ls('show.html');
</pinp>
By setting the variable ‘allnls’ to true, all child objects will be called with the template ‘show.html’, even if they do not have the correct language set. Each object in Ariadne has a ‘default’ language. If the requested language is not available, Ariadne will switch to this default language and use that.
Another problem can be that you are looking at cached output. Ariadne has a builtin caching system with two levels: a ‘public’ page level cache and a ‘private’ template level cache. The public cache can be configured in Ariadne’s UI through the ‘cache’ dialog. Disabling it while debugging is generally a good idea. The private cache is configured in your template code — using the ‘cached’ and ‘getdatacache’ methods. The cache dialog has a ‘clear cache’ checkbox that will delete both the public and private caches for the entire subtree where you check it.
Finally there may be problems in your query syntax. So much is done in Ariadne with the ar::find() queries that simple mistakes here can lead to unexpected results. Ariadne provides a search dialog in the main toolbar. The ‘Advanced’ section allows you to test and debug your search queries in isolation. Any query that works here will work in your code.
If you come this far and still have no results, you’ll have to go into Ariadne a bit deeper. Ariadne comes bundled with a simple debug tool that you can trigger in your templates by calling the function ‘debugon()’. This function has one parameter, the debug level, which can be either ‘pinp’, ‘object’, ‘class’,‘store’ or ‘all’. For each level, starting at ‘pinp’, you will get more and more debugging information interspersed between the template output. You can stop the debug messages by calling ‘debugoff()’ at any point.
The debug messages are included in the normal output by default, but can also be sent to a seperate log file or even the system log (syslog). You can set the output channel in Ariadne’s main configuration file in lib/configs/ariadne.phtml.
$AR->DEBUG = 'WEB';
Valid values are ‘WEB’, ‘SYSLOG’ or ‘FILE’. If you specify ‘FILE’, you will need to configure the file to use. For this open the file lib/modules/mod_debug.php and enter an absolute file name and path in the $DB[“file”] variable. Make sure the webserver user can open and write to this file.
If you start with debuglevel ‘all’ you will probably be overwhelmed with all the debug output generated by Ariadne. CMS systems are complex and generally do a lot of configuring and initializing before they get to execute your code. It will require quite a bit of knowledge about how Ariadne goes about user authentication and authorization, configuration loading and finding the correct templates to run to understand it all. That is why there are a number of debuglevels to choose from. The ‘pinp’ level is the quietest level, it is not used by Ariadne itself, but meant for libraries of pinp templates to use. This means that you can add debug statements in your own pinp code and trigger only these messages by using debugon(‘pinp’).
You add a debug message in a pinp template like this:
<pinp>
debug('Your debug message','pinp');
</pinp>
The next level, ‘class’, will add debug messages from functionality in Ariadne’s content classes. The level ‘store’ will also tell you about stuff going on in the core of Ariadne’s storage system. And the final level ‘all’ will tell you about all the stuff going on behind the scenes.