When I wrote up my (initial) tweaks to the Summary plugin, Rick Cockrum helpfully pointed out in his comment how it would be possible to avoid changing the core code just to change the presentation of the extra textarea. I fully agree that should be avoided whenever possible (and had hoped it would be possible), so I set out to make the proposed change and managed to make it work after a small modification. But now I've done it again, and this time I believe there really is no way around it.
Formatting
When you type in an entry, you don't need to add paragraph tags: these get added automagically when the post is displayed. This magic works quite well in practically all cases, so naturally I wanted that to happen for my (often multi-paragraph) summaries as well. What is more, I would like to implement MarkDown formatting for both the main entry and its summary as well — no doubt a similar process — so I'd better find out how this works. That turned out to be much harder than I expected, due to Habari's own flavor of magic. The first thing I noted was patterns.
Patterns
In the theme.php file of the theme I am currently using (for now), I noted some apparent formatting taking place, like this:
// Apply Format::autop() to post content: Format::apply( 'autop', 'post_content_out' );
$out = Plugins::filter( "post_{$name}", $out, $this ); if ( $filter ) { $out = Plugins::filter( "post_{$name}_{$filter}", $out, $this ); }
Analogies
A post's content is represented by:
$post->content
$post->content_out
post_content_out
Now the summary:
The summary's content is represented by (see the action_publish_post() function):
$post->info->summary
$post->info->summary_out
$post->info_summary_out
$post->info_out
post_info_summary_out
post_info_out
I tried a lot of things but there were two problems: first of all that extra level so creating analogous patterns was not quite straightforward; and second I could not figure out how to create an extra function in Summary that would mimic what __get() was doing in post.php, and maybe somehow "bridge" that extra level as well. Whatever I tried, I either got an error message, or nothing at all.
During all this trial and error I was also re-reading the various functions involved, and gradually began to explain to myself how the mechanism works.
The mechanism
This is how I understand it now:
- When a construct like $post->content_out is encountered, this (somehow) triggers __get() in post.php to be called with content_out as parameter
- The function detects that this is not a standard property of $post and parses it into a $name part ('content') and a $filter part ('out'). These are then used to first retrieve the data indicated by the $name part, and then create a plugin hook called 'post_content_out'
- But, this is only a hook; nothing will happen at this point unless there is a function (or more than one) that is registered to use it. This is what happens with the Format::apply( 'autop', 'post_content_out' ); statement: the apply() function dynamically creates a function which applies autop() and registers it for the (also dynamically created) post_content_out hook which operates on the data retrieved by __get() just before. So this is where the real magic happens!
The problem
And herein lies the problem: __get() parses its parameter to see what data is requested, retrieves that data, and creates a hook for it; but it uses a switch statement to find which existing or custom object property is requested… while Summary adds its own custom property. And I can see no mechanism for Summary (or any other plugin, for that matter!) to add another property to the list of properties recognized by __get(), or to somehow supplement that with its own parsing-and-hook-creation mechanism.
Once I got to this point I gave up, and broke in: I just added another case to the switch statement in __get():
case 'info_summary': // mk 20081203 added for Summary plugin $out = $this->get_info()->summary; break;
// apply output filter for summary - works in combination with post.php extension Format::apply( 'autop', 'post_info_summary_out' );
Even better: Summary also adds the summary text to the Atom feed, and this can now be formatted as well with a slight modification to Summary's action_atom_add_post() which I now have as follows:
/** * Add summary element to Atom feed, if a summary is present. * * @param SimpleXMLElement $feed_entry * @param Post $post The post corresponding to the feed entry */ public function action_atom_add_post($feed_entry, $post) { if ((boolean) $post->info->summary) { // apply output filter for summary - works in combination with post.php extension (as in theme) mk 20081203 Format::apply( 'autop', 'post_info_summary_out' ); // add formatted summary to feed $entry_summary = $feed_entry->addChild( 'summary', $post->info_summary_out ); $entry_summary->addAttribute( 'type', 'html' ); } }
Solution?
But is this a real solution? I think not. And why shouldn't a plugin that produces its own content be able to use existing formatting functions for that content?
Of course it's entirely possible I still have overlooked a possible mechanism for Summary to accomplish this without breaking into the __get() function in post.php and add a few lines there.
But it seems to me the real problem is the fixed list of property types that the __get() function uses. If this list could be stored as data instead of in code, with a mechanism for plugins to extend that list, there would be no need to break into the code.
Did I miss something? (I'm still very much a Habari noob, after all!) Is it a stupid idea to turn the list of recognized $post properties into (extensible) data, instead of code? Please let me know!


0 Responses to I broke in again (sorry)
Leave a Reply