Annoyances: vBulletin 4 Template Hooks

I’ve been doing commercial software development for vBulletin 3.x (and, by extension, 4.x) off and on now for a couple of years. While there are some things that irritate the crap out of me about both of these products, vBulletin (both versions) have features that just aren’t found in other bulletin board packages. Admittedly, many of these exclusive features are provided by an extensive library of 3rd party software, but the point still stands–as much as I hate to admit it. Few other message boards have a plugin system that’s easy to develop for, and fewer still have the vast library of plugins available. phpBB doesn’t even come close. vBulletin still has its shortcomings for developers, but I’ll save my complaints for a later installment.

What I’m going to write about tonight is something that bit me, and I know it’s going to bite someone else out there: Template hooks have been the bane of my existence in vB4 for the majority of this weekend, and once you start adding a few yourself, you’ll grow to appreciate the manic schizophrenia that is the vBulletin 4.x template system in all its unadulterated glory. I hope to save you from the onset of severe insanity, so keep reading for my story and my solution.

Side note: You might also want to make this a summer project, because you’ll be bald by the time you’re finished, and I understand that bald heads get cold quite quickly. If you’re already bald, accept my apologies and tear something else out–like the upholstery stuffing in your desk chair. Don’t have a chair? Reach for the carpet. Don’t have carpet? Well, you’re on your own.

Template Hooks: They Work–But not When You Want Them To

I’ve written a couple of plugins that rely on the various forumhome_wgo_pos* template hooks for both vBulletin 3.x and 4.x. These hooks work perfectly for most use cases, regardless of when your plugin fires, and are almost foolproof. Don’t be lulled into a false sense of security, though. The moment you do anything unusual with template hooks in vBulletin 4.x, you’ll be bitten by the what-the-heck-happened-to-my-output surprise.

To reproduce the ailment that has been afflicting my sanity for the better part of this last Sunday, I direct you to a simple test:

  1. Create a new product, complete with its very own plugin.
  2. Set the plugin to fire on the global_start plugin hook.
  3. Add the following code to the plugin:
    $template_hook['footer_test_hook'] = '<b>Hi!</b>';
  4. Add the following code to your footer template:
    {vb:raw template_hook.footer_test_hook}
  5. Run it!

You should notice that you now have a nice, shiny string containing Hi! at the bottom of your page in the footer code. Now, let’s break it:

  1. Add a template, such as break_my_footer to your product XML (optional; you could use any other template if you like)
  2. Call this template from your plugin using something like:
    $tpl = vB_Template::create('mytemplate');

    Or, if you decided to use an existing (small) template:

    $tpl = vB_Template::create('option');
  3. Then modify your template hook code appropriately:
    $template_hook['footer_test_hook'] = htmlentities($tpl->render());
  4. Watch in horror as nothing appears in your footer.

Try as I might, I spent a good hour or two trawling various vBulletin support sites for answers. Rather than make a post somewhere and risk having one of their ill-tempered devs explain “Well, this is how it’s supposed to work, didn’t you use the search?” when the built in search generally sucks and Google doesn’t always pick up their help threads, I decided that this issue became personal. That is to say, this code insulted my mother, my father, my nonexistent siblings, and each of my ancestors going back 1,500 years.

After performing various blind tests I concluded that somehow the call to the vB_Template::create() factory method was effectively wiping the contents of $template_hook–or ignoring it, or purging it, or performing an exorcism on it with tremendous glee while I steamed with fury in front of my monitor. I then decided that I’d had enough, and so I searched for the footer template to determine where it was being called, prepared, and possibly rendered in the code. My hunch was that the footer was being generated separately from the forumhome cruft that so happily seemed to work no matter where I used it or what I did with it (and indeed it is generated separately). Yet my own template hook refused to work.

Then I came across this code in includes/class_bootstrap.php:

 $templater = vB_Template::create('footer');
                        $templater->register('admincpdir', $admincpdir);
                        $templater->register('ad_location', $ad_location);
                        $templater->register('cronimage', $cronimage);
                        $templater->register('languagechooserbits', $languagechooserbits);
                        $templater->register('modcpdir', $modcpdir);
                        $templater->register('quickchooserbits', $quickchooserbits);
                        $templater->register('template_hook', $template_hook);
                        $templater->register('facebook_footer', $facebook_footer);
                $footer = $templater->render();

Pay careful attention to the line $template->register('template_hook', $template_hook);. Clearly, the footer is processing the template hook here–so I thought to myself, perhaps there’s a nearby hook that I could attach my plugin to so I can guarantee I know that the content of $template_hook won’t be interfered with.

I scrolled up and found a hook that probably should have been fairly obvious to me from the start. But hey, it’s the weekend. What more can you expect?

($hook = vBulletinHook::fetch_hook('parse_templates')) ? eval($hook) : false;

Sheepishly, I changed my plugin to use the parse_templates plugin hook instead of global_start, and it worked! So the upshot is: If you’re going to try using custom template hooks and you discover that they won’t work the moment you load a template, try changing the plugin hook to parse_templates. It might just fix the problem.

Now, this was admittedly all my fault for not realizing that parse_templates may be the correct solution; I really should have examined the vBulletin sources more closely. Shame on me. In my defense, though, the vBulletin documentation is pretty poor, much of it is outdated, and even less of it focuses on issues specific to 4.x. However, I have one particular bone to pick: It’s puzzling to me that whatever is in $template_hook will work fine up until the moment you decide to call vB_Template::create(). There’s a comment under the create() method that indicates something to do with $template_hook and treating it as a special case for the purpose of various globals or some such, along with a reference to a bug tracker ID. I think that’s more coincidental than anything else, and certainly if I wanted to find out what was happening, I could run a trace with XDebug, but I’m not that desperate–or bored (yet). My guess is that, somehow, subsequent calls to vB_Template::create() clobber the contents of $template_hook by the time vBulletin gets around to rendering the footer; I may be wrong–I probably am–but this is an example of bizarre code suffering from manic schizophrenia.

Frankly, the vBulletin sources are so stupidly convoluted it’s a miracle the software works as well as it does. I’ll save that for another rant much later this week or next. In short, remember: If you’re toying with custom template hooks, you might just break your code. If you do, try changing the plugin you’re writing for template rendering purposes to hook into parse_templates. You’re almost guaranteed to have little to no interference with the contents of $template_hook and the parse_templates hook is nearest to the templates that are most likely to be affected.

Toodles for now. Expect to see a whiny rant soon!

3 comments.
***

Annoyances: Video Tutorials

I’ve ranted about this before in another post, but it’s so damnably obnoxious that I can’t contain myself.

Before I start, I want to address the disagreement some of you are bound to have–yes, yes, I know that video tutorials have their place. For example, they might be exceedingly helpful for individuals whose tech level is below such threshold that they have a difficult time understanding the difference between left and right click. Or perhaps it’s a topic that requires some visual guidance such as conceptual demonstrations for Blender, Photoshop, or various other things that are highly interactive and not easily explained. (I still appeal that a skilled writer can explain anything with the written word that a video tutorial can–it’s just that some things are easier to convey visually.)

That, of course, is not the point of this post. The point is that there is a right way to illustrate simple concepts such as a single configuration change in an OS, and there are many more wrong ways to do the same thing.

Here’s an example. I haven’t (until recently) been using Ubuntu much, mostly because I’m in the process of abandoning Gentoo. Thus, I couldn’t remember specifically how to move the window interaction widgets (close, minimize, and maximize) to the right. I immediately stumbled across numerous sites that had embedded Youtube videos like this one.

I promptly closed them.

Video tutorials are a time sink. Generally, the viewer will have wasted at least one minute listening to someone introduce themselves, why they’re important, and then rant about whatever solution they’re going to demonstrate. Then, when the star of the show finally gets to the meat of a discussion that should take less than 15 seconds to explain, they invariably drone on and on about what items to click on, where to enter the change, and we get to stumble over each typo with our hapless host for 20 painful seconds. Once we’re finally presented with useful information, our brains have collectively rotted so severely that we have no recollection of what we were initially researching or attempting to resolve. This is the wrong way to share information. Worse, if one were to add up the total time consumed by video tutorials, minus the 5 seconds of useful information, there are hundreds of hours being wasted every day. It may not be Farmville, but it is close.

Side note: I’m not picking on the video I linked to above–I actually haven’t watched it–but I did see one earlier today where it took the individual recording it about 5 attempts to type gconf-editor correctly.

How then is the right way to do this? Easy. Howtogeek typically does things the right way in a manner that is insanely easy to follow, and you’d have to be comatose to have any difficulty with their tutorials. There are many more examples of how to illustrate a very simple concept quickly and efficiently, both in terms of time and bandwidth.

In other words, a good rule of thumb to follow is that if you can explain the concept in less than a paragraph, a video tutorial is like nuking your house from orbit because you’re too inept to fumble around for a slipper to kill that pesky house spider. That there are video tutorials on how to boil water worries me. Has our society grown so collectively dependent on instant gratification that we can’t so much as spend the time to read something?

Hint: It almost always takes longer to sit and watch an instructional video than it otherwise would to read those same instructions. Ever wonder why those cabinet kits you buy at the store have a piece of folded paper stuffed inside the hardware bag instead of a DVD? Paper is cheaper, for one, and for two, the average consumer is free to stare at the diagram (usually poorly written) for as long as they like; with an equally poorly recorded instructional video, I can only imagine that same consumer replaying the same 5 second segment two or three dozen times trying to figure out that the wooden dowel does, in fact, go inside the hole.

Let me reiterate my pet peeve about frivolous video tutorials:

Stop.

This.

Insanity.

Right.

Now.

Your unnecessary video tutorials are wasting bandwidth, and for most people looking for a quick solution (or reminder), a video tutorial is simply going to waste their time. Certainly, video tutorials are handy for individuals who may not know where to click on something, but I don’t see how it’s any faster than making a single post with a handful of easy to follow written instructions. Click here, click here, type this, press enter, look for item X, change it to Y, click close, done. See? Easy.

For those of you who link to every single obnoxious video tutorial on Youtube for all of your woes, please stop. Find something more meaningful like a textual post. It might surprise you to discover that some of us know how to read.

Video rots the brain, and get off my lawn.

Update: I decided to do some research, and while it doesn’t specifically address video tutorials, I think that usability expert Jakob Nielsen has an article worth reading that targets video on the web. It’s not the same thing, but I do feel that it applies tangentially to this topic.

No comments.
***

Dreams are Weird

I haven’t had much of a chance to catch up on a few things I was hoping to post about, but I had the most unusual experience Tuesday morning. It was so strange, in fact, that I can’t help myself from sharing it with you.

I have almost always had trouble sleeping. As far back as I can remember, I tossed and turned most school nights for whatever silly reasons kept a young boy of that age awake. I suppose it would have been (and may still be) diagnosed as some form of insomnia, but I confess that sometimes–sometimes–it is worth more to me than all the gold in the world.

Monday night/Tuesday morning was one such experience. For the first time in my life, I couldn’t get any sleep because every thirty minutes I was waking up laughing. I’m not talking about a foggy-minded chuckle, either. You know the sort: You’ve stayed up far later than any sane person would otherwise do and everything is just stupidly hialrious. Except it totally wasn’t like that at all. I think I woke up laughing at least 5 times with a loud cackle. Worse, it was my laughter that woke me up. Every time. I really wish I could remember what I was dreaming about each of those times, but I can only recall one. It made absolutely no sense, but the premise was so ridiculous I couldn’t keep myself from laughing.

It would’ve been classified as a partial flash back dream. I know you have all had this sort from time to time: You’re back in school, you’re sitting in a familiar class, maybe the instructor is someone you know–or someone you don’t–and you haven’t any idea what you’re doing there. You’re just there. I don’t recall a great deal about the class other than it was a rather peculiar combination of some room I vaguely recall from high school mixed with about three other locations at two different college campuses. I also recall that it was a mixed class–military, older folks, and younger folks all tossed in together.

Oh, and the marine I was sitting behind in this dream was ranting about some enlisted army man he couldn’t stand. That’s where this dream begins to break down into hilariousness. Not only was the marine complaining out loud, but before he was finished, he pulled a banjo out of thin air and started singing his disgust with his compatriot from another branch of the services. Weirder still, in the middle of his melodic rant about some poor army serviceman, two other guys in the class room pulled out their own banjos and started singing backup vocals. The entire scene was so outrageous and so silly that I started laughing. And laughing. And laughing.

Then I woke up–still laughing.

Sleep deprivation sucks. However, I have to confess something to you: If you’re going to be sleep deprived, it’s just way too awesome to be deprived because you can’t stop laughing in your sleep.

No comments.
***