Add suport for custom output

There is a site where I use WordPress Popular Posts in the last year. On this site I have to implement a custom layout with many extra fields defined by other plugins and the theme. It’s impossible to build this layout with the widget settings form.

After I examined the code of the plugin i created a patch. You can access it at pastebin.com: http://pastebin.com/303WF7mT This patch is for latest, 2.3.5 version (SVN Revision 724288)

Basically I added a filter called wpp_get_popular_posts_custom_display. If any plugin or theme implement this filter and create any output get_popular_posts() will return only this custom output.

With this patch I moved the query builder logick from get_popular_posts() into a standalon new function called query_posts().

why not use the wpp_get_mostpopular() template tag with the post_html parameter instead?

I sorry that I cannot say a lot about this project, but I’ll try to explain the situation for you.

So, as mentioned earlier, the posts have a lots of special, structured extra data. These data have to display for the users. I tried to write the post_html parameter, but with the placeholders, defined in WordPressPopularPosts::format_content() method, no way to show the special post meta fields, or other not handled data.

In earlier (2.3.2) version I extend WordPressPopularPosts class, I have to unregister your widget class and register my (overwritten) class to make it work. In my class I override get_popular_posts function, and call the original one with $return = true paramter. I got the posts data from your method, so i could write my own output. But in version 2.3.3 this method ignore the return parameter and returns all the formatted content. I do not like this way to create special formatted post output, because I built it on a non documented behaviour and i don’t think the widget replacement is a good long-term solution.

I think its a good think to use actions and filters in plugin development, so theme and plugin developers could add extra functions and features without hacking original code

Actually, it was easier than I expected. I just implemented a new filter for the get_popular_posts() method that provides access to the popular posts data array that you can use to build your own HTML markup.

It looks fine. My patch define a filter after the DB query and before the HTML markup builder codes. So when some plugin implement that filter, the default HTML build routine unnecessary to run. Because someone is want to override the default output.

I think the best we could do is define multiple filters.

Before HTML build, as in my first patch. With this we do not need default HTML builder behaviour (call it wpp_custom_html)

In the end of the foreach($mostpopular as $p) loop for every post output (wpp_post)

And a last one for the end, as you just defined wpp_html

=======================

If you don’t mind i give some advice. There are some principles I follow when write codes. A functions should do one and only one thing. When I keep my functions and methods as simple as possible at the end I get easily read and understandable code. Only two of these: KISS principle and DRY principle. You can read about these principles, and more in Clean Code by Robert C. Martin.

Now the WordPressPopularPosts::get_popular_posts() method is doing multiple things:

Builds an SQL query

Run the builded SQL query

Iterates over the results

In this loop builds a default HTML post output…

… but if the user set some custom post_html builds post HTML from that layout

With an intensive refactoring the code of WordPressPopularPosts can become extremely readable and much more developer friendly. If you have a clean code you can implement new features faster and safely.

If you think and don’t mind i can help to refactor your code. What do you think?

When I created the _get_title() method I realized this new function will be called two times on every post rendering. It will be called to create the $title variable in render_popular_post function and it will be called again in _get_thumb().

The _get_title() can be resource-intensive method if qtrans is presented and other plugins/themes are defined some filter on the_title. So we can save some time and resource if we use the previous result.

This cache is only available for runtime. It uses a static variable for store datas.

Thanks for the input! I’ve been following the changes on your github account. Left a comment there about image_resize and the code you mentioned.

Also, seeing your work made me want to rework the plugin – so I took most of your suggested changes and merged them into a newer version I’ve been working on. I’ll be probably uploading this version to Github as well, maybe this weekend, so I’m probably going to merge any new commits you’ve made that I may have missed.

By the way, I’ve finally moved the plugin to GitHub. It’s updated until version 2.3.5 (current official release), and I’m already commiting changes and bug fixes there. There’s a more recent version of WPP based on Vince’s code refactoring, but it won’t be available yet since I want to release a stable 2.3.6 before jumping to 3.0.0.