Trendly: Trends for Google Analytics

Don’t you just love APIs? Unless you were never a fan of Google Analytics, you would have heard of the Google Analytics Data Export API. It allows developers to make good use of the data collected in a Google Analytics account by churning better reports, integrating information into an existing application or whatever creative ways you can think of. This is exactly what the guys at Smallthought Systems, makers of DabbleDB (which I recommend you check out as well), did by coming up with Trendly.

I wanted to post a full review but since Trendly did a good job of explaining how it works, I got lazy. The idea is simple. Google Analytics shows you how many visits each traffic source generates but it will probably take more than a few clicks to understand exactly which source brings you the most traffic last month and even harder to understand how this same source trends compared to other sources over the last couple of months. Trendly does exactly that in 4 clicks:

  1. Click to try Trendly for free.
  2. Allow Trendly to access your Google Account.
  3. Choose the profile you would like analysed.
  4. Wait for email notification to Trendly results and click on the link provided.

Trendly is still in preview phase so do go ahead and try for free while you can! On a side note, Enhanced Google Analytics Firefox extension does something similar on a smaller scale.

Any more interesting projects making use of the Google Analytics Data Export API that I should know of?

Bookmark and Share
Posted in Uncategorized | Tagged , , , | 1 Comment

iPhone OS 3.0 Bug with Group MMS (or rather SMS)

Bug bug! Contrary to the 12 bugs in iPhone OS 3.0 that Woot found, I only encountered 1 not in the list. I just sent 5 MMSes instead of SMSes yesterday without noticing that the iPhone shows Group MMS instead of Group SMS whenever you add more than one recipient to the list.

iPhone OS 3.0 Group MMS Bug

This has been confirmed by other users as well so it can very well be an actual bug. Now the only solution will be to switch MMS Messaging to Off whenever you want to send a group SMS. More bugs?

Bookmark and Share
Posted in Uncategorized | Tagged | 5 Comments

How-to: iPhone Tethering via Bluetooth on a Mac

Alright. Everyone is excited with the just released iPhone OS 3.0 and so am I! To be honest, I have never used Bluetooth on a Mac before and the way to setup tethering just feels a little different from what I expected. No, I did not try tethering via USB since I very much prefer wireless. The steps below should work for anyone whose mobile service provider (I am on SingTel by the way) does not explicitly disable tethering.

  1. Ensure that the settings Internet Tethering and Bluetooth is set to On on your iPhone.
  2. Click on the Bluetooth icon on the menu bar (the top right corner of your screen with lots of icons).
  3. Choose Set up Bluetooth Device.
  4. Click Continue then Mobile phone and Continue again.
  5. Ensure that you are on the Bluetooth settings page on your iPhone. You should see your iPhone listed under the list of Mobile Phones then click Continue and Continue (notice the number of Continues?) again.
  6. The Bluetooth Setup Assistant on your Mac should now be showing the PIN required to pair up the iPhone so just enter the PIN as shown into your iPhone and “touch” Connect.
  7. Now, your Mac and iPhone are finally paired. Ensure that Use device as a network port is checked and click Continue.
  8. Congratulations and we are done with the set up!

Every time you wish to connect to the Internet via your iPhone, click on the Bluetooth icon on the menu bar again and choose Your iPhone > Connect to Network. Once connected, you should see a nice blue Internet Tethering banner pulsating on your iPhone. Have fun!

Bookmark and Share
Posted in Uncategorized | Tagged , , | 7 Comments

Upgraded to WordPress 2.8

Cool, WordPress upgraded from 2.7.1 to 2.8 in seconds! Can’t wait for Drupal to follow suit with automatically upgrading (OK, one-click upgrade) of modules and core. Definitely not easy to keep Planet CakePHP updated since it is quite a chore to download updated module, disable current module, unzip and override,  re-enable module, run update.php and finally done. Worst when you need to upgrade Drupal core. One thing however, that I liked in Drupal, would be the maintenance mode which is absolutely useful from keeping visitors away while the things get upgraded or screwed up. :p

Bookmark and Share
Posted in Uncategorized | Tagged , | 2 Comments

Tracking Country Specific Google Search Engines in Google Analytics using Filters

Tracking additional search engines (see 1, 2 and 3) in Google Analytics is hardly a new thing. The usual method of adding additional search engines to be tracked would be to use the _addOrganic() function of the tracking code. While that works perfectly, I would like to propose a different way of achieving the same results using filters in Google Analytics.

The advantages of using filters:

  • You can (and you should) create an additional profile with the same tracking ID to track country specific search engines while leaving the original profile for an overview. Calling _addOrganic() will modify all the profiles with the same tracking ID.
  • Visitors to your website do not have to load a long list of JavaScript code containing all the additional search engines you want to track therefore reducing some (minimal) load time.
  • There should be no changes required even if Google deploys another search engine at If you call _addOrganic() with a static list of search engine names, you will have to add and update your list of search engines to track.

This is an example of the steps required to track additional Google search engines using a single filter:

  • Create an additional profile with the same tracking ID.
  • Add a new filter with filter type as “Custom Filter” and choose “Advanced“.
  • Select “Campaign Source” under “Field A -> Extract A” and enter “^google$” as input.
  • Select “Referral” under “Field B -> Extract B” and enter “^http://www\.(google\.[^/]*)” as input.
  • Select “Campaign Source” under “Output To -> Constructor” and enter “$B1” as input.
  • Set “Field A Required” to “Yes“.
  • Set “Field B Required” to “Yes“.
  • Set “Override Output Field” to “Yes“.

What this filter does is to check that the traffic source is one of Google’s search engines and thus extract the “” part from the referral field (usually something like “…“) then show the search engine source as ““. Do take note that while this is an example for Google search engines, the same steps (with slightly different input) will work with other search engines.

Bookmark and Share
Posted in Uncategorized | Tagged , | 8 Comments

CakePHP’s HtmlHelper::link() Escaping of Attribute Values Gotcha

Just updated pHing Classifieds to CakePHP and that breaks some JavaScript codes for deleting of messages. Turns out the escape attribute is now passed on to Helper::parseAttributes() so if you have an image link like me, you will have to remember to manually escape the attribute values.

<?= $appHtml->link(
      'escape' => false,
      'onclick' => h('if (confirm("True?")) alert ("Yes"); return false;')
) ?>

Not a big issue and it probably seem more consistent that the escape option is applied to both the link title and the HTML attributes. See ticket #6071 for why it was changed and what was changed.

Bookmark and Share
Posted in Uncategorized | Tagged , | Leave a comment

Middle Click to Open Links in a New Tab in Firefox on a Mac

I have always been irritated by the fact that I could not middle-click to open links in a new tab in Firefox on a Mac. This is one of the most used action while web browsing on a PC yet I have to do a command-click while on a Mac. But I am glad I finally found a solution! I am using Microsoft’s IntelliMouse Explorer 3.0 and it seems like by installing the software for the mouse, I get to configure the behavior of the wheel button used for middle-clicking. Call me silly but I have never bothered with any mouse software/drivers on Windows.

So how this works is you basically download the software for the mouse from Microsoft Hardware and install! After installation, open System Preferences and you should see “Microsoft Mouse” under the group “Other”. Now all you have to do is to set your assignment of the “Wheel Button” to “Handled by Mac OS”. That’s all and it works perfect. One less switch to a Mac problem. :p

Microsoft Mouse System Preferences

Bookmark and Share
Posted in Uncategorized | Tagged , , , | 3 Comments

Working with Associations using CakePHP

I was asked by Niraja Mulye of Packt Publishing if I would be interested in publishing an article on my blog from the book, CakePHP Application Development. Since it seems relevant to any starting out with CakePHP, I guess why not.

Instead of copying and pasting what was sent, I found two articles which seemed like the original source. Being properly formatted, I guess it will be more appropriate for me to point them to you. The first article titled, Working with Simple Associations using CakePHP talks about the basic belongsTo, hasOne and hasMany assocations while the second article titled, Working with Complex Associations using CakePHP tackles the hasAndBelongsToMany association where most beginners have difficulty with.

The articles will be useful for anyone starting out but unfortunately, CakePHP had gone through lots of changes and the book (published on July 2008) is based on an older version of CakePHP. So now there are actually better ways of dealing with associations using the Containable Behavior. The Containable Behavior binds and unbinds model on the fly, automatically setting the recursive level to suit. This means you no longer have to bother about setting the recursive level as long as you “contain” your find() queries. I am mentioning this because I have to warn against the setting of recursive level directly.

// All models have recursive level set to 1 by default
$this->Author->recursive = 2;
$this->Author->id = 1001;
$this->Author->find('first'); // Return results based on recursive level of 2
// some
// codes
// in
// between
$this->Author->find('all'); // Return results based on recursive level of 2 (as set previously) and not 1!

This causes CakePHP to retrieve more data than it should when it is unintended by you. My suggestion is to have all models default to recursive level -1 by setting it in the AppModel and let “contain” handle the rest.

$this->Author->id = 1001;
$this->Author->find('first', array('contain' => 'Book')); // Returns author 1001 and all books authored by him/her
$this->Author->find('all'); // Returns all authors only

How nice!

Bookmark and Share
Posted in Uncategorized | Tagged , , , | 1 Comment

What a Start to 2009

5 days of downtime and finally back online. A faulty RAID card leading to all sorts of restoration problems. Totally unacceptable. I have to probably start looking out for a new web hosting provider but what a hassle. :(

For fellow Planet CakePHP subscribers, I apologise for having you missed 5 days of CakePHP news. Now that it is back, keep reading.

Happy New Year!

Bookmark and Share
Posted in Uncategorized | Tagged , | 1 Comment