[This blog post is a rewrite of just the main points due to my baby Macbook Pro dying while I was distracted.]

Drupal content types with CCK make it quite easy to add any number of defined fields to an 'object', and with multiple/unlimited values for a field or with node references it's possible to make a Drupal node 'two-dimensional'.

Sometimes you need more. Sometimes you want tabular data, a table, to be part of a node. If the table always has the same dimensions, and at least the same columns for each node, then the above can work through node references and views.

What if you want to add a different two-dimensional table to nodes of a content type, but without knowing the number or labels for the columns and rows beforehand.  For example, you might want to attach a pricing table to a node, with multiple products and multiple ways to price each product.  An example of that might be 5 t-shirt designs, where shirts are priced based on size and quantity ordered.

Read the rest of this article...

[This is the third post about Accessing Facebook in Vietnam

Lately, ISPs in Vietnam has begun randomly blocking Facebook again after a period of openness.  When it's blocked, even accessing Facebook via their Lisp4 server (or using the Saigonist DNS server) doesn't work.

But there are a number of apps, both web-based and desktop apps, which integrate with Facebook to different extents.  These apps, once you login to them with your Facebook account, can basically get your Facebook updates for you without requiring access to Facebook.

One such app is Seesmic, which has both a web and a desktop client.  Seesmic connects to a numer of social networks and I use it for reading my Twitter feed, with a custom hack to fix a serious problem with disappearing Tweets.  But once you login to Seesmic and connect it to your Facebook account, you can see your Facebook feed as well as messages.  That's enough for most people, most of the time.

Other desktop apps that can connect to Facebook are Bubbles and Hootsuite, but I wasn't able to get Hootsuite to connect to my Facebook account.

Another less convenient way is to use Opera's online demo of their Opera Mini browser.  It's a Java app and you use it like you're using a phone, but it will connect to Facebook for you (unless your browser doesn't let Java make network connections).

When I saw that Diesel released a desktop app called Excellbook as part of a marketing campaign called Be Stupid At Work, I was hoping it would also work in bypassing the Facebook block.  It's an Adobe AIR app, which requires installing Adobe AIR, and is generally a piece of crap.  Even if you can get it to connect, it will require a connection to Facebook still and so it's not so useful.  Nice idea, terrible execution and yet another example of a bad Adobe AIR app.

PSD to HTML Slicing Services Reviewed

Submitted by tomo on June 17, 2011 - 10:45pm

I've known for awhile about the existence of PSD to XHTML cutting (slicing) services which can turn your website design straight from Photoshop into clean HTML/CSS in factory assembly line turnaround.  But I didn't realize there there were hundreds, perhaps thousands of little shops like this.  With so many options, a number of sites have sprung up to review these PSD2HTML clones.

If you don't want to read any further then just go with  They started the industry and are the most well known and most reviewed.  In general, the reviews are positive.  But there are many, many cheaper options.  If you, like me, always strive to get the best deal, then read on.

Read the rest of this article...

Since I mostly use Hootsuite and Seesmic for reading my Twitter timeline (the other big reader, TweetDeck, won't connect to both Twitter and Facebook in either it's Chrome app or desktop versions), I've updated h8sq: the 4sq killer to work on those clients.

This also includes performance enhancements for the version.

Furthermore, if you open your Chrome Developer JavaScript console, you will see log messages for each hated on FourSquare tweet like so:

"hated on tomosaigon" 


Do you find Hootsuite's "Promoted Tweets" distracting?  I've also hacked together an ad blocker for Hootsuite.  Rather, it should be called an ad blacker, as it blacks out the ad but still makes it clear who is spamming you, and you can still read the full ad by mousing over it.

Install h8sq for Chrome

Install hootfree hootsuite ad blacker for Chrome

Drupal Views UI Filter Fields by Content Type

Submitted by tomo on April 21, 2011 - 4:18am

Late night hack:

You have a lot of fields in a lot of content types. You're creating a view with new display fields but it's a pain to find just the content type fields you want. Wouldn't it be cool if you could just select a content type from a pulldown and see content fields filtered to just the ones in that content type?

Add this bookmarklet to your bookmarks bar:
Views UI Filter

Read the rest of this article...

Every few months, I've had remote OpenBSD servers die mysteriously, without any visible console messages, and still responding to pings, although higher level networking (http, ssh) are unresponsive. The crontab I setup to dump output from top (or systat) also stops. But before the kernel failure load was low and swap was unused.

After rebooting and checking dmesg, I see before the most recent reboot:

uvm_mapent_alloc: out of static map entries

Doing some research, it seems like it could be a problem with kmem_map fragmentation, possibly from long-running processes (like apache, which is being used more heavily now). The problem appears to have been fixed in recent releases of OpenBSD which dynamically increase kmem, but upgrading the server right now isn't feasible.

So the solution is to compile a custom kernel with an increased MAX_KMAPENT added to GENERIC config:

Read the rest of this article...

Using Nokia's PC Suite, one can export SMS messages from one's phone (maybe only their smartphones with USB). The format is CSV but the output is basically unreadable due to PC Suite bugs. Only a phone number is exported per message, no contact name. But more importantly, the CSV output is broken -- double quotes aren't properly escaped.

I think it's useful to be able to browse old messages online, say in a Google spreadsheet. But to do that, we need to rewrite PC Suite's output a bit.

[I didn't know anything about scripting Excel (or Google's spreadsheet which is basically Excel) but I did want to look up some old messages because I couldn't remember somebody's birthday. After importing messages from a year ago to Google docs, I could read messages between my friend and I around that day to find out exactly.]

Read the rest of this article...

Drupal Add Comment Form Above Comments

Submitted by tomo on March 24, 2011 - 12:57am

Drupal 6 allows you to either display the comment form below saved comments or on a separate page. There's surprisingly no way to configure the form to appear above the comments. It's hard-coded at the bottom of comment_render to either append the form, or not at all.

There's a micro-module aptly titled 'Comment form above comments' which does the job but does so using string replaces on resulting html so it's not the ideal or elegant solution.

It turns out to be simple to get the same effect in code.

First, we need to "configure" the form to appear on a separate page, but only because we're going to manually show it. You can ensure this configuration with the line:

variable_set('comment_form_location_'.$node->type, COMMENT_FORM_SEPARATE_PAGE);

You could even variable_get and re-variable_set after printing the form if you really wanted to.

Next, output the following where you want to display comments, whether in a PHP code block or node template:

$edit = array('nid' => $node->nid);
print comment_form_box($edit) . comment_render($node);

Another recent discovery was that the comment form is hard-coded to redirect to /node after submitting. This hack, as a module, will get you back to the page you submitted from:

function noredirect_comment_form_submit(&$form, &$form_state) {
    $form_state['redirect'] = ltrim($form['#action'], '/');

function noredirect_form_alter(&$form, $form_state, $form_id) {
    if ($form_id == 'comment_form') {
       $form['#action'] = request_uri();
        $form['#submit'][] = 'noredirect_comment_form_submit';

Improved Google Spam Filter?

Submitted by tomo on February 26, 2011 - 10:08pm

Google, in response to the flood of recent concern about spam/content farms showing up in their results, have just announced a big change in their system of algorithms which calculate page rankings. They had previously published a Chrome plugin that lets you manually block results, and Google says the new algorithm blocks some 84% of the same sites that people were blocking with the plugin. I guess some people were controversially blocking non-spammy sites, rather than guess that Google's algorithm isn't good enough. Or isn't it?

Matt Cutts, the main anti-spam guy at Google, says the new algorithm change affects 11.8% of queries. Since the change is only effective in the US right now and I can browse from both Vietnam and the US, we can compare results and some one in eight queries should be improved.

So I tested "dog shampoo" out of the blue. I have never had a dog because I think they smell.

In Vietnam, high ranking results included which had a low quality page of filler about dog shampoo and which is clearly a made-for-adsense site. In the US, the drnaturalvet link is much lower, but maintains the same high position. A link to content farm is also lower now. And a link to, a made-for-adsense site with nothing about dog shampoo at the time of indexing (see cache) is now gone too.

A search for winrar came up with fairly similar results in either country, and both maintained links to spam sites like

A search for "tightvnc server authentication successful closed connection" punished duplicate content site slightly but another duplicate/copy site maintained its position in the top 20. Both copy the StackExchange site

So it seems that the new algorithm change is an improvement, but I don't think it goes far enough to filter spammy results. While it may be a slight setback for those guys, they are still in the running and will be emboldened to try to rank higher.

There may still be a need for users to crowdsource a database of filtered spam sites until further algorithm improvements.

Note: The Atlantic did a similar test from India on "is botox safe" and "drywall dust" and found their results to be much improved.

I've tracked down a source of the bug which breaks jquery (1.2.6) in FireFox (Chrome is fine) where you'll see a debug message of "z.indexOf is not a function". If you're running a minified jquery then the line number won't help locate the bug, but in this case it was around line 1715:

type == "^=" && z && !z.indexOf(m[5])

This code is triggered by jquery attribute filters like ^= (starts with) or *= or ~= and in this case I found that if z had been 0 then the code which checks "&& z" would short circuit and not try to reference indexOf of z.

Looking deeper, I found that z == -1 (not a string) and that this was because I was filtering on the 'value' attribute, and that in FireFox, the 'li' node was being given some value of -1. You can check this by running "$('li')" and checking out the returned values. In Chrome, there is no value. This difference causes a bug in FireFox.

One workaround is to use only use attribute filters when using selectors that select for specific tags which exclude 'li', at least for filtering on 'value'. For example, use 'input[value^=whatever]' instead of just '[value^=whatever]'.

Syndicate content
© 2010-2014 Saigonist.