Code / Appnel Solutions 

Posted
24 October 2007 @ 12pm

So that's what it's for!

In my career I've been called in many times to figure out what another developer had done and not documented before becoming unavailable to answer for one reason or another. I guess I've developed a knack for it since these experiences of mine goes back to my days of Access 1.0 and Visual Basic 3.0. (Stop laughing. I'm not THAT old.) There have been many days then I thought I was a detective and not a programmer or that I should apply for a degree in forensic programming.

This skill is really helpful in getting the most out of Movable Type because of its generally under documented nature. (It is approving and will only get better.) Thankfully Movable Type has always had an open code base that has made this type of investigation easier then working with decompilers and looking through machine code.

Working on Feeds.App I came across is one of those small cases. I was integrating the Feed Widget Wizard in Feeds.App Lite back into Feeds.App and needed to make a registry entry for those modes. Lite has used code references that I don't like to use for reasons I'll detail here one day.

I looked to other examples where the registry entries was using handler names. There was one thing I found puzzling that I could find an explanation for. So code handlers where prepended with a dollar sign, plugin ID and double colon.

id => 'X',
key1 => {
    foo => 'MT::Plugin::X::foo_method' # no prefix
},
key2 => {
    bar => '$X:MT::Plugin::X::bar_method' # ID prefix.
}

I didn't understand why that ID was necessary in some entries and not used in others. It was confusing, undocumented (as far as I could see) and seemingly inconsistent. I looked at the handler_to_coderef method and notice that MT will load and create a code reference without the prefix. The addition step the prefix performed was wrapping the method in a subroutine that also did a temporary switch of the component from the caller to the plugin/addon. That didn't seem important or necessary so I tried without the ID being a student of less is more and minimalism.

Everything was fine the plugin loaded, MT didn't complain, menu items and actions appeared and templates rebuilt. When I got testing the wizard is when I hit trouble. MT couldn't find my templates though I was using the same code as what was working in Lite and MT3. I keep trying things until eventual I resorted to placing debugging messages in MT itself to reveal what it was doing. It wasn't going looking in my plugin's template directory, but MT's primary and alternate template directories. Why was that? More digging in the code I learned that MT uses the component to determine which template directories to search. The wizard is now implemented as a mode of MT itself, the new and recommended means, and not a separate script as was common in MT3.

Aha! So that is what that prefix is for! It switches the component so things like the template path can be located.

I haven't fully investigated which registry entries require this and which do not. I can verify application methods though.

Mystery solved though it still seems confusing and damn inconvenient. MT should know what plugin/component/registry it is loading so why should I be required to tell it again?

I can deal with a lack of docs generally, but it's this type of thing (inconsistency and inconvenience) that makes me unhappy as a developer.


5 Comments

Posted by
Chad Everett
24 October 2007 @ 2pm
Permalink

I also ran into these odd constructs, and encountered the handler_to_coderef function, but was unable to figure out the details of when to use which.

At this point, I'm using the $Component notation for callbacks, functions specified in tags and code specified in upgrade_functions, and they seem to work fine.

I was unable to use them registering list_actions, list_filters, menus and methods. Naturally you wouldn't use them in object_types either.

I don't know if that helps, but that's what I've found thus far!


Posted by
Chad Everett
24 October 2007 @ 2pm
Permalink

Let me amend that - actually, in the list_actions and methods, I do use the $Component notation, but not directly. Rather, I call an anonymous subroutine:

sub init_registry {
my $plugin = shift;
$plugin->registry({
applications => {
'cms' => {
list_actions => sub { My::Plugin::list_actions },
}
}
});
}

And there I have been unable to use the $Component notation. Within My::Plugin::list_actions, I can use it without a problem. I'm not sure why that is!

(Hopefully the formatting will work okay.)


Posted by
Timothy Appnel
24 October 2007 @ 3pm
Permalink

Thanks for the input Chad. Formatting looks fine. I need to clean up the comments submissions area on these blogs.

I have to agree this construct is also awkward in addition to being inconvenient. I'd just assume that be done away with then explained and documented really. Remembering which need the component prefix and which do not is just annoying to me. Having to prefix every component would be equally as annoying since its so redundant.


Posted by
Dan Wolfgang
26 October 2007 @ 9am
Permalink

This certainly offers a bit of clarity on some trouble I've had working with templates. Thanks.

The thing I've wondered about--and maybe this is best posted to mt-dev--is the greater reason for the name, key, and id. My knowledge is limited, but I can see why the name could be troublesome--something namespace- or variable-safe might be needed. But couldn't the name be... um, dirified, to use as an id or key? For example could the name "My Plugin" be dirified to the id "my-plugin" or similar?


Posted by
Timothy Appnel
26 October 2007 @ 11am
Permalink

Glad you found this helpful Dan.

I think the reasoning for the key or ID is necessary because the name could change overtime and would break any associations in the database and elsewhere. Where I am unclear is the purpose for introducing a plugin ID when the key already existed for what I thought was the same purpose -- uniquely identifying a plugin in a reliable machine readable way. I asked, but don't recall getting an answer.


Leave a Comment

← Before After →