Hey all you bloggers and publishers. If, like me, you’ve been putting off updating your blogs and wikis to show up nicely on smartphones, fear not, there are DIRT SIMPLE FAST solutions available today to set up special skins for mobile browsers that are gorgeous. As of today, here are the instant solutions.

WordPress

  • Right inside your admin panel in WordPress, click on the Plugins button in the left pane.
  • Select Add New.
  • Punch in WPTouch and hit “Search Plugins”.
  • There it is, now install it!
  • That’s it. Seriously. You can play with the settings if you want (like changing the logo), but you don’t need to. Wow!

Mediawiki

  • This skin is the one you want, but it has a few issues.
  • Here is a corrected version, use it to take your chance for it to work “out of the box” 🙂 Download and untar it from within your [mediawiki/skins] folder. The changes I made are listed at the end of this post.
  • Now users can select the skin in their preferences, but we want automatic! Update your LocalSettings.php file to set $wgDefaultSkin as follows:
    if (preg_match("/iphone/i", $_SERVER['HTTP_USER_AGENT'])) {
        $wgDefaultSkin = 'wptouch';
    } elseif (preg_match("/android/i", $_SERVER['HTTP_USER_AGENT'])) {
        $wgDefaultSkin = 'wptouch';
    } elseif (preg_match("/webos/i", $_SERVER['HTTP_USER_AGENT'])) {
        $wgDefaultSkin = 'wptouch';
    } elseif (preg_match("/ipod/i", $_SERVER['HTTP_USER_AGENT'])) {
        $wgDefaultSkin = 'wptouch';
    } elseif (preg_match("/opera mini/i", $_SERVER['HTTP_USER_AGENT'])) {
        $wgDefaultSkin = 'wptouch';
    } else {
        $wgDefaultSkin = 'vector';
    }
  • Go enjoy it!

Easy and beautiful!

(continued…)

A new article describing my cross-platform development environment setup is now on the wiki

Updated with more detail on 2011/09/18…

The latest reincarnation of Hang The DJ, my music player, is coming along nicely. In the alpha stage, it’s currently an excellent way to stream your massive music collection to your laptop.

It sits atop an open source media streamer called Ampache. I had to extend Ampache to support the more advanced features of Hang The DJ. But this extended version of Ampache still retains its full feature set.

I have plans for a full set of Hang The DJ mobile clients, but they are further down the roadmap.

In the meantime, I can still use Ampache with my iPhone in a couple different ways. There are some Ampache iPhone clients but they are rough and limited. However, Ampache by itself has a nice web interface. You can play your music by downloading, by streaming, or through a bare-bones flash player.

Flash is out on the iPhone. Downloading each song is cumbersome. But the streaming works! It’s not foolproof. The silly Safari browser on the iPhone has a ridiculously short timeout on streaming requests, something like 16 seconds, and I don’t know of any way to adjust it. So for a long time, it just didn’t seem to work for me. But following these rules, I can get to my whole music collection from my iPhone:

  • Make sure you have a decent server. I recently upgraded my server to use a quad core i7 cpu and it seems to help.
  • Make sure your upload bandwidth is sufficient, obviously. I have really crappy crappy “10Mbit” service from CenturyLink, which gives me about 20kbps upload. Hates it. But it’s currently my only option and it’s working.
  • Make sure your iPhone is in a 3G zone. Edge service through AT&T didn’t seem to work. Stupid AT&T.
  • Stream 1 song first. This is your best chance of completing the setup between Apache and Safari before timing out. Once that’s confirmed to work, slowly bump it up until you get timeouts. I can do 3-4 songs but 20 seems to fail consistently.

Yeah it’s not ideal. Just more motivation to get going on the iPhone client! 🙂

In the meantime, shoot me an email if you’re willing to try Hang The DJ out on a desktop or laptop, that would rock. Peace.

I’m using the cross-platform Qt C++ library to write an app for linux, OS X, and Windows. Qt source can be compiled to a wide range of systems and devices, with two obvious omissions that are not likely to be filled any time soon: iPhone and Android. I know I am going to need client code on these devices, and I know that the client code is going to be extremely similar to the Qt client code. How do you design for this?

Applying the concept of separation of concerns, you design your classes into layers. The base layer consists of high level concept classes that perform all fundamental actions using generic data types. Then, the derived layer is used to get the job done, using the most useful and powerful lower level tools at your disposal. Push everything you can into the base layer, until you hit the limit of non-portable information and data types. It’s a beautiful way to code.

To be more specific, in my case, the base class layer will be using C++, including the STL, which gives me tons of power. I will pull in boost if even more horsepower is needed. The derived class layer for the first round of clients will be Qt-powered. The Qt library has a massive amount of real-world usefulness, supporting everything from http to video playback. I have not gotten to the iPhone and Android clients yet so the whole concept may change, but here’s my current plan. The iPhone code will be Objective C with the C++ base class layer linked in. I will attempt to incorporate the C++ base class layer into the Android code using the NDK.

Here’s a quick example of the layer approach, in this case used to quickly set up profiling using Qt’s QTime class at the lower level: (continued…)

I love my asserts. I use them like crazy throughout my code and catch errors faster than you and your whole testing department. :> The computer does exactly what I ASK of it, which sometimes is not the same as what I EXPECT of it. So I wrap up my expectations with assert macros so my computer friend and I stay on the same page. Happy happy joy joy.

In Qt, we have the Q_ASSERT macro. Qt default behavior is to abort on any Q_ASSERT macro failure. This is weird to me (even if it is common). Almost universally, I want to SEE what’s going on when I hit an assert. Sometimes the assertion turns out to be wrong and may need adjusting. Even if it’s right, sometimes it’s helpful to check the effect of the failed assertion. And certainly, being able to walk back up the stack trace is critical to determine where things went wrong. I can kill the program easily if I WANT to, but I may want to continue – it should be my choice. It’s a no-brainer!

So I don’t use Q_ASSERT. Here’s my cross-platform C++ assert macro hackery. It’s not perfect but it’s getting me by so far… (continued…)