{"id":909,"date":"2008-12-17T01:21:40","date_gmt":"2008-12-17T01:21:40","guid":{"rendered":"http:\/\/www.nargalzius.com\/blog\/archives\/2008\/12\/17\/wordpress-plug-in-hacks\/"},"modified":"2017-02-10T02:33:49","modified_gmt":"2017-02-10T02:33:49","slug":"wordpress-plug-in-hacks","status":"publish","type":"post","link":"http:\/\/nargalzius.com\/blog\/archives\/2008\/12\/17\/wordpress-plug-in-hacks","title":{"rendered":"WordPress plug-in hacks"},"content":{"rendered":"<p>I&#8217;ve been meaning to post this ever since I transitioned to the new blog.<\/p>\n<p>I&#8217;ve already explained in <a href=\"http:\/\/www.nargalzius.com\/blog\/archives\/2008\/12\/08\/wordpress-vs-mt-revisited\">another post<\/a> the frustrations I have with regards to the approach of WordPress plugins <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_1');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_1');\" ><sup id=\"footnote_plugin_tooltip_909_1_1\" class=\"footnote_plugin_tooltip_text\">1 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_1\" class=\"footnote_tooltip\">How &#8220;snobbishly self-contained they tend to perform, etc.<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_1').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_1', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script><\/p>\n<p>This post however is to assert that despite all these &#8220;limitations&#8221; there is one developer that seems to have found an awesome workaround &#8211; and if people just get on board with his plugin architecture, most of the &#8220;silly issues&#8221; plaguing WP plugins could be solved.<\/p>\n<p>So yeah, I guess this post is more of an evangelical one to [hopefully] give more exposure to <a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Mr. Rob Marsh SJ<\/a> and his extremely versatile <a href=\"http:\/\/rmarsh.com\/plugins\/post-plugin-library\" title=\"Post-Plugin Library\">Post-Plugin Library.<\/a><!--more--><!--\/\/--><\/p>\n<h1>Sample Problem<\/h1>\n<p>Just to practically demonstrate the &#8220;issues&#8221; I have, lets take any individual entry page in my site; like what you&#8217;re reading right now. <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_2');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_2');\" ><sup id=\"footnote_plugin_tooltip_909_1_2\" class=\"footnote_plugin_tooltip_text\">2 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_2\" class=\"footnote_tooltip\">Assuming you&#8217;re not reading this through an RSS reader<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_2').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_2', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> At the bottom of this page, we have the <em>&#8220;Probably Related&#8221;<\/em> section. <\/p>\n<p>For any advanced user, it goes without saying that <em>that&#8217;s<\/em> the work of a plugin. And plugins tend to hit-or miss as far as crafting the exact output code goes.<\/p>\n<p>My blog, unfortunately, already has a specific &#8220;format&#8221; as far as what data and visual elements are exposed; this was since I first made it in MovableType and that layout has been set in stone for &#8220;user interface efficiency.&#8221; These plugins, taken individually, do not support that level of detail on their own. <\/p>\n<p>For example, there are a lot of &#8220;Related Posts&#8221; plugins available&#8230; but my particular related posts entries need to have a <strong>primary category<\/strong> icon. WordPress supports multi-categories, but doesn&#8217;t have any provision for calling the primary category&#8230; so you need <em>another<\/em> plugin to do that&#8230; which is obviously <em>not<\/em> included (why should it be?) in the &#8220;Related Posts&#8221; plugins you will find floating around. Same goes for the need of a word-count&#8230; or a better way of displaying excerpts.<\/p>\n<p>All of which by the way are available through <em>separate plugins.<\/em> But like I said in the beginning, unlike MovableType, these plugins tend to only look after themselves&#8230; and not take the time to &#8220;integrate&#8221; with the system as a whole. <\/p>\n<p>So If say I did a simple call to that excerpt plugin I use within the &#8220;Related Posts&#8221; (whether hacked the code, or if the plugin supports inline function calls <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_3');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_3');\" ><sup id=\"footnote_plugin_tooltip_909_1_3\" class=\"footnote_plugin_tooltip_text\">3 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_3\" class=\"footnote_tooltip\">Which I&#8217;ll get to in a minute<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_3').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_3', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> ) &#8211; <strong>all the excerpts<\/strong> of those &#8220;posts&#8221; will be a single excerpt of the main post you&#8217;re reading &#8211; because it will not recognize that you&#8217;re calling it from within another plugin which is essentially doing a new &#8220;the_loop.&#8221;<\/p>\n<h1>Rob Marsh&#8217;s Post-Plugin Library<\/h1>\n<p><a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Rob Marsh,<\/a> a Jesuit <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_4');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_4');\" ><sup id=\"footnote_plugin_tooltip_909_1_4\" class=\"footnote_plugin_tooltip_text\">4 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_4\" class=\"footnote_tooltip\">I just had to mention that since I studied in a Loyola school as well<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_4').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_4', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> approaches plugin development very practically with his <a href=\"http:\/\/rmarsh.com\/plugins\/post-plugin-library\" title=\"Post-Plugin Library\">Post-Plugin library<\/a><\/p>\n<p>His general approach to plugins allows the user to practically have <em>complete control<\/em> over the output formatting &#8211; by using template tags within the plugin. Plugins using their own template tags is not new, however this in conjunction with the Post-Plugin Library makes even the tags themselves extendable.<\/p>\n<p>For example, here&#8217;s the &#8220;output&#8221; code I &#8220;set&#8221; on my &#8220;Probably Related&#8221; entries. <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_5');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_5');\" ><sup id=\"footnote_plugin_tooltip_909_1_5\" class=\"footnote_plugin_tooltip_text\">5 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_5\" class=\"footnote_tooltip\">And yes, those ARE table elements, I don&#8217;t give a shit if they&#8217;re deprecated<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_5').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_5', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script><\/p>\n<pre><code>&lt;tr&gt;\n    &lt;td valign=\"top\" class=\"nRecentItemSide{alternate}\"&gt;\n        &lt;div class=\"nItemTime\"&gt;&lt;a href=\"{url}\" title=\"Read \"{title}\"\"&gt;{date:Y.m.d} {time}&lt;\/a&gt;&lt;\/div&gt;\n        &lt;div class=\"nItemTopic\"&gt;&lt;a href=\"http:\/\/nargalzius.com\/blog\/archives\/category\/{topcat}\" title=\"Primary Category: {topcat}\"&gt;{topcat}&lt;\/a&gt;&lt;\/div&gt;\n        &lt;div class=\"nItemWords\"&gt;{wordcount} words&lt;\/div&gt;\n        &lt;div class=\"nItemComment\"&gt;&lt;a href=\"{url}#comments\" title=\"view\/post comments\"&gt;{commentcount:No comments:comment:comments}&lt;\/a&gt;&lt;\/div&gt;\n    &lt;\/td&gt;\n    &lt;td valign=\"top\" class=\"nRecentItemMain{alternate}\"&gt;\n        &lt;div class=\"nRecentItemTitle\"&gt;&lt;a href=\"{url}\" title=\"Read \"{title}\"\"&gt;{title}&lt;\/a&gt;&lt;\/div&gt;\n        &lt;div class=\"nRecentItemContent\"&gt;\n            {advexcerpt}\n            &lt;div class=\"read_more\"&gt;&lt;a href=\"{url}\" title=\"View individual entry\" class=\"nMainEntryButton nRead\"&gt;READ&lt;\/a&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n    &lt;\/td&gt;\n    &lt;td class=\"nArchivePostRows{alternate}\"&gt;\n        &lt;a href=\"http:\/\/nargalzius.com\/blog\/archives\/category\/{topcat}\" title=\"Primary Category: {topcat}\"&gt;&lt;img src=\"http:\/\/www.nargalzius.com\/f\/i\/blog\/icon_topic_{topcat}.jpg\" alt=\"\" \/&gt;&lt;\/a&gt;\n    &lt;\/td&gt;\n&lt;\/tr&gt;<\/code><\/pre>\n<p>The template tags are in the curly braces, and you can see the list of commonly available tags (thanks to the Post-Plugin Library) <a href=\"http:\/\/rmarsh.com\/plugins\/post-options\">here.<\/a> But also notice that there are tags in there that <em>aren&#8217;t<\/em> included in the documentation such as <code>{alternate}<\/code>, <code>{topcat}<\/code>, <code>{advexcerpt}<\/code>, and <code>{wordcount}<\/code> among others.<\/p>\n<p>That&#8217;s because they were added by me. And that&#8217;s my whole point of evangelizing this library. <a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Mr. Marsh<\/a> designed it in such a way that you can easily add tags and functions and they&#8217;ll immediately be useable across <strong>all<\/strong> of his plugins. Now imagine if every developer would use the same framework&#8230; I mean they wouldn&#8217;t have to reinvent anything &#8211; it&#8217;s already made&#8230; all they have to do is use it.<\/p>\n<p>And to tell you the truth, if you install any of <a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Mr. Marsh&#8217;s<\/a> plugins, and see how configurable they are, they practically cover every customizable element you can think of &#8211; so the framework itself is very well thought out.<\/p>\n<h1>Enough of the pimping<\/h1>\n<p>I think I&#8217;ve said enough, if people don&#8217;t leverage this framework for their own needs, its <em>their loss.<\/em> I on the other hand, would like to share some &#8220;additions\/hacks\/modifications&#8221; I made to the library which allowed me to achieve the level of detail and visual eye-candy with the plugins.<\/p>\n<p>Most of the code snippets below essentially make it possible for the Post-Plugin Library to &#8220;tap into&#8221; other plug-in&#8217;s functions and use those functions for itself (and the plugins that use it). <\/p>\n<h2>TopCat<\/h2>\n<p>Add this block of code in <code>output_tags.php<\/code>to be able to use the <code>{topcat}<\/code> tag<\/p>\n<pre><code>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ INTEGRATE TOP CAT PLUGIN\n\/\/ http:\/\/www.thunderguy.com\/semicolon\/wordpress\/top-cat-wordpress-plugin\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\nfunction otf_topcat($option_key, $result, $ext) {\n\n    $top_category = '';\n\n    if(function_exists('topcat_the_main_category')) {\n        $top_category = topcat_get_the_main_category($result-&gt;ID);\n    } else {\n        $top_category = 'SORRY, THE {topcat} FUNCTION DOESN\\'T EXIST';\n    }\n\n    return $top_category;\n}<\/code><\/pre>\n<h2>Alternating rows<\/h2>\n<p>This is not a plug-in per se, but I do like styling alternating classes (i.e. multiple rows having alternating colors). So this addition was just begging to be made.<\/p>\n<p>Add this block of code in <code>output_tags.php<\/code>to be able to use the <code>{alternate}<\/code> tag<\/p>\n<pre><code>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ CUSTOM FUNCTION THAT SETS A VARIABLE FOR ALTERNATING ROWS\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n$classAlternate = 0; \/\/ REQUIRED FOR FUNCTION BELOW\n\nfunction otf_alternate($option_key, $result, $ext) {\n    global $classAlternate;\n    $classAlternate++;\n    $classDistinction = '';\n\n    if(!($classAlternate%2)) {\n        $classDistinction = 'A';\n    } else {\n        $classDistinction = 'B';\n    }\n\n    return $classDistinction;\n}<\/code><\/pre>\n<p>The only problem with this is that it exposed a bug in the Plugin Library&#8217;s hierarchy of processes. I had to set all the plugins to default sorting because I ended up having unpredictable class assignments precisely because the [alternating] classes were already assigned (while it was generating the <em>unsorted<\/em> output) then jumbled up because of the other sorting options.<\/p>\n<p>Technically, the &#8220;output&#8221; formatting should be applied as the very last step (literally right before it actually generates the html code. So if you set it to have some special grouping or sorting parameters&#8230; have it do those things <em>then<\/em> apply the formatting to the results.<\/p>\n<h2>Word Counter<\/h2>\n<p>Add this block of code in <code>output_tags.php<\/code> to be able to use the <code>{wordcount}<\/code> tag<\/p>\n<pre><code>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ INTEGRATE WORD COUNTER PLUGIN\n\/\/ http:\/\/www.murraywilliams.com\/software\/word-count-plugin-for-wordpress\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\nfunction otf_wordcount($option_key, $result, $ext) {\n    if(function_exists('mtw_string_wordcount')) {\n        return mtw_string_wordcount($result-&gt;post_content);\n    } else {\n        return \"SORRY, THE {wordcount} FUNCTION DOESN'T EXIST\";\n    }\n}<\/code><\/pre>\n<h2>Avanced Excerpt<\/h2>\n<p>Here&#8217;s a perfect example of why I love the library. There is actually an <code>{excerpt}<\/code> tag in the Post-Plugin Library. The trouble is that it sucks; it doesn&#8217;t parse Markdown code at all, etc. etc. Sufficed to say it wasn&#8217;t working for me.<\/p>\n<p>What does work though is the <a href=\"http:\/\/sparepencil.com\/code\/advanced-excerpt\">Advanced Excerpt Plugin<\/a> from <em>Sparepencil.<\/em> Thanks to the extendability of the Library, I was able to add the function and use that instead for my excerpts.<\/p>\n<p>Add this block of code in <code>output_tags.php<\/code> to be able to use the <code>{advexceprt}<\/code> tag<\/p>\n<pre><code>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ INTEGRATE ADVANCED EXCERPT PLUGIN (BRUTE FORCE)\n\/\/ http:\/\/sparepencil.com\/code\/advanced-excerpt\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\nfunction otf_advexcerpt($option_key, $result, $ext) {\n\n$text = '';\n\n    if (class_exists('AdvancedExcerpt')) {      \n\n        \/\/ HACKED SCOPE\n        $length = (!is_null($length)) ? (int) $length : get_option('AdvancedExcerpt' . '_length');\n        $use_words = (!is_null($use_words)) ? (int) (bool) $use_words : get_option('AdvancedExcerpt' . '_use_words');\n        $ellipsis = (!is_null($ellipsis)) ? $ellipsis : get_option('AdvancedExcerpt' . '_ellipsis');\n\n        $allowed_tags = (is_array($allowed_tags)) ? $allowed_tags : get_option('AdvancedExcerpt' . '_allowed_tags');\n        $allowed_tags = implode('&gt;&lt;', $allowed_tags);\n        $allowed_tags = '&lt;' . $allowed_tags . '&gt;';\n\n        \/\/ HACK: FORCE-FEED CONTENT TO PARSE\n        $text = trim($result-&gt;post_content);\n\n        $text = apply_filters('the_content', $text);\n        $text = str_replace(']]&gt;', ']]&gt;', $text);\n        $text = strip_tags($text, $allowed_tags);\n\n        if(1 == $use_words) {\n\n            \/\/ Count words, not HTML tags\n            if($length &gt; count(preg_split('\/[\\s]+\/', strip_tags($text), -1)))\n                return $text;\n\n            \/\/ Now we start counting\n            $text_bits = preg_split('\/([\\s]+)\/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);\n            $in_tag = false;\n            $n_words = 0;\n            $text = '';\n\n            foreach($text_bits as $chunk) {\n\n                \/\/ Determine whether a tag is opened (and not immediately closed) in this chunk\n                if(0 &lt; preg_match('\/&lt;[^&gt;]*$\/s', $chunk))\n                    $in_tag = true;\n                elseif(0 &lt; preg_match('\/&gt;[^&lt;]*$\/s', $chunk))\n                    $in_tag = false;\n\n                \/\/ Is there a word?\n                if(!$in_tag &amp;#38;&amp; '' != trim($chunk) &amp;&amp; substr($chunk, -1, 1) != '&gt;')\n                    $n_words++;\n\n                $text .= $chunk;\n\n                if($n_words &gt;= $length &amp;&amp; !$in_tag)\n                    break;\n            }\n\n            $text = $text . $ellipsis;\n\n        } else {\n\n            \/\/ Count characters, not whitespace, not those belonging to HTML tags\n            if($length &gt; strlen(strip_tags($text)))\n                return $text;\n\n            $n_chars = 0;\n\n            for($i = 0; $n_chars &lt; $length || $in_tag; $i++) {\n\n                \/\/ Is the character worth counting (ie. not part of an HTML tag)\n                if(substr($text, $i, 1) == '&lt;')\n                    $in_tag = true;\n                elseif(substr($text, $i, 1) == '&gt;')\n                    $in_tag = false;\n                elseif(!$in_tag &amp;&amp; '' != trim(substr($text, $i, 1)))\n                    $n_chars++;\n            }\n\n            $text = substr($text, 0, $i) . $ellipsis;\n\n        }\n\n        $text = force_balance_tags($text);\n\n    } else {\n        $text = 'SORRY, THE {advexcerpt} FUNCTION DOESN\\'T EXIST';\n    }\n\n    return $text;\n}<\/code><\/pre>\n<p>This is also a good example of how powerful the Library is; I ended up brute-forcing the addition of the Advanced Excerpt plugin, which means I practically copied over the entire function into the library, and not &#8220;tap into&#8221; the existing plugin. This is because the way the [Advanced Excerpt] plugin was done; you can&#8217;t really &#8220;tap into&#8221; it because of how it was written.<\/p>\n<p>Now if the (Advanced Excerpt) plugin had an auxiliary function like <code>get_advExcerptByID(POST_ID)<\/code> &#8211; which it <strong>doesn&#8217;t,<\/strong> all that convoluted code above would&#8217;ve just been replaced with something simpler like:<\/p>\n<pre><code>function otf_advexcerpt($option_key, $result, $ext) {\n    if(function_exists('get_advExcerptByID')) {\n        return get_advExcerptByID($result-&gt;ID);\n    } else {\n        return \"SORRY, THE {advexcerpt} FUNCTION DOESN'T EXIST\";\n    }\n}<\/code><\/pre>\n<h1>Same day, different year<\/h1>\n<p>This is a cute feature I had from the old site &#8211; as it was an avenue of constantly exposing old entries&#8230; this in turn kept those entries from getting stale (i.e. forgotten without a trace). While it was not a priority to &#8220;revive,&#8221; I have to thank <a href=\"http:\/\/riaosorio.com\">Ria<\/a> for inspiring me to get it to work again. I&#8217;m sharing the &#8220;hack&#8221; I did.<\/p>\n<p>There are two plug-ins I know of that do this, however given the amount of information I need available for each post, hacking those proved to be complicated. <\/p>\n<p>From my discussions above, we already know how using <a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Rob Marsh&#8217;s<\/a> plugin approach\/architecture is as far as supplying and extending metadata &#8211; so I decided to take one of his post plugins and create a new one out of it. <\/p>\n<p>I chose the simplest; which was the <em>Random Posts Plugin.<\/em> It had all the customizability as far as the output string <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_6');\" onkeypress=\"footnote_moveToReference_909_1('footnote_plugin_reference_909_1_6');\" ><sup id=\"footnote_plugin_tooltip_909_1_6\" class=\"footnote_plugin_tooltip_text\">6 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_909_1_6\" class=\"footnote_tooltip\">which is what you see in HTML<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_909_1_6').tooltip({ tip: '#footnote_plugin_tooltip_text_909_1_6', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> is concerned, and given the nature of the plugin, it already had access to the database values we&#8217;ll be needing&#8230; it was just a matter of &#8220;crafting&#8221; the plug-in&#8217;s database query to suit our needs.<\/p>\n<p>First thing I did was do an <em>en masse<\/em> search and replace for the keywords that identify the plugin &#8211; this is so the plugin would register as an entirely new one; thus avoiding the possibility of conflicting with his other plugin processes. I replaced all instances of <code>Random<\/code> to <code>SameDay<\/code>&#8230; hence the plugin now registers as the &#8220;SameDay&#8221; plug-in.<\/p>\n<p>After testing if it was still working (at this point, it still funcitoned as a random post generator), I now proceeded to do these minor modifications:<\/p>\n<p>On the <code>execute()<\/code> function in the <code>SameDayPosts<\/code> class, simply add <code>$post<\/code> along with the other global variable declarations. What this does is make the values\/data in <code>$post<\/code> available to the execute function&#8217;s scope.<\/p>\n<p>Next, add the following code <strong>above<\/strong> line that says: <code>$sql .= \"WHERE \".implode(' AND ', $where);<\/code><\/p>\n<pre><code>$curr_month = date(\"n\", strtotime($post-&gt;post_date));\n$curr_day = date(\"j\", strtotime($post-&gt;post_date));\n$where[] = \"DATE_FORMAT($wpdb-&gt;posts.post_date, '%c') = {$curr_month}\";\n$where[] = \"DATE_FORMAT($wpdb-&gt;posts.post_date, '%e') = {$curr_day}\";<\/code><\/pre>\n<p>This adds conditions on the query while still using <a href=\"http:\/\/rmarsh.com\" title=\"Rob Marsh\">Mr. Marsh&#8217;s<\/a> implode approach at the end (just so everything is tidy)<\/p>\n<p>Then you may optionally adjust the line that says: <code>$sql .= \" ORDER BY RAND() LIMIT $limit\";<\/code> By default, it randomizes the resulting posts. In my case I changed <code>RAND()<\/code> to <code>#wpdb-&gt;posts.post_date DESC<\/code> to have it sort by descending post date.<\/p>\n<p>That&#8217;s all there is to it!<\/p><div class=\"speaker-mute footnotes_reference_container\"> <div class=\"footnote_container_prepare\"><p><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_label pointer\" onclick=\"footnote_expand_collapse_reference_container_909_1();\">Notes<\/span><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_collapse_button\" style=\"display: none;\" onclick=\"footnote_expand_collapse_reference_container_909_1();\">[<a id=\"footnote_reference_container_collapse_button_909_1\">+<\/a>]<\/span><\/p><\/div> <div id=\"footnote_references_container_909_1\" style=\"\"><table class=\"footnotes_table footnote-reference-container\"><caption class=\"accessibility\">Notes<\/caption> <tbody> \r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_1');\"><a id=\"footnote_plugin_reference_909_1_1\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>1<\/a><\/th> <td class=\"footnote_plugin_text\">How &#8220;snobbishly self-contained they tend to perform, etc.<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_2');\"><a id=\"footnote_plugin_reference_909_1_2\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>2<\/a><\/th> <td class=\"footnote_plugin_text\">Assuming you&#8217;re not reading this through an RSS reader<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_3');\"><a id=\"footnote_plugin_reference_909_1_3\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>3<\/a><\/th> <td class=\"footnote_plugin_text\">Which I&#8217;ll get to in a minute<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_4');\"><a id=\"footnote_plugin_reference_909_1_4\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>4<\/a><\/th> <td class=\"footnote_plugin_text\">I just had to mention that since I studied in a Loyola school as well<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_5');\"><a id=\"footnote_plugin_reference_909_1_5\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>5<\/a><\/th> <td class=\"footnote_plugin_text\">And yes, those ARE table elements, I don&#8217;t give a shit if they&#8217;re deprecated<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_909_1('footnote_plugin_tooltip_909_1_6');\"><a id=\"footnote_plugin_reference_909_1_6\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>6<\/a><\/th> <td class=\"footnote_plugin_text\">which is what you see in HTML<\/td><\/tr>\r\n\r\n <\/tbody> <\/table> <\/div><\/div><script type=\"text\/javascript\"> function footnote_expand_reference_container_909_1() { jQuery('#footnote_references_container_909_1').show(); jQuery('#footnote_reference_container_collapse_button_909_1').text('\u2212'); } function footnote_collapse_reference_container_909_1() { jQuery('#footnote_references_container_909_1').hide(); jQuery('#footnote_reference_container_collapse_button_909_1').text('+'); } function footnote_expand_collapse_reference_container_909_1() { if (jQuery('#footnote_references_container_909_1').is(':hidden')) { footnote_expand_reference_container_909_1(); } else { footnote_collapse_reference_container_909_1(); } } function footnote_moveToReference_909_1(p_str_TargetID) { footnote_expand_reference_container_909_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } } function footnote_moveToAnchor_909_1(p_str_TargetID) { footnote_expand_reference_container_909_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } }<\/script>","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been meaning to post this ever since I transitioned to the new blog. I&#8217;ve already explained in another post the frustrations I have with regards to the approach of WordPress plugins 1 How &#8220;snobbishly self-contained they tend to perform, etc. This post however is to assert that despite all these &#8220;limitations&#8221; there is one &hellip; <p class=\"link-more\"><a href=\"http:\/\/nargalzius.com\/blog\/archives\/2008\/12\/17\/wordpress-plug-in-hacks\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;WordPress plug-in hacks&#8221;<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[9,13],"tags":[163,791,805,810,811,911,933,1303],"class_list":["post-909","post","type-post","status-publish","format-standard","hentry","category-nargalzius","category-technology","tag-blog","tag-movabletype","tag-mysql","tag-nargalzius","tag-nargalziuscom","tag-php","tag-plugins","tag-wordpress"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/comments?post=909"}],"version-history":[{"count":1,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/909\/revisions"}],"predecessor-version":[{"id":1733,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/909\/revisions\/1733"}],"wp:attachment":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/media?parent=909"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/categories?post=909"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/tags?post=909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}