Jan 04 2012
Here comes another chapter in my fights against Wordpress plugins' lack of quality code :)
For the small blog I have to toy with WP and try to optimize it, one of the tasks I had in the TODO list was setting up a mobile version. A while ago I did a quick search and found a few mobile plugins, both for administration ( which I'm not interested in) and for visitors browsing (let's call them 'mobile themes' although they require quite some coding).
I had three candidates, so this last nights I decided to test them, with terrible results: Some directly not work (or at least not render the homepage posts list), others were so ugly regarding source code, that once again I went the 'do it yourself' path (which usually is also the fun one).
My requisites:
- Do not reinvent the wheel: I don't want to code any complex Javascript, nor reimplement Wordpress and/or JQuery functions.
- Basic mobile site: Home/post list, individual posts, and as much as mobile placeholders for other "unsupported" pages (for example supporting rendering search results but not providing a mobile search page).
- Being able to toggle normal site back: Simple user story: I want to browse the normal version using my iPad, but not using my Phone. And I want to be able to choose.
- No UI from scratch: I am both bad and lazy when it comes to CSS.
- Support at least most grade A mobile devices: If it works in an old BlackBerry, nice, but I want iOS, Android, Windows Phone, Kindle and other current devices supported with HTML5 and Javascript.
JQuery mobile 1.0 has just been released, so It solved me two of the hardest requisites: It comes with nice themes (including a dark one!), it supports actual mobile devices, and I don't have to write almost any javascript for request handling (it intercepts and handles requests nicely).
I am not going to dig into how it works, because the documentation and samples are soo easy to follow. I built the whole mobile part in like two-three hours (counting some CSS overrides to better fit my desires).
I had a few other framework alternatives but this one was blazing fast to implement and as I was already using JQuery due to Wordpress, the impact was small (but I must say that 80KB for a mobile FW is a lot!).
As for how to plug a mobile theme into WordPress without rewriting much code, I went for the typical approach: Creating a plugin that switches the theme to the mobile one if detects a mobile device.
If you manage to do this, is the best approach, as you will reuse huge parts of your code and just provide another UI (and typically another client-side logic layer), but is not always possible.
Luckily, I could do it in wordpress with just some research.
This are the hooks/actions/filters/whatever you have to capture to either let return the function parameter (normal/desktop) or override with the mobile one:
add_filter('stylesheet', array(&$this, 'GetStylesheetFolder'));
add_filter('theme_root', array(&$this, 'GetThemeRootPath'));
add_filter('theme_root_uri', array(&$this, 'GetThemeRootUri'));
add_filter('template', array(&$this, 'GetTemplatesFolder'));
add_action('wp_footer', array(&$this, 'AddFooterSwitcher'));
Credit from learning which ones to use goes to WPTouch plugin developers who found it.
The fifth hook is for my requisite of "Being able to toggle normal site back". I inject in the theme footer a small hyperlink and javascript o set a cookie to allow me to override the mobile theme if desired:
public function AddFooterSwitcher()
{
if ($this->mode == Mobilizer::MODE_MOBILE)
{
echo '<a href="http://www.xxxxx.com',
$_SERVER['REQUEST_URI'],
'" onclick="Switch()" data-ajax="false">Switch to Desktop</a>',
$this->GetCookieModeSwitchJavascript();
}
else
{
echo '<a href="http://www.xxxxx.com',
$_SERVER['REQUEST_URI'],
'" onclick="Switch()">Switch to Mobile</a>',
$this->GetCookieModeSwitchJavascript();
}
}
And this is the switcher code:
public function GetCookieModeSwitchJavascript()
{
return
'<script type="text/javascript">function Switch() {' .
'var expiration = new Date();expiration.setDate(expiration.getDate() + 365);' .
'document.cookie = "' . self::$cookieName . '=' .
($this->mode == Mobilizer::MODE_NORMAL ? Mobilizer::MODE_MOBILE : Mobilizer::MODE_NORMAL) .
'; expires="+expiration.toUTCString()+"; path=/";' .
'}</script>';
}
The logic to decide the mode is very simple:
- If detected as mobile device*:
- Override cookie present and set to normal mode -> leave normal
- Override cookie not present or set to anything except normal mode ->set mobile
- else -> leave normal
* I have also a dev IP override (a variable) to do local tests
Mobile detection is fairly simple using a simple regexp , I didn't wanted anything complex:
public function IsMobile()
{
if (self::$devIpOverride != null && strcmp($_SERVER['REMOTE_ADDR'], self::$devIpOverride) === 0)
{
return true;
}
if (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))
{
return true;
}
if (strpos($_SERVER['HTTP_ACCEPT'], 'text/vnd.wap.wml') > 0 || strpos($_SERVER['HTTP_ACCEPT'], 'application/vnd.wap.xhtml+xml') > 0)
{
return true;
}
return (bool) preg_match("/(iphone|ipod|ipad|android|blackberry|kindle|iemobile|ppc|smartphone|windows phone|psp|symbian|smartphone|opera mini)/i",
strtolower($_SERVER['HTTP_USER_AGENT']));
}
To hook the plugin early enough so that no theme initialization code has been performed, I added this hook:
add_filter('plugins_loaded', 'MobilizerInit');
Code for the mobile pages is very simple HTML5 with the data-xxx attributes of JQuery mobile, for example this is the single post template:
<?php load_template(TEMPLATEPATH . '/header.php', false); ?>
<div data-role="page" data-theme="a">
<div data-role="header">
<a href="http://www.darkmillenniumcodex.com" data-icon="home" data-iconpos="notext">Index</a>
<h1>Dark Millennium Codex</h1>
</div>
<div data-role="content">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h4><?php the_title(); ?></h4>
<p>
<strong>Date:</strong> <?php the_time('m.d.Y') ?>
</p>
<p>
<strong>Categories:</strong> <?php the_category(', ') ?>
</p>
<?php the_content(); ?>
<?php comments_template(); ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
<div data-role="footer">
<?php load_template(TEMPLATEPATH . '/footer.php', false); ?>
</div>
</div>
</body>
</html>
Some PHP fragments are really ugly, I know, but I haven't had time to properly clean the theme, I just grabbed a normal one, stripped out all CSS and markup and rebuilt a minimal mobile version. Wordpress is just so ugly by default.
And really there is not much else… One huge win with this approach is that all requests keep the same URLs, as we are only modifying the theme path and not the JS/PHP engines. The footer switcher function reloads exactly the same page you were visiting in the oppositve mode.
If you want to see it in action, just point a mobile phone, ipad or similar to http://www.darkmillenniumcodex.com and play with it (remember, in the footer you can always change the mode).
The full source code of the plugin and my theme is available here. Just read the notes and comments, should be easy to follow and setup.
Dec 07 2011
I'm taking advantage of this week of vacations for getting some pending tasks done and organizing stuff.
Both to try it and to have a clean way of embedding slideshows here (clean == no Flash requirement) I have created a SpeakerDeck account and uploaded all my talks (even old old ones!) there: http://speakerdeck.com/u/kartones
I finally got the strenght to dig inside my backups of old source codes and select something not awful, so I have uploaded some personal source codes. Nothing impressive there (I have probably more interesting code in my posts) but at least is organized in one place.
I also have updated a bit my Links list (think of it as a public bookmarks list). Excepting some Lego Mindstorms stuff mostly is development, design and security.
And although it hasn't been updated in a while, I would like to remind that I also maintain a small free developer tools list, with sub-pages containing interesting plugins for Chrome, Firefox and IE.
Ok, enough spamming. Enjoy Christmas and code a lot!
Dec 02 2011
Years ago I wrote about editing in-memory values with tools like Cheat Engine, to hack your game as you were playing it.
But there is another way to hack games: To edit their savegames.
I will use the great Game Dev Story game, which you should buy inmediatly if you have an iPhone. It is a simulation of a videogame creation company; we will hack/modify the company money.
I will do it on this smartphone because having so much games from varying skilled developers, probably not much of them will have online-only storage or synchronization of the game state, plus jailbreaking is an option but not too widely extended, so many developers might think access to phone files is forbidden.
So… I started a new game, saved as soon as I could, took note of those 500.0K and exited.

With a Jailbroken iPhone that has OpenSSH installed you just need to connect to it. I use WinSCP under Windows to connect.
In my iphone, the path that we want to navigate to is:
/private/var/mobile/Applications/1E64F579-3EEC-495C-9C31-B179BEB06E0F/Library/Preferences
But the GUID in the path will change for each device, just search for 'gm08E' inside.
Once in that folder, copy to your PC the file 'com.kairosoft.gm08E.plist', and open it with a hexadecimal editor (I use the great Hex Workshop).
Remember the initial money amount? The 500.0K?
As it has decimals, we can assume it can just shift the comma and use an integer number, there is no need of floats just for one digit...
Also there is no need for negative numbers, so we'll try with an unsigned.
That trailing K can perfectly be a literal, to enforce the fake feeling of managing high sums of money (simple trick, instead of x1, make everything cost x1000). For the example, we will directly ignore it (because I know he solution) but usually you would have to search for both values.
So, as the iPhone is Little endian we want to search for the values 0x 8813 (unsigned int 16 bits) or 0x 8813 0000 (unsigned int 32 bits).
I was correct and in my savegame I found it at address 0x0000ACDF (After two tests, it is an unsigned int 32 bits).
We can just change the value for 0094 3577 (2000000000 in hex, a bit below int 32 max. value), and save.
We copy back the file to the device's folder, and run the game:

Check the money again in the upper-right part, it doesn't even fully fit so renders all 9s :)
Remember that money doesn't equal to happiness, so try not to cheat until you have finished your games first at least once, or you will spoil the fun!
With this small post we've went back to the early 90's where hex. editing strategy games saves was as easy as now it is editing an offline iPhone game!
The best solutions to avoid this editing are usually:
- Encryption of the full savegame
- Checksums stored somewhere else, to detect tampering with the savegame and reset it
- Full online storage of saves (getting more common with "the Cloud")
- Online storage of sensible data (like money) so critical stuff is safer *
* Safer, but if sync. code is not properly done you could sniff the data and inject your values anyway!