Archive for October, 2009

Keyboard navigation plugin for WordPress

I prefer to use the keyboard for navigating content whenever possible, rather than the more awkward movement of a mouse… and my carpal tunnels thank me for that preference. I’ve seen keyboard navigation of posts implemented on FFFFOUND! and thought it was really nice. So I decided to make a WordPress plugin to allow others that functionality easily.

Scrolling through posts by keyboard may not be useful to everyone, but it makes a lot of sense for anyone with a photoblog. Users can quickly flip through your content without enlessly flicking a scroll wheel or clicking and dragging until they grab their wrists in pain.

Features:

  • Press the “J” key to see the next post, and the “K” key takes you to the previous post.

Planned features:

  • Add “next” and “previous” keys for page-by-page navigation.
  • Add an options page which allows the navigation keys to be customized.
  • Automatically load the “next” or “previous” page when you hit the end.
  • Detect the scrollable element in a site’s design. (Current version only scrolls the body.)

Download
The current version can be downloaded at WordPress.org.

Changelog

  • 0.5
    • Added scroll event listener to make the navigation sensitive to your current scroll position
  • 0.4
    • Continues to next/previous page when you navigate past the last (or first) post
  • 0.3
    • Javascript has moved to a separate file and is now added through via wp_enqueue_script
    • jQuery has been implemented for all DOM functions
    • ScrollTop is now at the top of the screen, as expected
    • Tested on Internet Explorer 7, Firefox 3.5, Safari 4, and Chrome 3
  • 0.2
    • Key navigation is no longer added on single posts
    • Keypress events are ignored inside of TEXTAREA and INPUT elements
  • 0.1
    • Initial version

Tags: ,

Comments

Barnes and Noble “Nook”

Yesterday, Barnes and Noble released their new e-book reader called the nook, billing it as “the world’s most advanced e-book reader”. I don’t think “nook” is a very catchy name, in spite of rhyming with book… but that’s another story.

I’ve made no secret in the past about my dislike, even distrust, of eBook readers. Especially the Kindle, which I vow to never own after their 1984 debacle.

As I’ve discussed the subject with friends and colleagues, my opinion has refined quite a bit, and my basic points come down to:

  1. The price of a book reflected heavy publishing costs, including equipment, materials, labor, and distribution… none of which apply to eBooks, making them rather expensive in comparison.
  2. Real books can be shared with friends, given away, or re-sold, but while the format of data makes doing this even easier, the licensing applied to eBooks prohibits doing so.
  3. Real books don’t stop working when a battery dies.
  4. Dropping a book in a puddle, losing it while on the bus, are misfortunes that only cost a few dollars to correct, a far smaller amount than the cost of even the cheapest ebook reader.
  5. Dropping a book on the floor, or accidentally sitting on it does nothing to reduce your ability to read it later… and in fact, people often use books to hold things up, to sit on, to stand on, etc.
  6. None of the books I would most desire to replace are available as ebooks. I enjoy turning the pages of a novel, but I’d love to be able to carry around dozens or hundreds of reference books without breaking my back.
  7. By that same measure, most students would also love to stop breaking their backs with textbooks, but no ebook reader yet has solved the problems of universal page numbers or of jotting notes in the margins.
  8. And finally, they take away all those expected advantages of real books without giving any significant new adantages in return.

While the Nook offers many advantages over the Kindle, including built-in WiFi, direct loading and reading of PDFs, replacable batteries, and synchronized annotations, it only overcomes one of my stated hurdles, and only to a limited extent. Nook allows you “loan to a friend”, but it does not allow you to “give” to a friend. Nor does it allow you to re-sell to anyone.

As far as I can tell, all Barnes and Noble did was add a touch-sensitive LCD screen to the bottom of a Kindle, and add a half-baked book loaning mechanism. That may be enough to lure in people who want a Kindle but were scared off by the 1984 debacle… but I don’t believe it’s going to be enough to coax any book converts.

So what would it take to convert me — and lots of others like me — to ebooks? Pressure publishers to make searchable ebook versions of reference materials.

Working 9-to-5 in information technology, I have acquired a large library of reference books on programming languages, APIs, systems, data formats, and so on. If I could carry all of those (dozens of books) to work with me on a small device, I’d jump on the opportunity, but none of those materials are available in ebook format.

And when I’m not at work, my two most time-consuming activities are photography and language study. Admittedly, it will be a long time before photographic quality is available on ebook readers, but current readers are already capable of displaying language lessons… and most even support MP3 playback for the accompanying audio materials. I have an entire bookshelf at home dedicated to beginner, intermediate, and advanced books and CDs for Spanish, Russian, Italian, German, French, Ukrainian, and Portuguese, which I would happily trade for even a mostly disfunctional e-reader if I could, but unfortunately, those materials are simply not available in any other format at present.

For companies with the leverage of Amazon and Barnes and Noble, it should be a no-brainer to lean on those publishers. Today, all books are written in an electronic format to begin with. Why should it be so hard to simply run that original through some converter and do a little bit of editing, and produce the single most useful argument for a higher-profit, lower-overhead version of their product?

Tags: , , ,

Comments

Politically Correct WordPress plugin

Please note that plugin was meant to be fun. Don’t expect to see lots of support for it.

Politically Correct swaps the occasional “politically incorrect” term with a more socially acceptable replacement. For instance, if your author types post-traumatic stress disorder (PTSD), your viewers see post-traumatic stress disorder. If your author types mentally challenged, your viewers see mentally challenged.

Example:

What output shows up if I say “homosexual people”? What about “African-American men”? And “caucasian men”? Does it know the difference between “African-American men” and “black licorice”? Can I say that “Asian people are good at math”?

What about expletives? What happens when I say “have sexual relations you”? “Eat defacate”? “Kiss my rear end”? Does this thing know the difference between “a sexual favor” and “several sexual favors”?

Is this going to give me “post-traumatic stress disorder (PTSD)”? What will the “vision-imparied”, the “hearing-impaired”, and “the disabled” think about this? What about “elderly people”?

If you have a serious web site, perhaps with a rogue author or two, you can use this plugin to help slow down some of the offense. Or, perhaps more likely, you have a personal web site and you think you could have some fun by replacing words with their PC counterparts.

Features:

  • Force filtering on individual posts by use of a custom tag
  • Admin can apply the filter to all users or only to specific users
  • Admin can apply the filter to all categories or only to specific categories

Planned features

  • Allow admins to define custom terms

You can download it here: politically-correct-v0.2.zip

Please note:
Creating this plugin was meant to be a joke, since I find the entire concept of “political correctness” to be not only mentally challenged and wasteful, but I also think it runs completely in opposition to the very nature of “the internet”. It started as a joke, and it continues mostly out of my own desire to learn more about WordPress and its APIs. I won’t be putting a tremendous amount of energy into this plugin, but I provide it both for the enjoyment of those with a sense of humor, and also on the off chance that someone might actually get some legitimate use out of it… such as a multi-user blog with one particularly “brash” author.

But to the losers who are writing in to say it’s a “stupid idea”, I simply say stop taking yourselves so seriously. Instead of whining about what you think is a stupid idea, why don’t you write to me and tell me what you think would be a better idea? Put up or shut up.

Tags: ,

Comments

Freedom of Information!

Freedom of Information, my second WordPress plugin, is just for fun. It filters the content of your post and “redacts” terminology that certain nefarious conspirators wouldn’t want getting out.

Example:

This is a government test of a new top secret plugin for ufo homeland security. I wonder what will happen to George Bush and Karl Rove when I type their names. Do you think John F. Kennedy was involved with the Secret Service’s plot to give H1N1 Swine Flu and Mad Cow Disease to the citizens? I wonder who knows about President Obama’s secret plan to bring socialism to the United States?

Current version is 0.1, and you can download it here: freedom-of-information

Tags: ,

Comments

Add Linked Images To Gallery

screenshot-1Add Linked Images To Gallery
Makes local copies of all the linked images in a post, adding them as gallery attachments on the post itself.

I have a photoblog, for my iPhone. I take a lot of pictures, and I want them to post quickly and easily. And I’m lazy. I want to send the photo to Flickr, and let Flickr update my blog. But I also want my main pages to reflect the latest additions. And what’s more, I want customized images on the front page, and I need to use the gallery to get those.

This WordPress plugin creates local copies of all external linked images in the SRC attribute of IMG tags. It extracts a list of IMG tags in the post, saves copies of those images locally as gallery attachments on the post, and then offers the option to replace the external link with a link to the local copy.

Features

  • Finds all external images linked in the SRC attribute of IMG tags and makes local copies of those images
  • Allows the SRC to be updated to point to those local copies
  • Can be applied to posts in all categories, or only those selected
  • Can be applied to all authors, or only selected authors
  • Administrator has the option to replace the external src with the url of the local copy. Another option allows the plugin to be applied to all external images, or only to those on Flickr.

This plugin is particularly useful for photobloggers, especially those who update using the mail2blog Flickr API. The plugin will saved the linked image file from Flickr locally.

Planned features

  • Add internationalization support
  • Integrate with Flickr API in order to allow always downloading the original image size regardless of which is linked
  • Additional options to allow running the plugin only for specific users or categories

Download

Download the current stable version: Add-Linked-Images-To-Gallery.

Changelog

  • 0.6

    • Suppresses safe_mode warnings from CURL
    • Adds compatibility with WordPress 2.9
  • 0.5
    • Fixes a bug that cause all img tags to be rewritten as the last matched image
  • 0.4
    • Option added to option panel allowing the plugin to run only on posts in specific categories
    • Option added to option panel allowing the plugin to run only on posts by specific authors
  • 0.3
    • Improved pattern matching for images
    • 404 errors not processed
    • Flickr “image-not-found” jpg not processed
    • Improved local file naming
    • Replace feature was replacing URL in entire text. Now only replaces in IMG src.
    • Added feedback when options are saved.
  • 0.2
    • Added options panel
    • User can apply plugin to all external images or choose only to apply to Flickr
    • User can choose to either mark images by custom tag, or to replace image source
    • Custom tag name is user-definable
    • Improved regular expression matching
  • 0.1
    • Initial version

Tags: ,

Comments

The Apple tablet computer

MacBook Touch Mockup

MacBook Touch Mockup

The rumor mill has been flying for a while, and I think enough has been confirmed for us to say confidently that Apple is definitely going to release a tablet computer in the beginning of 2010. At this point, I believe we can safely say that computer will have a 10-inch electrostatic touch sensitive screen (like the iPhone), and it will most likely have a HSPDA connection to AT&T.

The part that’s unclear, though, is… well… everything else about it.

But here’s my theory:

The MacBook Air was an incredibly cool new addition to Apple’s laptop lineup, but it was really mostly a sales dud by most measures… and I think the only reason for that was that the price was too high. But I believe the Air was merely an interim product — a way to begin recovering some of the costs associated with designing a completely disconnected, paper-thin computer.

Think about it: if you take a paper-thin tablet computer, lose the touch-screen, and add a keyboard… what are you left with, if not a MacBook air?

So what, then, do I expect to see? I think the iTablet (or whatever they choose to call it) will be exactly that: a MacBook Air, sans keyboard. I believe it will fit into a manilla envelope the way the Air does… and I believe that alone will be enough to distinguish it from all the other tablet computer offerings we’ve seen so far. A 10-inch tablet that fits in an envelope is exactly what every traveler on earth wants.

But that’s not enough. OS X has had some excellent handwriting recognition software for quite a while, but it will be better if I don’t need a tablet to enter it. Such features make this an easy Kindle killer. And in fact, if you include a stylus and allow me to write directly on the screen, you might as well go that extra step allow me to use my new iTablet as the world’s best ever replacement for a Wacom tablet.

And if the rumors I’ve heard about it pairing magically with the iMac as a second screen are true, well, how could you not think it’s worth that $799-999 rumored price?

Tags: , ,

Comments

CSS Blinker

The secret to user-friendly forms in web apps is to draw attention to errors before submitting the form, and to do so without accosting the user with irritating Javscript popups.

After filling in half a dozen (or more) form fields and then pressing the submit button, the user has mentally moved on. Suddenly hearing a “clunk” sound and getting a popup that says “invalid ssn” is jarring to say they least… but it also means the user must now read through all the form labels looking for something that sounds like “invalid ssn”.

My solution is to flash the form field drawing the user’s attention to exactly what information needs to be fixed. And for that, I have created Blinker.js.

Just include Blinker.js into your page. Then, during validation, when a field is not valid, just call Blinker:

1
Blinker.blink('element-id', 'error-classname');

Blinker uses the supplied CSS classname to do the blinking, so you can use any effect you want: change the text color, change the background, underline, add a border, whatever floats your boat. Just declare the desired style in your CSS and then use that class name in your call, along with the DOM ID of the element to flash.

The scrollTo option allows Blinker to scroll a field into the viewport if it’s not visible. The onDelay and offDelay allow you to customize the rate of blinking, and cycle determines the number of times to flash.

Tags: ,

Comments

Recursive script inclusion with REQUIRE (C#)

This is the C# version of the script I posted earlier. It’s also available as a VB.net version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System;
using System.Collections;
using System.IO;
using System.Web;
 
public partial class javascript : System.Web.UI.Page
{
	private Stack files;
 
	protected void Page_Load(object sender, EventArgs e)
    {
		files = new Stack();
		Response.ContentType = "application/x-javascript";
		Response.Write(GetFile("js/Contacts.js"));
	}
 
	private string GetFile(string path)
	{
		string result = "";
		string filespec = HttpContext.Current.Request.PhysicalApplicationPath +
						 path.Replace("/", "\\");
 
		filespec = Path.GetFullPath(filespec);
 
		//if the file is already loaded, then exit
		if(files.Contains(filespec))
			return "";
 
		//add this file to the loaded list
		files.Push(filespec);
 
		//load the file
		string s = "";
		bool b = false;
		try {
			StreamReader sr = File.OpenText(filespec);
			do {
				b = true;
				s = sr.ReadLine() + "\n";
				if(s.IndexOf("//LIBRARY:") == 0)
					b = false;
 
				if(s.IndexOf("//REQUIRES:") == 0) {
					b = false;
					s = s.Replace("//REQUIRES:", "").Trim();
					result = result + GetFile(".." + s);
					s = "";
				}
				result = result + s;
			} while (sr.Peek() != -1 && !b);
			result = result + sr.ReadToEnd() + "\n";
			sr.Close();
		} catch {
			result = "\n/* Error loading file: " + filespec + " */\n"
		}
		return result;
    }
}

Tags: , ,

Comments

Recursive script inclusion with REQUIRE

One thing that tends to seriously limit the “best practices” when it comes to enterprise development and code reuse for Javascript is a lack of INCLUDE or REQUIRE functionality.

Code reuse and portability requires various functionality to be compartmentalized into individual .js files containing only related functionality, but on the web, including several files means making lots of unnecessary roundtrips, which can add up to a huge performance cost in the load time of your pages.

Good compartmentalized code also necessitates some sort of REQUIRE mechanism, which allows one unit of code (ie, script file) to specify when it won’t run properly without another unit of code.

Thus, while working on a VB.Net project, I created this simple Javascript loader, which looks at the name of the directory in which an app resides, and then looks for a javascript file by that name and loads it. Directives can be placed in that Javascript file (and in any subsequent file) requiring the inclusion of additional script files.

Not only does this allow for easier inclusion of libraries as needed, but it also makes it easier to strip out unused code if/when it is no longer needed by an app.

This source code is also available in a C# version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Imports System.IO
 
Partial Class javascript
	Inherits System.Web.UI.Page
 
	Private files As Stack
 
	Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
		files = New Stack()
		Response.ContentType = "application/x-javascript"
		Response.Write(GetFile("js/Contacts.js"))
	End Sub
 
	Private Function GetFile(ByVal path As String) As String
		Dim result As String = ""
		Dim filespec As String = HttpContext.Current.Request.PhysicalApplicationPath & path.Replace("/", "\")
 
		filespec = IO.Path.GetFullPath(filespec)
 
		'if the file is already loaded, then exit
		If files.Contains(filespec) Then Return ""
 
		'add this file to the loaded list
		files.Push(filespec)
 
		'load the file
		Dim s As String = ""
		Dim b As Boolean = False
		Try
			Dim sr As StreamReader = File.OpenText(filespec)
			Do
				b = True
				s = sr.ReadLine() & vbCrLf
				If s.IndexOf("//LIBRARY:") = 0 Then
					b = False
				End If
				If s.IndexOf("//REQUIRES:") = 0 Then
					b = False
					s = s.Replace("//REQUIRES:", "").Trim()
					result = result & GetFile(".." & s)
					s = ""
				End If
				result = result & s
			Loop While sr.Peek() <> -1 And Not b
			result = result & sr.ReadToEnd() & vbCrLf
			sr.Close()
		Catch ex As Exception
			result = vbCrLf & "/* Error loading file: " & filespec & " */" & vbCrLf
		End Try
 
		Return result
	End Function
 
End Class

This could be easily updated to work for CSS files as well.

Tags: ,

Comments