Yet Another Related Posts Plugin (YARPP) - Version 1.1

Version Description

Download this release

Release Info

Developer mitchoyoshitaka
Plugin Icon 128x128 Yet Another Related Posts Plugin (YARPP)
Version 1.1
Comparing to
See all releases

Code changes from version 1.0.1 to 1.1

Files changed (2) hide show
  1. readme.txt +24 -9
  2. yarpp.php +64 -15
readme.txt CHANGED
@@ -4,10 +4,10 @@ Author: mitcho (Michael Yoshitaka Erlewine)
4
  Author URI: http://mitcho.com/
5
  Plugin URI: http://mitcho.com/code/
6
  Donate link: http://mitcho.com/code/
7
- Tags: related, posts, post
8
- Requires at least: 2.0
9
  Tested up to: 2.3.2
10
- Stable tag: 1.0.1
11
 
12
  Returns a list of the related entries based on keyword matches, limited by a certain relatedness threshold. Like the tried and true Related Posts plugins�just better!
13
 
@@ -16,12 +16,13 @@ Returns a list of the related entries based on keyword matches, limited by a cer
16
  Yet Another Related Posts Plugin (YARPP) is the result of some tinkering with [Peter Bowyer's version](http://peter.mapledesign.co.uk/weblog/archives/wordpress-related-posts-plugin) of [Alexander Malov & Mike Lu's Related Entries plugin](http://wasabi.pbwiki.com/Related%20Entries). Modifications made include:
17
 
18
  1. *Limiting by a threshold*: Peter Bowyer did the great work of making the algorithm use MySQL's [fulltext search](dev.mysql.com/doc/en/Fulltext_Search.html) score to identify related posts. But it currently just displayed, for example, the top 5 most "relevant" entries, even if some of them weren't at all similar. Now you can set a threshold limit for relevance, and you get more related posts if there are more related posts and less if there are less. Ha!
19
- 2. *Being a better plugin citizen*: now it doesn't require the user to click some sketchy button to `alter` the database and enable a `fulltext key`. Using [`register_activation_hook`](http://codex.wordpress.org/Function_Reference/register_activation_hook), it does it automagically on plugin activation. Just install and go!
20
- 3. *Miscellany*: a nicer options screen, displaying the fulltext match score on output for admins, an option to allow related posts from the future, a couple bug fixes, etc.
 
21
 
22
  == Installation ==
23
 
24
- Just put it in your `/wp-content/plugins/` directory, activate, and then drop the `related_posts` function in your [WP loop](http://codex.wordpress.org/The_Loop). Change any options in the Related Posts (YARPP) Options pane in Admin > Plugins.
25
 
26
  You can override any options in an individual instance of `related_posts` using the following syntax:
27
 
@@ -31,7 +32,15 @@ Most of these should be self-explanatory. They're also in the same order as the
31
 
32
  Example: `related_posts(10, null, 'title: ')` changes the maximum related posts number to 10, keeps the default threshold from the Options pane, and adds `title:` to the beginning of every title.
33
 
34
- There's also a `related_posts_exist()` function. It has three optional arguments to override the defaults: a threshold, the past only boolean, and the show password-protected posts boolean.
 
 
 
 
 
 
 
 
35
 
36
  == Examples ==
37
 
@@ -49,11 +58,17 @@ On my own blog I use the following code with `<li>` and `</li>` as the before/af
49
  >`<p>No related posts.</p>`
50
  >`<?php endif; ?>`
51
 
 
 
52
  == Coming soon (probably) ==
53
 
54
  1. Incorporation of tags and categories in the algorithm. I've gotten the code working, but I still need to think about what the most natural algorithm would be for weighing these factors against the mysql fulltext score currently used (and works pretty well, I must say).
55
- 2. Um, something else! Let me know if you have any suggestions for improvement. ^^
 
56
 
57
  == Version log ==
58
  1.0 Initial upload
59
- 1.0.1 Bugfix: 1.0 assumed you had Markdown installed
 
 
 
4
  Author URI: http://mitcho.com/
5
  Plugin URI: http://mitcho.com/code/
6
  Donate link: http://mitcho.com/code/
7
+ Tags: related, posts, post, pages, page
8
+ Requires at least: 2.1
9
  Tested up to: 2.3.2
10
+ Stable tag: 1.1
11
 
12
  Returns a list of the related entries based on keyword matches, limited by a certain relatedness threshold. Like the tried and true Related Posts plugins�just better!
13
 
16
  Yet Another Related Posts Plugin (YARPP) is the result of some tinkering with [Peter Bowyer's version](http://peter.mapledesign.co.uk/weblog/archives/wordpress-related-posts-plugin) of [Alexander Malov & Mike Lu's Related Entries plugin](http://wasabi.pbwiki.com/Related%20Entries). Modifications made include:
17
 
18
  1. *Limiting by a threshold*: Peter Bowyer did the great work of making the algorithm use MySQL's [fulltext search](dev.mysql.com/doc/en/Fulltext_Search.html) score to identify related posts. But it currently just displayed, for example, the top 5 most "relevant" entries, even if some of them weren't at all similar. Now you can set a threshold limit for relevance, and you get more related posts if there are more related posts and less if there are less. Ha!
19
+ 2. *Related posts and pages*: **New in 1.1!** Puts you in control of pulling up related posts, pages, or both.
20
+ 3. *Being a better plugin citizen*: now it doesn't require the user to click some sketchy button to `alter` the database and enable a `fulltext key`. Using [`register_activation_hook`](http://codex.wordpress.org/Function_Reference/register_activation_hook), it does it automagically on plugin activation. Just install and go!
21
+ 4. *Miscellany*: a nicer options screen, displaying the fulltext match score on output for admins, an option to allow related posts from the future, a couple bug fixes, etc.
22
 
23
  == Installation ==
24
 
25
+ Just put it in your `/wp-content/plugins/` directory, activate, and then drop the `related_posts()` function in your [WP loop](http://codex.wordpress.org/The_Loop). Change any options in the Related Posts (YARPP) Options pane in Admin > Plugins. See Examples in Other Notes for sample code you can drop into your theme.
26
 
27
  You can override any options in an individual instance of `related_posts` using the following syntax:
28
 
32
 
33
  Example: `related_posts(10, null, 'title: ')` changes the maximum related posts number to 10, keeps the default threshold from the Options pane, and adds `title:` to the beginning of every title.
34
 
35
+ There's also a `related_posts_exist()` function. It has three optional arguments to override the defaults: a threshold, the show password-protected posts boolean, and the past only boolean.
36
+
37
+ == Related pages ==
38
+
39
+ YARPP 1.1 introduces related pages through the `related_pages()` function. `related_pages()` optionally may take the same arguments that `related_posts()` does.
40
+
41
+ By default, `related_posts()` gives you back posts only, `related_pages()` gives you pages, and there's also a new `related_entries()` which gives you posts and pages. When the "cross-relate posts and pages" option is checked in the YARPP options panel, `related_posts()`, `related_pages()`, and `related_entries()` will give you exactly the same output.
42
+
43
+ There are also, as you may expect, new `related_pages_exist()` and `related_entries_exist()` functions.
44
 
45
  == Examples ==
46
 
58
  >`<p>No related posts.</p>`
59
  >`<?php endif; ?>`
60
 
61
+ Of course, if you change all the instances of `posts` above to `pages`, you'll get a related pages listing.
62
+
63
  == Coming soon (probably) ==
64
 
65
  1. Incorporation of tags and categories in the algorithm. I've gotten the code working, but I still need to think about what the most natural algorithm would be for weighing these factors against the mysql fulltext score currently used (and works pretty well, I must say).
66
+ 2.
67
+ 3. Um, something else! Let me know if you have any suggestions for improvement. ^^
68
 
69
  == Version log ==
70
  1.0 Initial upload
71
+
72
+ 1.0.1 Bugfix: 1.0 assumed you had Markdown installed
73
+
74
+ 1.1 Related pages support! Also, uses `apply_filters` to apply whatever content text transformation you use (Wikipedia link, Markdown, etc.) before computing similarity.
yarpp.php CHANGED
@@ -3,13 +3,13 @@
3
  Plugin Name: Yet Another Related Posts Plugin
4
  Plugin URI: http://mitcho.com/code
5
  Description: Returns a list of the related entries based on keyword matches, limited by a certain relatedness threshold. Like the tried and true Related Posts plugins—just better!
6
- Version: 1.0.1
7
  Author: Alexander Malov, Mike Lu, Peter Bowyer, mitcho (Michael Erlewine)
8
  */
9
 
10
  // Begin setup
11
 
12
- $yarpp_version = "1.0.1";
13
 
14
  function yarpp_enabled() {
15
  global $wpdb;
@@ -22,6 +22,7 @@ function yarpp_enabled() {
22
 
23
  function yarpp_activate() {
24
  global $wpdb;
 
25
  add_option('threshold',5);
26
  add_option('limit',5);
27
  add_option('lim',10);
@@ -65,7 +66,7 @@ function current_post_keywords($num_to_ret = 20) {
65
  // weighting, changing this may give you better results
66
  $string = str_repeat($post->post_title, $w['title'].' ').
67
  str_repeat(str_replace('-', ' ', $post->post_name).' ', $w['name']).
68
- str_repeat(strip_tags((defined(MARKDOWN_WP_POSTS)) ? Markdown($post->post_content) : $post->post_content), $w['content'].' ');//mitcho: strip_tags
69
 
70
  // Cat names don't help with the current query: the category names of other
71
  // posts aren't retrieved by the query to be matched against (and can't be
@@ -99,13 +100,46 @@ function current_post_keywords($num_to_ret = 20) {
99
 
100
  }
101
 
 
 
102
  function related_posts() {
103
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  global $wpdb, $post, $user_level;
105
  get_currentuserinfo();
106
 
 
 
 
107
  // Get option values from the options page--this can be overwritten: see readme
108
- $args = func_get_args();
109
  $options = array('limit','threshold','before_title','after_title','show_excerpt','len','before_post','after_post','show_pass_post','past_only','show_score');
110
  $optvals = array();
111
  foreach (array_keys($options) as $index) {
@@ -130,7 +164,8 @@ function related_posts() {
130
  . "MATCH (post_name, post_content) "
131
  . "AGAINST ('$terms') AS score "
132
  . "FROM $wpdb->posts WHERE "
133
- . "MATCH (post_name, post_content) AGAINST ('$terms') >= $threshold "
 
134
  . "AND (post_status IN ( 'publish', 'static' ) && ID != '$post->ID') ";
135
  if (past_only) { $sql .= "AND post_date <= '$now' "; }
136
  if ($show_pass_post=='false') { $sql .= "AND post_password ='' "; }
@@ -157,12 +192,22 @@ function related_posts() {
157
  }
158
  }
159
 
160
- function related_posts_exist($threshold = 0,$past_only = 2,$show_pass_post = 2) {
161
  global $wpdb, $post;
162
 
163
- if ($threshold == 0) $threshold = get_option('threshold');
164
- if ($past_only == 2) $past_only = get_option('past_only');
165
- if ($show_pass_post == 2) $past_only = get_option('show_pass_post');
 
 
 
 
 
 
 
 
 
 
166
  $terms = current_post_keywords();
167
 
168
  $time_difference = get_settings('gmt_offset');
@@ -170,10 +215,12 @@ function related_posts_exist($threshold = 0,$past_only = 2,$show_pass_post = 2)
170
 
171
  $sql = "SELECT COUNT(*) as count "
172
  . "FROM $wpdb->posts WHERE "
173
- . "MATCH (post_name, post_content) AGAINST ('$terms') >= $threshold "
 
174
  . "AND (post_status IN ( 'publish', 'static' ) && ID != '$post->ID') ";
175
  if (past_only) { $sql .= "AND post_date <= '$now' "; }
176
  if ($show_pass_post=='false') { $sql .= "AND post_password ='' "; }
 
177
  $result = $wpdb->get_var($sql);
178
  return $result > 0 ? true: false;
179
  }
@@ -195,7 +242,7 @@ function yarpp_subpanel() {
195
  foreach ($valueoptions as $option) {
196
  update_option($option,$_POST[$option]);
197
  }
198
- $checkoptions = array('past_only','show_score','show_excerpt','show_pass_post');
199
  foreach ($checkoptions as $option) {
200
  (isset($_POST[$option])) ? update_option($option,true) : update_option($option,false);
201
  }
@@ -220,21 +267,24 @@ function yarpp_subpanel() {
220
  if (get_option('threshold') == '') update_option('threshold',5);
221
  if (get_option('length') == '') update_option('length',5);
222
  if (get_option('len') == '') update_option('len',10);
 
223
  ?>
224
 
225
  <div class="wrap">
226
  <h2>Yet Another Related Posts Plugin Options <small><?php echo $yarpp_version; ?></small></h2>
227
- <p><small>by <a href="http://mitcho.com/code/">mitcho (Michael 芳貴 Erlewine)</a> and based on the fabulous work of <a href="http://peter.mapledesign.co.uk/weblog/archives/wordpress-related-posts-plugin">Peter Bower</a>, <a href="http://wasabi.pbwiki.com/Related%20Entries">Alexander Malov & Mike Lu</a>.</small></p>
228
  <form method="post">
229
  <fieldset class="options">
230
  <h3>"Relatedness" options</h3>
231
  <p>YARPP is different than the <a href="http://wasabi.pbwiki.com/Related%20Entries">previous plugins it is based on</a> as it limits the related posts list by (1) a maximum number and (2) a <em>match threshold</em>. <a href="#" onclick="javascript:document.getElementById('yarpp_match_explanation').style.display = 'inline';this.style.display='none'" id="yarpp_match_explanation_trigger">Tell me more.</a></p>
232
 
233
- <p id="yarpp_match_explanation" style="display:none;">The higher the match threshold, the more restrictive, and you get less related posts overall. By default, the match threshold is 5. If you want to find an appropriate match score, I recommend you turn on the "show admins the match scores" setting below. That way, you can see what kinds of related posts are being picked up and with what kind of match scores, and determine an apprpriate threshold for your site. <a href="#" onclick="javascript:document.getElementById('yarpp_match_explanation_trigger').style.display = 'inline';this.parentNode.style.display='none'" id="yarpp_match_explanation_trigger">Tell me less now.</a></p>
234
 
235
  <table>
236
  <?php textbox('limit','Maximum number of related posts:')?>
237
  <?php textbox('threshold','Match threshold:')?>
 
 
238
  </table>
239
  <h3>Display options</h3>
240
  <table>
@@ -257,7 +307,6 @@ function yarpp_subpanel() {
257
  <?php checkbox('show_past_post',"Show password protected posts?"); ?>
258
  <?php checkbox('past_only',"Show only previous posts?"); ?>
259
  <?php checkbox('show_score',"Show admins (user level > 8) the match scores?"); ?>
260
-
261
  </table>
262
  </fieldset>
263
 
3
  Plugin Name: Yet Another Related Posts Plugin
4
  Plugin URI: http://mitcho.com/code
5
  Description: Returns a list of the related entries based on keyword matches, limited by a certain relatedness threshold. Like the tried and true Related Posts plugins—just better!
6
+ Version: 1.1
7
  Author: Alexander Malov, Mike Lu, Peter Bowyer, mitcho (Michael Erlewine)
8
  */
9
 
10
  // Begin setup
11
 
12
+ $yarpp_version = "1.1";
13
 
14
  function yarpp_enabled() {
15
  global $wpdb;
22
 
23
  function yarpp_activate() {
24
  global $wpdb;
25
+ add_option('cross_relate',false);
26
  add_option('threshold',5);
27
  add_option('limit',5);
28
  add_option('lim',10);
66
  // weighting, changing this may give you better results
67
  $string = str_repeat($post->post_title, $w['title'].' ').
68
  str_repeat(str_replace('-', ' ', $post->post_name).' ', $w['name']).
69
+ str_repeat(strip_tags(apply_filters('the_content',$post->post_content)), $w['content'].' ');//mitcho: strip_tags
70
 
71
  // Cat names don't help with the current query: the category names of other
72
  // posts aren't retrieved by the query to be matched against (and can't be
100
 
101
  }
102
 
103
+ // Here are the related_WHATEVER functions, as introduced in 1.1, which actually just use the yarpp_related and yarpp_related_exist functions.
104
+
105
  function related_posts() {
106
+ $a = func_get_args();
107
+ return yarpp_related(array('post'),$a);
108
+ }
109
+
110
+ function related_pages() {
111
+ $a = func_get_args();
112
+ return yarpp_related(array('page'),$a);
113
+ }
114
+
115
+ function related_entries() {
116
+ $a = func_get_args();
117
+ return yarpp_related(array('page','post'),$a);
118
+ }
119
+
120
+ function related_posts_exist() {
121
+ $a = func_get_args();
122
+ return yarpp_related_exist(array('post'),$a);
123
+ }
124
+
125
+ function related_pages_exist() {
126
+ $a = func_get_args();
127
+ return yarpp_related_exist(array('page'),$a);
128
+ }
129
+
130
+ function related_entries_exist() {
131
+ $a = func_get_args();
132
+ return yarpp_related_exist(array('page','post'),$a);
133
+ }
134
+
135
+ function yarpp_related($type,$args) {
136
  global $wpdb, $post, $user_level;
137
  get_currentuserinfo();
138
 
139
+ // if cross_relate is set, override the type argument and make sure both matches are accepted in the sql query
140
+ if (get_option('cross_relate')) $type = array('post','page');
141
+
142
  // Get option values from the options page--this can be overwritten: see readme
 
143
  $options = array('limit','threshold','before_title','after_title','show_excerpt','len','before_post','after_post','show_pass_post','past_only','show_score');
144
  $optvals = array();
145
  foreach (array_keys($options) as $index) {
164
  . "MATCH (post_name, post_content) "
165
  . "AGAINST ('$terms') AS score "
166
  . "FROM $wpdb->posts WHERE "
167
+ . "post_type IN ('".implode("', '",$type)."') "
168
+ . "AND MATCH (post_name, post_content) AGAINST ('$terms') >= $threshold "
169
  . "AND (post_status IN ( 'publish', 'static' ) && ID != '$post->ID') ";
170
  if (past_only) { $sql .= "AND post_date <= '$now' "; }
171
  if ($show_pass_post=='false') { $sql .= "AND post_password ='' "; }
192
  }
193
  }
194
 
195
+ function yarpp_related_exist($type,$args) {
196
  global $wpdb, $post;
197
 
198
+ if (get_option('cross_relate')) $type = array('post','page');
199
+
200
+ $options = array('threshold','show_pass_post','past_only');
201
+ $optvals = array();
202
+ foreach (array_keys($options) as $index) {
203
+ if (isset($args[$index+1])) {
204
+ $optvals[$options[$index]] = stripslashes($args[$index+1]);
205
+ } else {
206
+ $optvals[$options[$index]] = stripslashes(get_option($options[$index]));
207
+ }
208
+ }
209
+ extract($optvals);
210
+
211
  $terms = current_post_keywords();
212
 
213
  $time_difference = get_settings('gmt_offset');
215
 
216
  $sql = "SELECT COUNT(*) as count "
217
  . "FROM $wpdb->posts WHERE "
218
+ . "post_type IN ('".implode("', '",$type)."') "
219
+ . "AND MATCH (post_name, post_content) AGAINST ('$terms') >= $threshold "
220
  . "AND (post_status IN ( 'publish', 'static' ) && ID != '$post->ID') ";
221
  if (past_only) { $sql .= "AND post_date <= '$now' "; }
222
  if ($show_pass_post=='false') { $sql .= "AND post_password ='' "; }
223
+
224
  $result = $wpdb->get_var($sql);
225
  return $result > 0 ? true: false;
226
  }
242
  foreach ($valueoptions as $option) {
243
  update_option($option,$_POST[$option]);
244
  }
245
+ $checkoptions = array('past_only','show_score','show_excerpt','show_pass_post','cross_relate');
246
  foreach ($checkoptions as $option) {
247
  (isset($_POST[$option])) ? update_option($option,true) : update_option($option,false);
248
  }
267
  if (get_option('threshold') == '') update_option('threshold',5);
268
  if (get_option('length') == '') update_option('length',5);
269
  if (get_option('len') == '') update_option('len',10);
270
+ if (get_option('cross_relate') == '') update_option('cross_relate',false);
271
  ?>
272
 
273
  <div class="wrap">
274
  <h2>Yet Another Related Posts Plugin Options <small><?php echo $yarpp_version; ?></small></h2>
275
+ <p><small>by <a href="http://mitcho.com/code/">mitcho (Michael 芳貴 Erlewine)</a> and based on the fabulous work of <a href="http://peter.mapledesign.co.uk/weblog/archives/wordpress-related-posts-plugin">Peter Bower</a>, <a href="http://wasabi.pbwiki.com/Related%20Entries">Alexander Malov & Mike Lu</a>. If you appreciate this plugin, please consider <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=mitcho%40mitcho%2ecom&item_name=mitcho%2ecom%2fcode%3a%20donate%20to%20Michael%20Yoshitaka%20Erlewine&no_shipping=0&no_note=1&tax=0&currency_code=USD&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8">donating to the author, mitcho</a>.</small></p>
276
  <form method="post">
277
  <fieldset class="options">
278
  <h3>"Relatedness" options</h3>
279
  <p>YARPP is different than the <a href="http://wasabi.pbwiki.com/Related%20Entries">previous plugins it is based on</a> as it limits the related posts list by (1) a maximum number and (2) a <em>match threshold</em>. <a href="#" onclick="javascript:document.getElementById('yarpp_match_explanation').style.display = 'inline';this.style.display='none'" id="yarpp_match_explanation_trigger">Tell me more.</a></p>
280
 
281
+ <p id="yarpp_match_explanation" style="display:none;">The higher the match threshold, the more restrictive, and you get less related posts overall. The default match threshold is 5. If you want to find an appropriate match threshhold, I recommend you turn on the "show admins the match scores" setting below. That way, you can see what kinds of related posts are being picked up and with what kind of match scores, and determine an appropriate threshold for your site. <a href="#" onclick="javascript:document.getElementById('yarpp_match_explanation_trigger').style.display = 'inline';this.parentNode.style.display='none'" id="yarpp_match_explanation_trigger">Tell me less now.</a></p>
282
 
283
  <table>
284
  <?php textbox('limit','Maximum number of related posts:')?>
285
  <?php textbox('threshold','Match threshold:')?>
286
+ <?php checkbox('cross_relate',"Cross-relate posts and pages? <a href='#' onclick=\"javascript:document.getElementById('yarpp_cross_relate_explanation').style.display = 'table-row';this.style.display='none'\" id='yarpp_cross_relate_explanation_trigger'>Tell me more.</a>"); ?>
287
+ <tr id="yarpp_cross_relate_explanation" style="display:none;"><td style='background-color: gray; width: 3px;'>&nbsp;</td><td colspan = '2'>When the "Cross-relate posts and pages" option is selected, the <code>related_posts()</code>, <code>related_pagaes()</code>, and <code>related_entries()</code> all will give the same output, returning both related pages and posts. <a href="#" onclick="javascript:document.getElementById('yarpp_cross_relate_explanation_trigger').style.display = 'inline';this.parentNode.parentNode.style.display='none'" id="yarpp_cross_relate_explanation_trigger">Tell me less now.</a></td></tr>
288
  </table>
289
  <h3>Display options</h3>
290
  <table>
307
  <?php checkbox('show_past_post',"Show password protected posts?"); ?>
308
  <?php checkbox('past_only',"Show only previous posts?"); ?>
309
  <?php checkbox('show_score',"Show admins (user level > 8) the match scores?"); ?>
 
310
  </table>
311
  </fieldset>
312