Use Google Analytics on every page using Apache
I’ve recently set up my own server at home, containing all the pictures and data I did not want to host on Facebook, Hyves (dutch Facebook), Picasa or even Photobucket (ugh!) any longer. Sometimes when I’m at home I hear my server crunching some numbers although I would not even be using it, so I was wondering what exactly it was doing. I started looking for a PHP apache/server request monitoring application so I could ‘check’ what the server would be doing or serving, but could not really find anything useful. I then decided to just use Google analytics.
I have multiple applications running on the server (phpmyadmin for database administration, ampache for streaming music, a svn directory, the excellent Deluge web client, the great eXtplorer filemanager and the wonderful Gallery3 image gallery) so it was not very feasible to edit every template and inject the required G.A. javascript.
Apache however has enough modules that make our life easier and I found this little explanation by Oliver Zheng explaining how to setup Apache so it injects a string on every served page.
Configure apache using Mod_substitute
First, you have to enable the subtitution module in apache. (For me) this was as easy as issuing a
sudo a2enmod substitute
Then, tell apache to insert a snippet on every page:
<VirtualHost *:80>
...
<Location />
AddOutputFilterByType SUBSTITUTE text/html text/plain
Substitute "s|</body>|<script type='text/javascript'>var gaJsHost = (('https:' == document.location.protocol) ? 'https://ssl.': 'http://www.');document.write(unescape('%3Cscript src=\'' + gaJsHost + 'google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E'));</script><script type='text/javascript'>try {var pageTracker = _gat._getTracker('UA-1234567-1');pageTracker._setDomainName('.yoursite.com');pageTracker._trackPageview();} catch(err) {}</script></body>|i"
</Location>
</VirtualHost>
Note that the substitution string needs to consist of a single line only. Replace the UA-XXXXXX-X code with your Google Analytics tracking number and replace .yourwebsite.com with your actual website address.
Finally, restart apache. (May differ across platforms..)
sudo /etc/init.d/apache2 restart
The first page visits will be recorded somewhere within 24 hours.
Other
A module has been written for Apache that does exactly the same, albeit a bit cleaner. It can be found here: https://github.com/dragon3/mod_google_analytics (I have not this one)
Kirill Minkovich has written about this as well: http://cadlab.cs.ucla.edu/~kirill/analytics.html
Disable foreign key checks in MySQL
I frequently need to disable the foreign key constraint checks in MySQL when developing, but i often forget the command.
Here it is:
SET FOREIGN_KEY_CHECKS = 0;
Prepend this to the SQL query you are running to disable foreign key checks in the query that is about to be processed.
Using Dia in one-window mode on Linux
I study Information Sciences, so i have to make a lot of diagrams. As I’m on Linux, Dia is the editor of choice.
However, just like GIMP, it suffers from the fact that the the toolbox window is for some reason separated from the diagram editor.
The windows version though, operated in one-window-mode out-of-the-box!
Today, I have finally found out how to run Dia on Linux in one-window mode:
start Dia like this:
dia --integrated
It’s that easy. I don’t understand why this is not the default option on Linux.
How to: Integrate Invision Power Board in Kohana (and possibly every other forum)
After integrating a blog in my Kohana install, I wanted a forum.
Many, if not all, websites that ‘integrate’ professional forum software such as PhpBB, vBulletin or Invision Power Board (IPB) by setting up a separate page or subdomain to host the new environment, and try to mimic their own website header in the header of the forum. This should give the feeling that the forum is just another page because the header is the same. However, I wanted a tight integration between Kohana and the forum software so I wanted to (again) integrate the forum into Kohana.
The result of the integration will look like this: (the example shows IPB integrated in a fixed-width website of mine)
Note that the board in the image has no styling whatsoever applied to it beyond the default skin.
Here’s a list of what we are going to do:
- install IPB installation
- configure installation
- create Kohana view
- create Kohana controller
- setup routing
- create custom Kohana router
Let’s start.
First, install IPB in a folder in your Kohana project folder, this should not be much of a problem. I installed it in a folder called ‘ipb’. By now, my Kohana project folder looks something like this:
- application
- system
- wordpress (the integrated WordPress installation)
- ipb (the to be integrated installation of IPB)
The installation has to be configured to work with Kohana, let’s do this now.
Proceed to the admin panel of your forum and do the following:
- disable gzipped compression in System Settings -> Server Settings
- enable the use of .htaccess using Apache Mod_Rewrite
The code
I have a Kohana view called ‘forum’ which is basically a copy of IPB’s index.php in a Kohana view. This view loads the IPB environment. It looks something like this:
<?php define( 'IPB_THIS_SCRIPT', 'public' ); require_once( './ipb/initdata.php' ); require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' ); require_once( IPS_ROOT_PATH . 'sources/base/ipsController.php' ); ipsController::run(); //exit();
Note that the exit command was commented out because the Kohana environment should not be terminated after processing this view.
IPB has another built-in exit command that makes sure the environment unloads after each request that should be disabled. This exit command can be found in the following file: {ipb root directory}/admin/sources/classes/output/publicOutput.php at the end of function sendOutput() on line 2183. Just comment it out.
Now we should create a controller that accepts parameters and URIs and forwards them to the IPB environment. The following code is based on the controller we created when integrating WordPress with Kohana.
Here’s the controller:
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Forum_Controller extends Page_Controller {
// laad IPB view
public function index()
{
// haal request op
$url = url::current(TRUE);
if (strpos($url, 'forum/public') !== FALSE)
{
$url = str_replace('forum/public', 'ipb/public', $url);
url::redirect($url);
}
// admin area
if (strpos($url, 'forum/admin') !== FALSE)
{
echo new View('forum');
exit;
}
Kohana::log('info', 'Forum request caught: ' . $url);
$this->template->content = new View('forum');
}
public function params($param1, $param2='', $param3='', $param4='', $param5='', $param6='')
{
$this->index();
}
}
Next, we need to route the forum requests to our controller. Append this to your routing configuration file:
$config['forum/([A-Za-z0-9-_\./=\?&,]+)'] = 'forum/params/$1';
Now, open the file conf_global.php in the IPB root directory and change the ‘board_url’ setting from the name of the name of the IPB root foler to the name of the forum controller, like this:
$INFO['board_url'] = 'http://localhost/forum';
There’s only one step left, which is a custom Router class.
Copy Kohana’s Router.php file from system/libraries/Router.php to application/libraries/MY_Router.php. Open the copied file and change the class declaration to this:
class Router extends Router_Core {
Find the following line:
Router::$current_uri = (string) substr(Router::$current_uri, $strpos_fc + strlen(KOHANA));
and modify the line to this:
if (strpos(Router::$current_uri, '/forum') !== 0)
{
Router::$current_uri = (string) substr(Router::$current_uri, $strpos_fc + strlen(KOHANA));
}
That’s it for the code!
The explanation
So, how does this little puzzle work? When loading the /forum page, the content of IPB’s index.php page inside your forum view loads the forum and renders it inside the view. Rendering the page at all succeeds because we turned off the gzip compression from within IPB. The admin area is rendered without the website template because we echo the view directly. Kohana’s page rendering process won’t get interrupted because we prevented IPB from terminating the PHP environment by disabling the exit statements. IPB ‘thinks’ it’s root folder is named ‘forum’ because we changed the ‘board_url’ option in IPB’s configuration. The consequence of this is that every forum url get’s routed through our forum controller. Our controller merely accepts the parameters, starts the forum software and renders the board. The forum software itself fetches the parameters from the url and generates the corresponding page. There was one problem though: other files such as javascript and css files were routed through the controller as well and were left to the View to figure out what to do with them, which wouldn’t work. Therefore, the controller had to do some routing on it’s own, so we rerouted every file to IPB’s ‘public’ folder (where the CSS files reside) and the ‘admin’ folder to the corresponding folders in our IPB installation directory instead of the view. So why did we need to customize Kohana’s Router? With clean urls enabled in Kohana, Kohana tries to remove the index.php from the url. However, Kohana screws up when the links generated by IPB contain an index.php by itself. The default behaviour performed by the Router was to route every IPB url that contained an index.php to the frontpage of your site, so we had to modify it to disable the removal of index.php from urls targeted at /forum.
That’s basically it. As you can see, the method is quite similar to the method we used to integrate WordPress in Kohana.
About breadcrumbs in browsers
This is something I’ve been wondering about for a while, and I would like to know what you think.
Every navigational component that is able to browse paths these days is moving towards navigation by breadcrumbs: the Windows Vista/7 file manager, linux file managers and websites are just a few examples. Even the preference pages of Firefox 4 are getting breadcrumbed navigation.
The component we use the most however, is still supporting text-based navigation: the browser. So my question is, why don’t we use breadcrumbs for website addresses?
There have been a lot of cases when I would really like to use breadcrumbed navigation in the URL bar of the browser. Here follow some cases I found myself in.
Case: editing the URL
Suppose I go to http://www.example.com/intuitivity, I would find out that the URL does not exist. Well then, I would like to edit the address so it would point to a correct URL, such as http://www.example.com/existingurl. I begin by clicking the address bar, and here begins the agitation. Some browsers respond to this clicking action by placing a caret on the position you clicked so you are able to edit the path (in this case, this would be the desired action). Other browsers however, automatically select the whole URL, because they assume you want to enter a completely new URL. In that case, you would have to click a second time to place the caret.
Case: navigating the site by browser
Websites have moved to more and more semantic URLs and paths, such as http://www.intuitivity.org/archives/38. This URL clearly says that you are currently viewing post #38 that resides in the archives, on the website intuitivity.org . This URL hints that the URL http://www.intuitivity.org/archives would also be a valid URL (it isn’t, but could be). It would be fairly easy to navigate to that URL by editing the URL and removing the post id. Alternatively, it would be fairly easy to navigate to another post by editing the URL and replacing the post id with another. But why do we have to textually edit this path when it behaves just like a path on a local file system?
Solution: breadcrumbs
Suppose the browsers would render their address bars as breadcrumbs, then every element of a URL would be a crumb. In the example of http://www.example.com/intuitivity, the crumbs would consist of: [http://] [www] . [example] [.] [com] [/] [intuitivity]. (Unfortunately, the dots would require their own crumbs because multiple subdomains and custom URLs may exist)
Every crumb needs to be able t perform 3 actions:
- edit the textual contents of the crumb
- navigate to the path denoted by this crumb
- navigate to other paths in the same hierarchy as this crumb
To be able to perform these actions for every breadcrumb, we divide the crumbs in 3 parts:
- a small rectangular region on the left of the crumb that would render the crumb, the whole crumb and nothing but the crumb as flat text when clicked, so we could easily edit the part of the path denoted by this crumb. It would automatically select the whole text, just as the browsers do now with the complete URL, so we may retype the crumb. After hitting the ‘return’ key, the browser will render the newly entered text as a crumb again, or remove the crumb completely if there was no text entered.
- the largest region in the center that displays the contents of the breadcrumb. When this region gets clicked, the trailing breadcrumbs would be removed and the browser would navigate to the URL that would end in this breadcrumb. Imagine you are visiting http://www.example.com/intuitivity/post and you would like to return to the page http://www.example.com/intuitivity, you would only have to click the [intuitivity] breadcrumb. The usability could even be enhanced by making the browser check for the path of the crumb to exist, and disabling this area of the crumb if the path wouldn’t exist (and would effectively render a ’404 – page nout found’ error).
- a small region with an arrow pointing down, just like a drop-down box, that would show the available alternative paths in this path hierarchy when clicked. If there are no alternative paths available or known, this area would be disabled. (Windows Vista/7 explorer supports this alternative path drop-down feature) This would be a logical possibility for breadcrumb denoting the URL protocol, as there are only a limited number of defined protocols. Switching from http:// to https:// would require only a single click.
The breadcrumb bar as a whole should be able to perform these actions:
- rendering the breadcrumb bar as a single string of text, for entering a new URL or editing strings that are part of 2 or more crumbs.
Browser breadcrumbs could even provide visual hints to show different types of URL segments. Crumbs consisting of query string parameters could be given a special color, or a special shape, as an indication.
Problems and discussion
Duplicate functionality
I know one of the counter arguments: ”why do we need breadcrumb navigation in the browser when websites provide navigation themselves?”. This is a valid point, but the possibilities do not exclude each other.
- breadcrumbs in the browser would make the browser more consistent with the rest of the system where we have already gotten used to breadcrumbs
- because of the available screen size for the browser, navigation may be possible to deeper levels than the navigation of the website perhaps could provide. Many WordPress blogs (including this one) have a list of most recent posts in the sidebar. This is often a short list as the sidebar hosts other widgets too that should be visible. Browser breadcrumbs however, when clicked, could show the user a big list of posts by using the screen size of the desktop instead of being limited by the window of the browser.
Providing alternative paths
I don’t know whether browsers are able or allowed to query websites for the contents of a specific path. This would be necessary for the browser to be able to provide the user with alternative paths. As an example: if we are visiting http://www.intuitivity.org/post/2, it would come in handy if the browser somehow knew that a post with the id 1 would exist so that it could provide http://www.intuitivity.org/post/1 as an alternative path when we click on the drop-down part of the [2] crumb. Alternatively, the browser could provide just the known alternative paths that we have already found or visited (when you have already read post #1 i.e.)
Key actions
With the ‘classic’ address bar, it is clear what would happen when we hit the return key after entering or editing a URL. I have not yet thought about how the bar should react to the return key in its different states (normal state, breadcrumb editing state).
So, what do you think?
Todo
Create some mockups, because a picture… you know.
Sources
Firefox 4 mockup: http://blog.stephenhorlander.com/2010/06/01/in-content-ui-visual-unification/
Nautilus Elementary screenshot: http://ammonkey.posterous.com/combined-mode-button-for-nautilus-elementary
Windows explorer: http://www.microsoft.com/presspass/gallery/screenshots/windows.mspx
Edit
A friend pointed out there already exists an add-on for Firefox implementing parts of this specification called: Locationbar², which may be found here: https://addons.mozilla.org/en-US/firefox/addon/4014/
This add-on highlights the domain and separates the URI segments. These segments are clickable by holding CTRL, ALT or META.
What this add-on does not do is creating segments for query string parameters, providing the ability to quickly edit a segment, and providing the ability to navigate to alternate paths in the same hierarchy.
How to: Integrate WordPress in Kohana
There are many projects trying to integrate Kohana into WordPress, like here, but I wanted the exact opposite. I wanted seamless integration of WordPress in my Kohana website, with clean urls and all.
Yesterday, I finally managed to get the integration of wordpress inside the great Kohana framework working, after three days. Here’s how I did it.
My wordpress installation (v3.x) is located in the directory of my Kohana project (v2.x) so it looks like this:
- application
- system
- modules
- wordpress
- (… etc …)
The Code
I have a Kohana view called ‘blog’ which contains the standard WordPress program loop, but also contains the inclusion of the WordPress environment. This view loads the wordpress environment. It looks something like this:
<?php require_once('wordpress/wp-blog-header.php'); ?>
<h2>Blog</h2>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
*wordpress loop*
<?php endwhile; else: ?>
<?php _e('Sorry, no posts matched your criteria.'); ?>
<?php endif; ?>
*wordpress loop* is the place where ‘The Loop’ of WordPress should reside which loads the post as explained here: codex.wordpress.org/The_Loop
Next, we need a Kohana controller for the blog view.
My Blog Controller looks like this (also shortened):
class Blog_Controller extends Page_Controller {
public $template = 'template/page';
public function __construct()
{
parent::__construct();
}
public function params($param, $param1='', $param2='', $param3='', $param4='', $param5='')
{
$this->template->content = new View('blog');
}
}
And I have added a single routing rule:
$config['blog/([A-Za-z0-9-_/=]+)'] = 'blog/params/$1';
That’s it for the code. Easy no?
The Explanation
What all this does:
- when someone visits the /blog page (controller), the blog view is rendered.
- the blog view includes the WordPress environment and loads the posts
when a page within wordpress is loaded, for example, /blog/archives/13/14/stuff, the following happens:
- the routing rule routes everything to the ‘params’ function within the blog controller.
because the wordpress clean urls feature is turned on, the ‘/archives/13/14/stuff’ part gets interpreted as arguments by Kohana, so we need enough defined parameters in the params function in the controller.
- the controller does absolutely nothing with the parameters, it merely accepts them and prevents generating a 404.
- the view gets loaded
- wordpress processes the url and loads the corresponding page.
That’s it… accept for one thing. WordPress expects to be loaded as a single package. This means that it expects to have its own index.php file, from where the environment is loaded. However, this is not the case in our installation, as the wordpress environment gets loaded by our view.
Our view gets loaded by Kohana’s index.php. You might notice the problem here…
As wordpress processes the url, it thinks the index.php is its own, and thinks /blog is the name of a page within wordpress, which is not the case. /blog is actually the document root for WordPress, but it doesn’t know this. The solution is to fake the document root from the perspective of WordPress. This may be done by the following:
The wordpress environment contains a file called ‘classes.php’. This file contains a function called
'parse_request($extra_query_vars = '')'
.
Within this function, add the following line:
$pathinfo = str_ireplace('/blog', '', $pathinfo); // /blog is the name of your blog controller
Below the following code block:
if ( isset($_SERVER['PATH_INFO']) ) $pathinfo = $_SERVER['PATH_INFO']; else $pathinfo = '';
This fakes the document root for WordPress. It’s a bit hacky, and if a cleaner solution is possible (I guess, something with .htaccess), please let me know
This last bit works by removing your controller name from the pathinfo. Pathinfo is the path that comes after the index.php, but before the query string.
The PHP documentation (http://php.net/manual/en/reserved.variables.server.php) says this about pathinfo:
Contains any client-provided pathname information trailing the actual script filename but preceding the query string, if available. For instance, if the current script was accessed via the URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, then $_SERVER['PATH_INFO'] would contain /some/stuff.
Now, the wordpress blog should feel like it’s just a Kohana page or module.
Note: because the complete wordpress installation is still in /wordpress, the official template version of the blog can still be accessed from localhost/wordpress (for example), because it still contains its own index.php
Disclaimer: I haven’t tested this thoroughly.

