The Freehare

About

Having been involved in freeware games for years, I noticed that the general opinion on them is that they’re not as good as commercial games. None of the sites distributing these games helped turn that opinion. Instead, they put both the real gems along with the rushed projects with no effort put into them. Because the free games with outstanding quality deserve a special place, I started The Freehare.

Why Drupal?

The previous version was in plain PHP, built fully from scratch. This new version needed to be faster to maintain and easier to add expansions. The workflow for adding new contents needed to be more efficient, since in the last version, lots of time and work were lost on things that should’ve been done automatically or simply could’ve been done better.

Drupal fits the bill for all of that perfectly. Since I also still needed to learn a lot about Drupal, the APIs it offers and several modules, this project also gave me a good sandbox to play around in, experimenting and learning as I went along.

Modules used

The Freehare uses both contrib. modules as well as modules I wrote myself. I won’t go into the basic contrib. modules (CCK, Views, Administration Menu, Devel – now turned off –, FCK Editor, IMCE and Scheduler ). Instead, here’s a list of each specific module and why they’re used.

Node referrer:

Since each game has to be linked to a developer, this option should be available when creating a game entry. To keep the workflow as slick as possible, I’ve made the node referrer field hidden through CSS, though, and handle filling it in through hook_nodeapi. Why I decided to do things this way, is explained in the Code part.

Views Galleriffic:

The screenshots on the games’ detail pages are done using a view. It took quite some searching and experimenting, and some interesting pointers from people of Drupal.org before I found this module. What I needed, was a way of displaying one big screenshot and a carousel of thumbnails below. When a visitor clicks a thumbnail, it shows the new screenshot without refreshing the entire page. Views Galleriffic does this, except for the carousel part. To get the carousel part in, I had to include the Jcarousel library (not the module. I forgot why exactly, though…) and tweak the theming a little.

Search contents module:

Because the default search feature in Drupal acts odd now and then, I decided to write a module that shows search results in a consistent way. That, and because I don’t use the Path / Pathauto / Global Redirect combo (using hook_menu properly means less overhead to do pretty much the same thing, and without having to bother the user about these things), the search results would go to the wrong page (node/[nid]).

Choosing for hook_menu has another issue. When saving a new node, or when clicking on a node from the backend’s node list, you’ll go to node/[nid]. Since this problem is solved in almost the exact same way as the search problem resulting from using hook_menu, this module fixes that problem as well.

Sitemap:

I know of the XML Sitemap module, but chose to write a sitemap module myself. This is mainly because I want all the settings in one place, and once set, not have to worry ‘bout it anymore. This especially pays off when creating content from a type with lots of fields to fill in. This module doesn’t have taxonomy support yet. All contents comes from nodes. I’m still working on the taxonomy support.

Tasks:

Contents to The Freehare is added by a small group of people. To keep things in check, I’ve written a module that allows creating projects and tasks, assigning tasks to someone, posting comments on a task and checking a task off when it’s finished. It still needs some polish, and a couple more features before the module is fully finished, but it’s usable (and in use) already. It’s mainly meant for keeping track of what needs to be done (which games need to be prepared, what should be written for a blog, which issues or features should be addressed to, …). It’s not meant to be a tool like OpenAtrium, but just a way to keep things manageable for a small team on one main project.

Google Asyonchronous Analytics:

When I wrote this (veeeery basic) module, the regular Google Analytics module didn’t provide support for the Google Asynchronous code. Since that code loads while the page loads, instead of before, it results in better load times. I chose to use that for previous sites, and have been using that module since. I don’t know if the official Google Analytics module allows the Asynchronous code by now or not, since this module does what it should.

Code

The site-specific code is all placed in a single workflow module. It uses the basic hooks (hook_menu, hook_theme, hook_block, the Form API, …). There’re some specifics, which will be discussed below.

Hook_nodeapi for node reference:

Node reference fields have one main limitation: The referenced node has to exist already. This has as a result that, when creating a game node, the user’ll first have to check if there’s already a node of type Developer, and create it if it doesn’t exist.

I wanted to cut those extra steps out and create a developer node if it doesn’t exist already when creating a game node. To do this, I had to make the node reference field hidden (using CSS), and add a regular text field where the user fills in the developer’s name.

Using hook_nodeapi, I check whether or not the developer already exists, create it if necessary, and set the node reference field to the developer node’s ID. The developer node’s status is also set accordingly (Published if at least one game belonging to this developer is published, and unpublished otherwise).

This method has one main downpoint: It’s prone to spelling mistakes. If a developer’s name is misspelled and the correct spelling is already in the database, both the correct spelling and the misspelled version will be in there.

Hook_form_alter for the comment form:

Using the default comment form in a game’s tab menu (below the screenshots and ratings), the redirect after posting a comment goes wrong. To fix this, I use hook_form_alter to override the default submit callback. The custom submit callback is just the default one, but with the redirect part changed, so it goes to the right page.

Hook_form_alter for limiting textareas with a character limit:

With CCK, you can set a textarea to have a character limit. It can still contain any amount of characters, but once the form’s submitted, it will give a validation error, saying that textarea has more characters in it than allowed.

I wrote a very basic piece of Javascript that shows how many characters are still available and blocks writing more than allowed for these textareas. The Javascript file is included using hook_form_alter, so it only gets included when it’s actually necessary.

Game ratings:

The game ratings, shown by any amount of carrots ranging from 0 to 5, doesn’t use the Five Stars module, but is custom-written. The reason for this is that it was written before I learned of the Five Stars module.

RSS feeds:

Both news items and blog posts have their own RSS feed. I wrote a function to create a feed for both, because that went faster than learning how to use the built-in aggregator or any modules that would do the same. The function’s fully reusable, so I’ve never had the need to switch.

Tabs:

Drupal offers several modules that handles tabs. I know of three in specific: Quicktabs is one, Magic Tabs is another, and Tabs is a third. Quicktabs didn’t do what I wanted. Magic Tabs did, but isn’t compatible with IE8. There was something wrong with the Tabs module too, but I forgot what…

In short, I had to create those tabs without using a module. I found a nice Jquery library that does just this (Tabs Done Right, available here: http://flowplayer.org/tools/tabs/index.html ). Didn’t take too much time to implement it, and it works fine in any browser.

Also Try list:

On each game’s page, there’s an Also Try list. This is built dynamically. A game can get tags from several vocabularies (game genre, graphics style, settings and a few others). Tags from each vocabulary carry a different weight. To build the Also Try list, all games with one or more tags in common get selected. For each game, the sum of the weight of the tags that’re the same with the current game, is calculated. The games with the highest sum get shown in the Also Try list.

Result

The result can be seen here: http://www.freehare.com The site is compatible with every browser (there are still some minor issues with Elinks, which will get ironed out once I can get it tested on there again).

Along with all the contents, game developers with an account on the site can also post news items (under their username, not under the developer group’s name).

The site’s also ready to implement any new features as seen necessary or as requested by visitors or developers.

Comments

paolo12’s picture

I'd like to criticize the design. Maybe it was your goal to make it simple but .. it's very sharp, no rounded corners or smth... Although content is good.

Raf’s picture

The previous version had nothing but rounded corners and looked badly, so now I went with just straight corners. It keeps everything simple and flexible, and personally, I think it looks quite good. If rounded corners (like on the tabs on game pages) is an improvement, though, I can give it a try. I'll do a mockup of it this evening and send it to the two creative people whom I run everything like this by, see what they think looks best.