Changeset 45021
- Timestamp:
- 05/09/08 14:21:07 (2 months ago)
- Files:
-
- clean-archives-reloaded/trunk/clean-archives-reloaded.php (modified) (5 diffs)
- clean-archives-reloaded/trunk/readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
clean-archives-reloaded/trunk/clean-archives-reloaded.php
r33845 r45021 5 5 Plugin Name: Clean Archives Reloaded 6 6 Plugin URI: http://www.viper007bond.com/wordpress-plugins/clean-archives-reloaded/ 7 Description: A slick, Javascript-enhanced post archive list generator . Based on concepts and ideas by <a href="http://www.kingcosmonaut.de/">Sebastian Schmieg</a>, <a href="http://www.sporadicnonsense.com/">Shawn Grimes</a>, and <a href="http://cdcstudios.com/">Chris O'Rourke</a>.8 Version: 2.0.07 Description: A slick, Javascript-enhanced post archive list generator for WordPress 2.5+. 8 Version: 3.0.0 9 9 Author: Viper007Bond 10 10 Author URI: http://www.viper007bond.com/ 11 11 12 ************************************************************************** 13 14 Copyright (C) 2008 Viper007Bond 15 16 This program is free software: you can redistribute it and/or modify 17 it under the terms of the GNU General Public License as published by 18 the Free Software Foundation, either version 3 of the License, or 19 (at your option) any later version. 20 21 This program is distributed in the hope that it will be useful, 22 but WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 GNU General Public License for more details. 25 26 You should have received a copy of the GNU General Public License 27 along with this program. If not, see <http://www.gnu.org/licenses/>. 28 12 29 **************************************************************************/ 13 30 14 31 class CleanArchivesReloaded { 15 32 16 ########## SET OPTIONAL CONFIGURATION HERE ########## 17 18 # Enable/disable the Javascript features (expand/collapse) 19 var $usejs = TRUE; // default is TRUE 20 21 # TRUE for listing posts within individual months from newest to oldest, FALSE for oldest to newest 22 var $postnewtoold = FALSE; // default is FALSE 23 24 # TRUE for listing months from newest to oldest, FALSE for oldest to newest 25 var $monthnewtoold = TRUE; // default is TRUE 26 27 ########## OKAY, STOP EDITING HERE ########## 28 29 var $postcount = 0; 30 var $postdata = array(); 31 var $html; 33 # Configuration has been moved to the new options page at Settings -> Clean Archives. 34 # You can also set the configuration via the shortcode tag. 35 32 36 33 37 // Class initialization 34 38 function CleanArchivesReloaded() { 35 if ( TRUE == $this->usejs ) add_action( 'wp_head', array(&$this, 'wp_head') ); 36 add_filter( 'the_content', array(&$this, 'PlaceholderReplace'), 8 ); 37 38 wp_enqueue_script( 'jquery' ); 39 if ( !function_exists('add_shortcode') ) return; 39 40 40 41 // Load up the localization file if we're using WordPress in a different language 41 42 // Place it in this plugin's folder and name it "car-[value in wp-config].mo" 42 43 load_plugin_textdomain( 'car', '/wp-content/plugins/clean-archives-reloaded' ); 44 45 // Make sure all the plugin options have defaults set 46 if ( FALSE === get_option('car_usejs') ) add_option( 'car_usejs', 1 ); 47 if ( FALSE === get_option('car_monthorder') ) add_option( 'car_monthorder', 'new' ); 48 if ( FALSE === get_option('car_postorder') ) add_option( 'car_postorder', 'old' ); 49 50 // Register all the hooks 51 add_action( 'admin_menu', array(&$this, 'AddAdminMenu') ); 52 add_shortcode( 'cleanarchivesreloaded' , array(&$this, 'PostList') ); 53 add_shortcode( 'cartotalposts' , array(&$this, 'PostCount') ); 54 55 // Enqueue the Javascript and the little CSS to be outputted 56 add_action( 'wp_head', array(&$this, 'OutputCSSJavascript') ); 57 wp_enqueue_script( 'jquery' ); 58 59 // For users with a persistent object caching plugin installed, we need to dump the cache in some cases 60 add_action( 'save_post', array(&$this, 'DeleteCache') ); 61 add_action( 'edit_post', array(&$this, 'DeleteCache') ); 62 add_action( 'delete_post', array(&$this, 'DeleteCache') ); 63 } 64 65 66 // Register the admin menu 67 function AddAdminMenu() { 68 add_options_page( __('Clean Archives Reloaded', 'car'), __('Clean Archives', 'car'), 'manage_options', 'clean-archives-reloaded', array(&$this, 'OptionsPage') ); 69 } 70 71 72 // The options page for this plugin 73 function OptionsPage() { ?> 74 75 <div class="wrap"> 76 <h2><?php _e('Clean Archives Reloaded', 'car'); ?></h2> 77 78 <form method="post" action="options.php"> 79 <?php wp_nonce_field('update-options') ?> 80 81 <table class="form-table"> 82 <tr> 83 <th scope="row" colspan="2" class="th-full"> 84 <label for="car_usejs"> 85 <input name="car_usejs" type="checkbox" id="car_usejs" value="1" <?php checked('1', get_option('car_usejs')); ?> /> 86 <?php _e('Use Javascript to make the months collapsible', 'car'); ?> 87 </label> 88 </th> 89 </tr> 90 <tr valign="top"> 91 <th scope="row"><?php _e('Month Ordering', 'car'); ?></th> 92 <td> 93 <p> 94 <label><input name="car_monthorder" type="radio" value="new" <?php checked('new', get_option('car_monthorder')); ?> /> <?php _e('Show newest months first', 'car'); ?></label><br /> 95 <label><input name="car_monthorder" type="radio" value="old" <?php checked('old', get_option('car_monthorder')); ?> /> <?php _e('Show oldest months first', 'car'); ?></label> 96 </p> 97 </td> 98 </tr> 99 <tr valign="top"> 100 <th scope="row"><?php _e('Post Ordering', 'car'); ?></th> 101 <td> 102 <p><?php _e('Within individual months...', 'car'); ?></p> 103 <p> 104 <label><input name="car_postorder" type="radio" value="new" <?php checked('new', get_option('car_postorder')); ?> /> <?php _e('Show newest posts first', 'car'); ?></label><br /> 105 <label><input name="car_postorder" type="radio" value="old" <?php checked('old', get_option('car_postorder')); ?> /> <?php _e('Show oldest posts first', 'car'); ?></label> 106 </p> 107 </td> 108 </tr> 109 </table> 110 111 <p class="submit"> 112 <input type="submit" name="Submit" value="<?php _e('Save Changes') ?>" /> 113 <input type="hidden" name="action" value="update" /> 114 <input type="hidden" name="page_options" value="car_usejs,car_monthorder,car_postorder" /> 115 </p> 116 117 </form> 118 </div> 119 120 <?php 43 121 } 44 122 … … 46 124 // Output a little helper CSS and the Javascript for the plugin 47 125 // Based on code from http://www.learningjquery.com/2007/03/accordion-madness 48 function wp_head() { ?>49 50 <!-- Clean Archives Reloaded v 2.0.0-->51 <style type="text/css">.car- yearmonth { cursor: s-resize; } </style>126 function OutputCSSJavascript() { ?> 127 128 <!-- Clean Archives Reloaded v3.0.0 | http://www.viper007bond.com/wordpress-plugins/clean-archives-reloaded/ --> 129 <style type="text/css">.car-collapse .car-yearmonth { cursor: s-resize; } </style> 52 130 <script type="text/javascript"> 53 131 //<![CDATA[ 54 var allexpanded = false;55 56 132 jQuery(document).ready(function() { 57 jQuery(' ul.car-monthlisting').hide();58 jQuery(' ul.car-firstmonth').show();59 jQuery(' span.car-yearmonth').click(function() {133 jQuery('.car-collapse').children('ul').children('li').children('ul').hide(); 134 jQuery('.car-firstmonth').show(); 135 jQuery('.car-collapse').children('ul').children('li').children('.car-yearmonth').click(function() { 60 136 jQuery(this).next('ul').slideToggle('fast'); 61 137 }); 62 138 jQuery('.car-toggler').click(function() { 63 if ( false == allexpanded ) { 64 jQuery('ul.car-monthlisting').show(); 65 jQuery('.car-toggler').text('<?php echo js_escape( __('Collapse All', 'car') ); ?>'); 66 allexpanded = true; 139 if ( '<?php echo js_escape( __('Expand All', 'car') ); ?>' == jQuery(this).text() ) { 140 jQuery(this).parent('.car-container').children('ul').children('li').children('ul').show(); 141 jQuery(this).text('<?php echo js_escape( __('Collapse All', 'car') ); ?>'); 67 142 } 68 143 else { 69 jQuery('ul.car-monthlisting').hide(); 70 jQuery('.car-toggler').text('<?php echo js_escape( __('Expand All', 'car') ); ?>'); 71 allexpanded = false; 144 jQuery(this).parent('.car-container').children('ul').children('li').children('ul').hide(); 145 jQuery(this).text('<?php echo js_escape( __('Expand All', 'car') ); ?>'); 72 146 } 73 147 return false; … … 82 156 83 157 // Grab all posts and filter them into an array 84 function GenerateDataArray( $forceregen = FALSE ) { 85 if ( !empty($this->postdata) && FALSE == $forceregen ) return; 86 87 $posts = get_posts( 'numberposts=0' ); 88 89 $this->postcount = count( $posts ); 90 91 foreach( $posts as $post ) { 92 $this->postdata[ mysql2date( 'Y.m', $post->post_date ) ][ mysql2date( 'U', $post->post_date ) ] = $post; 158 function GetPosts() { 159 // If we have a cached copy of the filtered posts array, use that instead 160 if ( $posts = wp_cache_get( 'posts', 'clean-archives-reloaded' ) ) 161 return $posts; 162 163 // Get a simple array of all posts 164 $rawposts = get_posts( 'numberposts=0' ); 165 166 // Loop through each post and sort it into a structured array 167 foreach( $rawposts as $key => $post ) { 168 $posts[ mysql2date( 'Y.m', $post->post_date ) ][ mysql2date( 'U', $post->post_date ) ] = $post; 169 170 unset( $rawposts[$key] ); // Try and free up memory for users with lots of posts and poor server configs 93 171 } 94 95 // Ensure the post sorting is correct 96 foreach( $this->postdata as $key => $month ) { 97 ( TRUE != $this->postnewtoold ) ? ksort( $month ) : krsort( $month ); 98 $this->postdata[$key] = $month; 172 $rawposts = NULL; // More memory cleanup 173 174 // Store the results into the WordPress cache 175 wp_cache_set( 'posts', $posts, 'clean-archives-reloaded' ); 176 177 return $posts; 178 } 179 180 181 // Generates the HTML output based on $atts array from the shortcode 182 function PostList( $atts = array() ) { 183 global $wp_locale; 184 185 // Set any missing $atts items to the defaults 186 $atts = shortcode_atts(array( 187 'usejs' => get_option('car_usejs'), 188 'monthorder' => get_option('car_monthorder'), 189 'postorder' => get_option('car_postorder'), 190 ), $atts); 191 192 // Get the big array of all posts 193 $posts = $this->GetPosts(); 194 195 // Sort the posts based on $atts 196 foreach( $posts as $key => $month ) { 197 ( 'old' == $atts['postorder'] ) ? ksort( $month ) : krsort( $month ); 198 $posts[$key] = $month; 99 199 unset($month); 100 200 } 101 ( TRUE != $this->monthnewtoold ) ? ksort( $this->postdata ) : krsort( $this->postdata ); 102 } 103 104 105 // Generates the HTML output from the data array 106 function GenerateHTML( $forceregen = FALSE ) { 107 global $wp_locale; 108 109 if ( empty($this->postdata) || ( !empty($this->html) && FALSE == $forceregen ) ) return; 110 111 $this->html = ''; 112 113 if ( TRUE == $this->usejs ) $this->html .= '<a href="#" class="car-toggler">' . __('Expand All', 'car') . "</a>\n\n"; 114 115 $this->html .= '<ul class="car-list">' . "\n"; 201 ( 'old' == $atts['monthorder'] ) ? ksort( $posts ) : krsort( $posts ); 202 203 204 // Generate the HTML 205 $html = '<div class="car-container'; 206 if ( 1 == $atts['usejs'] ) $html .= ' car-collapse'; 207 $html .= '">'. "\n"; 208 209 if ( 1 == $atts['usejs'] ) $html .= '<a href="#" class="car-toggler">' . __('Expand All', 'car') . "</a>\n\n"; 210 211 $html .= '<ul class="car-list">' . "\n"; 116 212 117 213 $firstmonth = TRUE; 118 foreach( $ this->postdataas $yearmonth => $posts ) {214 foreach( $posts as $yearmonth => $posts ) { 119 215 list( $year, $month ) = explode( '.', $yearmonth ); 120 216 … … 122 218 foreach( $posts as $post ) { 123 219 if ( TRUE == $firstpost ) { 124 $ this->html .= ' <li><span class="car-yearmonth">' . sprintf( __('%1$s %2$d'), $wp_locale->get_month($month), $year ) . ' <span title="' . __('Post Count', 'car') . '">(' . count($posts) . ")</span></span>\n <ul class='car-monthlisting";220 $html .= ' <li><span class="car-yearmonth">' . sprintf( __('%1$s %2$d'), $wp_locale->get_month($month), $year ) . ' <span title="' . __('Post Count', 'car') . '">(' . count($posts) . ")</span></span>\n <ul class='car-monthlisting"; 125 221 if ( TRUE == $firstmonth ) { 126 $ this->html .= ' car-firstmonth';222 $html .= ' car-firstmonth'; 127 223 $firstmonth = FALSE; 128 224 } 129 $ this->html .= "'>\n";225 $html .= "'>\n"; 130 226 $firstpost = FALSE; 131 227 } 132 228 133 $ this->html .= ' <li>' . mysql2date( 'd', $post->post_date ) . ': <a href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>';229 $html .= ' <li>' . mysql2date( 'd', $post->post_date ) . ': <a href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>'; 134 230 135 231 // Unless comments are closed and there are no comments, show the comment count 136 if ( 0 != $post->comment_count || 'closed' != $post->comment_status ) $this->html .= ' <span title="' . __('Comment Count', 'car') . '">(' . $post->comment_count . ')</span>';137 138 $ this->html .= "</li>\n";232 if ( ( 0 != $post->comment_count || 'closed' != $post->comment_status ) && empty($post->post_password) ) $html .= ' <span title="' . __('Comment Count', 'car') . '">(' . $post->comment_count . ')</span>'; 233 234 $html .= "</li>\n"; 139 235 } 140 236 141 $ this->html .= " </ul>\n </li>\n";237 $html .= " </ul>\n </li>\n"; 142 238 } 143 239 144 $this->html .= "</ul>\n"; 145 } 146 147 148 function PlaceholderReplace( $content ) { 149 // Don't run if the placeholders aren't in this post 150 if ( FALSE === stristr( $content, '[cleanarchivesreloaded]' ) && FALSE === stristr( $content, '[cartotalposts]' ) ) return $content; 151 152 // Make sure we have data to use. These functions will automatically abort if they've already been run. 153 $this->GenerateDataArray(); 154 $this->GenerateHTML(); 155 156 // Find and replace our placeholders 157 $content = str_replace( '[cleanarchivesreloaded]', $this->html, $content ); 158 $content = str_replace( '[cartotalposts]', $this->postcount, $content ); 159 160 return $content; 240 $html .= "</ul>\n</div>\n"; 241 242 return $html; 243 } 244 245 246 // Returns the total number of posts 247 function PostCount() { 248 $num_posts = wp_count_posts( 'post' ); 249 return number_format_i18n( $num_posts->publish ); 250 } 251 252 253 // Deletes the cached filtered posts array for users using a persistent caching plugin 254 function DeleteCache() { 255 wp_cache_delete( 'posts', 'clean-archives-reloaded' ); 161 256 } 162 257 } … … 169 264 function car_total_posts() { 170 265 global $CleanArchivesReloaded; 171 $CleanArchivesReloaded->GenerateDataArray(); 172 $CleanArchivesReloaded->GenerateHTML(); 173 return $CleanArchivesReloaded->postcount; 266 return $CleanArchivesReloaded->PostCount(); 174 267 } 175 268 function clean_archives_reloaded() { 176 269 global $CleanArchivesReloaded; 177 $CleanArchivesReloaded->GenerateDataArray(); 178 $CleanArchivesReloaded->GenerateHTML(); 179 echo $CleanArchivesReloaded->html; 270 echo $CleanArchivesReloaded->PostList(); 180 271 } 181 272 function car_regenerate() { clean-archives-reloaded/trunk/readme.txt
r33848 r45021 3 3 Donate link: http://www.viper007bond.com/donate/ 4 4 Tags: archive, archives, posts 5 Requires at least: 2.0 6 Tested up to: 2.5 5 Requires at least: 2.5 7 6 Stable tag: trunk 8 7 … … 11 10 == Description == 12 11 13 **Clean Archives Reloaded**generates a list of all of your posts, sorted by month. It's enhanced with Javascript to allow collapsing and expanding of months.12 Clean Archives Reloaded generates a list of all of your posts, sorted by month. It's enhanced with Javascript to allow collapsing and expanding of months. 14 13 15 Based on concepts and ideas by [Sebastian Schmieg](http://www.kingcosmonaut.de/), [Shawn Grimes](http://www.sporadicnonsense.com/), and [Chris O'Rourke](http://cdcstudios.com/).14 It's highly efficient and won't kill your server with tons of MySQL queries. 16 15 17 16 = Demo = 18 17 19 18 Check out [my blog's archive page](http://www.viper007bond.com/archives/). 19 20 = Legacy Version = 21 22 The current version of this plugin is only compatible with WordPress 2.5 and newer. If for some reason you are running an older version of WordPress, you will need to use the <a href="http://downloads.wordpress.org/plugin/clean-archives-reloaded.2.0.0.zip">legacy version</a> of this plugin. But please, do yourself a favor and upgrade your version of WordPress! 20 23 21 24 == Installation == … … 51 54 [cleanarchivesreloaded]` 52 55 56 Configure options via Settings -> Clean Archives. 57 53 58 == Frequently Asked Questions == 54 59 … … 61 66 Sure! I do this in my free time and I appreciate all donations that I get. It makes me want to continue to update this plugin. You can find more details on [my donate page](http://www.viper007bond.com/donate/). 62 67 68 == Shortcode Tag Parameters == 69 70 You can customize the list options on a per-call basis if you wish. 71 72 * `usejs` -- (`1` or `0`) use Javascript or not to collapse the months 73 * `monthorder` -- (`new` or `old`) show newest months or oldest months first 74 * `postorder` -- (`new` or `old`) show newest posts or oldest posts first within months 75 76 = Examples = 77 78 No Javascript: 79 80 `[cleanarchivesreloaded usejs="0"]` 81 82 Oldest months first, oldest posts first: 83 84 `[cleanarchivesreloaded monthorder="old" postorder="old"]` 85 63 86 == ChangeLog == 87 88 **Version 3.0.0** 89 90 * Recoded (mostly) from scratch once again. Now requires WordPress 2.5+ as it uses the shortcode functions. 91 * Greatly increased efficiency. Page generation times dropped 10% on my localhost development blog. 92 * Options page -- no more editing the file to configure options. 93 * If you have multiple listings per page (no clue why you would, but hey), the Expand/Collapse All links will only apply to it's own listing rather than all listings on the page. 94 * You can override the individual options set on the options page via the shortcode tag (see above). 64 95 65 96 **Version 2.0.0**
