NSString+Templating
I haven’t posted any code to this site for awhile, and I think that’s a shame. So I’m going to remedy that tonight by publishing a handy little NSString category I wrote for use in my personal projects. This category, which I have christened “NSString+Templating,” arose out of two things: first, my frequent observation that a quick and dirty text templating mechanism is a very useful thing to have around; and, second, the huge appreciation I’ve recently gained for the “Key-Value Coding” design pattern.
So, where to start…
For those who aren’t familiar with Objective-C, the language has a rather unique feature in the notion of categories. Essentially, categories allow programmers to add functionality to existing classes—not by subclassing them, as is common in OO languages, but rather by grafting new methods onto existing classes. Thus, anyone can teach Cocoa’s standard string class (NSString) new tricks rather than creating a subclass called “MyFancyString” or something (this approach has its pros and cons, natch).
As it happens, my category adds one method to NSString (yes, I realize the selector is rather long, but I couldn’t think of a more succinct way of expressing what the thing does!):
- (NSString *) stringByParsingTagsWithStartDelimeter: (NSString *) startDelim endDelimeter: (NSString *) endDelim usingObject: (id) object;
The first two parameters (startDelim and endDelim) specify what will be recognized as a tag (I’ve been using “< $" and "/>”), and the last specifies an object that will provide the values to replace the tags.
This last bit is where the key-value coding comes into play. To determine the replacement value for a given tag, this code will use the tag’s “name” as a key to query the object. Thus, if the text contains a tag called “< $firstName/>,” the code will query the object using the “firstName” key. If the object responds to that method, the tag will be replaced with its return value (if not, the tag will be replaced with nothing).
The value returned from the key method must be coercible by NSString stringWithFormat: (using the ”%@” format string) into text. Fortunately (and surprisingly), this seems to include all of the “primitive types” (int, double, etc.) and any object that implements a “description:” method. In most cases, it “just works!”
(Update: It seems I was correct about the primitive types “just working,” but I was wrong about the reason why. See my addendum for more information.)
The source and header files (I didn’t put them into a project, since I’m using Xcode exclusively now) can be downloaded here:
- NSString+Templating.dmg (9k)
If anyone has any improvements or suggestions, I’d be interested in hearing them. I can think of a lot of interesting places this could be taken in the future (adding conditional branching, à la Rael Dornfest’s “Interpolate Fancy” Blosxom plugin, would be one example).
August 15th, 2005 at 12:05 pm
Hey there; saw this a long time ago in the sci-fi hi-fi feed, and I just now realized how badly I need it.
I’m going to be using it in my invoicing program– I generate invoices via HTML templates, y’see– and I just wanted to say thanks.
November 1st, 2005 at 1:46 pm
Funny, I will also be using it in an invoicing program.
January 18th, 2006 at 9:47 pm
Your “addendum” link is broken! So I can’t see what the resolution about ‘%@’ was. (My understanding is that it’s identical to calling -description.)
This is somewhat similar to the template engine that Syndication uses. Mine’s more powerful in some ways (it can do limited conditionals and looping) but your use of KV coding is more elegant; something I wish I’d thought of back then.
I’ve got a new template engine in the stuff I’m experimenting with now … at the moment it uses an embedded Lua interpreter plus the open-source ObjC/Lua bridge. I’ll probably replace it with something less outrĂ© before shipping; partly I was just looking for some excuse to use Lua =)