In the continuing saga of me trying to bludgeon WordPress into doing what I want it to, I took a shot at coding a simple widget. You can see it there on the right — it shows the local time here in Davao, Philippines, and a quote taken at random from a text file.

Widgets, for the uninitiated, are separate programs that “plug in” to (in this case) a WordPress page. There are thousands of WordPress widgets out there, and most of the ones you see on blogs are “canned” widgets — you just download them, drag/drop them onto your page, perhaps specify a setting or two.

Or, you can write your own. It isn’t difficult, but it does require some basic familiarity with at least PHP and preferably also javascript.

My old web site was written before tools like WordPress became popular. It started out, back in about 1996 or so, as plain HTML, and morphed into various other manifestations over the years, pretty much all hand-coded. One of the features of its most recent incarnation was a bit of code that selected a random quote from a text file and displayed it at the bottom of the page. I’ve been adding quotes to that file for a long time, and I like them, so I thought I would try to add that feature to the new WordPress blog. I also wanted to add a clock showing local time here in the Philippines, to make it easier for people who want to call me to figure out if it’s a good time to call.

You might be wondering, why not just find a suitable widget that someone else has written and use that? I did look, and there are certainly canned clock widgets and widgets that display random text selections, but none of them were quite what I wanted.

The clock widgets that I looked at (and one that I tried out) illustrate two mild objections that I have to a lot of the pluggable components available. First, they all want to run in Flash. Flash is Adobe’s graphics platform, and it comes with quite a bit of baggage. No disrespect to Adobe — getting graphics to work right on all the different browsers isn’t simple, and Flash is getting better and better. But it’s fair to say that, at least in my experience, when web pages have refused to load or render correctly, it isn’t unheard of for the problem to be something to do with Flash. (Also I’m probably a bit cranky about Flash because I hate it that there’s no convenient way to record Flash videos to listen to later on another device, but that’s a different issue.) Bottom line, Flash seems like massive overkill for displaying the time.

My other objection to what I saw with most of the canned widgets that I looked at is more fundamental: they seem to be doing nefarious things in the background. They’re linking out and pulling in bits and pieces from javascript and PHP scripts from other web locations, and embedding links to their own web pages — which they have a perfect right to do, but I also have a perfect right to choose not to cruft up my pages with someone else’s SEO tactics and, for all I know, user tracking. (I do think that it’s rather uncivilized not to openly disclose such things, when they’re being done.)

Anyway, I like to code, and I was curious how much trouble it would be to code a WordPress widget, so I coded my own.

Examples of the basic framework for a WordPress widget are available from various web sites — I began with this one, which is also explained in a youtube video. Another example is here. The place where all the actual coding happens is the WP_Widget->widget() function, and it has comments indicating where to insert your code. The rest of the WP_Widget class, and the index.php file, just handle the interfacing with WordPress, and doesn’t need to be changed except for doing a search and replace to change the name. (There is also a WP_Widget->form() function that is used to obtain input from the WordPress dashboard, to allow for whatever adjustable settings are needed — in this case, I didn’t need any.)

This post on how to debug plugins and this one on useful things to know about how plugins work were both helpful.

There were three minor challenges —

  1. Debugging seemed a bit tedious. The process for installing a widget takes perhaps a dozen steps, depending how you count them, and includes packaging the files (all 22k of them!) into a zip archive. Having to go through all those steps for each minor tweak while fine-tuning the format was a pain, until I figured out that it isn’t necessary — once the widget is installed, the files are in plain text format in the plugins folder, in their own subfolder, and you can just overwrite the file that you want to change by copying it into that subfolder by FTP. Obviously, it’s possible that WordPress does things with the files during the install process that I don’t know about, so probably best to uninstall and reinstall the widget at the end after it’s debugged, just to be sure, but for debugging purposes just overwriting seems to work fine.
  2. On the first attempt, the text file containing the quotes would not open — I had the file in the same directory as the widget files, but it seemed to be using the wrong path. The solution turns out to be, when accessing files from a plugin, you have to use WordPress’ defined constants (in this case WP_PLUGIN_DIR) rather than a relative path.
  3. With the clock widget, I didn’t want to have to pull in the time from some other web source, I just wanted to use the system time. (As someone who lives in a place where internet connections are somewhat glitch-prone and sometimes very slow, I have developed a serious dislike for the common practice of building site content on the fly from pieces pulled in from elsewhere, while I sit there waiting for the slow bits to load.) Of course, the system time depends on what time zone the system is in, so to ensure that it shows Davao time, it’s necessary to convert, but that’s fairly easy in javascript (see here for discussion). Then, on the first attempt, the widget showed the time, but 15 minutes later it was still showing the same time. (Duh.) Needed to make it update itself automatically, easy with javascript set_interval() function (see here).

Anyway, here’s the code (WP_Widget->widget() function only):

public function widget($args, $instance){
	extract($args, EXTR_SKIP);

	//added code
	$qfile=WP_PLUGIN_DIR."/datequote_widget/quotes.txt";
	$lines=file($qfile);
	$randkey=array_rand($lines,1);
	$line=$lines[$randkey];
	list($quote,$auth)=explode("\t",$line);
	date_default_timezone_set('Asia/Manila');

	//global WP theme-driven "before widget" code
	echo $before_widget;

	// code before your user input
	echo '<div class="your-class"><!--Your custom html code goes here!-->';
	echo '<h4 class="widgettitle">CURRENT TIME IN DAVAO</h4>
	<div id="timer" style="margin-left:20px;">
		<p> </p>
	</div><br>
	<script type="text/javascript">
		setInterval(function(){
			d = new Date();
			utc = d.getTime() + (d.getTimezoneOffset() * 60000);
			//+8 is UTC offset for philippines
			nd = new Date(utc + (3600000*8));
			document.getElementById("timer").innerHTML=
			"<span style=\"font-size:large; font-weight:bold;\">" +
			nd.toLocaleTimeString() +
			"</span>&nbsp;&nbsp&nbsp;&nbsp;" +
			nd.toLocaleDateString();},1000);
	</script>';
	echo "<h4 class=\"widgettitle\">TODAY's QUOTE</h4><i><font size=-1><div style='margin-left:10px;'>$quote</div></font></i><br>
	<div style='margin-left:20px; margin-right:0;'>-- $auth</div>";

	// code after your user input
	echo '</div>';

	//global WP theme-driven "after widget" code
	echo $after_widget;
}

Leave a Reply

Your email address will not be published. Required fields are marked *