Changeset 45021

Show
Ignore:
Timestamp:
05/09/08 14:21:07 (2 months ago)
Author:
Viper007Bond
Message:

v3.0.0

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • clean-archives-reloaded/trunk/clean-archives-reloaded.php

    r33845 r45021  
    55Plugin Name:  Clean Archives Reloaded 
    66Plugin 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.0 
     7Description:  A slick, Javascript-enhanced post archive list generator for WordPress 2.5+
     8Version:      3.0.0 
    99Author:       Viper007Bond 
    1010Author URI:   http://www.viper007bond.com/ 
    1111 
     12************************************************************************** 
     13 
     14Copyright (C) 2008 Viper007Bond 
     15 
     16This program is free software: you can redistribute it and/or modify 
     17it under the terms of the GNU General Public License as published by 
     18the Free Software Foundation, either version 3 of the License, or 
     19(at your option) any later version. 
     20 
     21This program is distributed in the hope that it will be useful, 
     22but WITHOUT ANY WARRANTY; without even the implied warranty of 
     23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     24GNU General Public License for more details. 
     25 
     26You should have received a copy of the GNU General Public License 
     27along with this program.  If not, see <http://www.gnu.org/licenses/>. 
     28 
    1229**************************************************************************/ 
    1330 
    1431class CleanArchivesReloaded { 
    1532 
    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 
    3236 
    3337      // Class initialization 
    3438      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; 
    3940 
    4041            // Load up the localization file if we're using WordPress in a different language 
    4142            // Place it in this plugin's folder and name it "car-[value in wp-config].mo" 
    4243            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 
    43121      } 
    44122 
     
    46124      // Output a little helper CSS and the Javascript for the plugin 
    47125      // Based on code from http://www.learningjquery.com/2007/03/accordion-madness 
    48       function wp_head() { ?> 
    49  
    50       <!-- Clean Archives Reloaded v2.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> 
    52130      <script type="text/javascript"> 
    53131            //<![CDATA[ 
    54                   var allexpanded = false; 
    55  
    56132                  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() { 
    60136                              jQuery(this).next('ul').slideToggle('fast'); 
    61137                        }); 
    62138                        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') ); ?>'); 
    67142                              } 
    68143                              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') ); ?>'); 
    72146                              } 
    73147                              return false; 
     
    82156 
    83157      // 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 
    93171            } 
    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; 
    99199                  unset($month); 
    100200            } 
    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"; 
    116212 
    117213            $firstmonth = TRUE; 
    118             foreach( $this->postdata as $yearmonth => $posts ) { 
     214            foreach( $posts as $yearmonth => $posts ) { 
    119215                  list( $year, $month ) = explode( '.', $yearmonth ); 
    120216 
     
    122218                  foreach( $posts as $post ) { 
    123219                        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"; 
    125221                              if ( TRUE == $firstmonth ) { 
    126                                     $this->html .= ' car-firstmonth'; 
     222                                    $html .= ' car-firstmonth'; 
    127223                                    $firstmonth = FALSE; 
    128224                              } 
    129                               $this->html .= "'>\n"; 
     225                              $html .= "'>\n"; 
    130226                              $firstpost = FALSE; 
    131227                        } 
    132228 
    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>'; 
    134230 
    135231                        // 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"; 
    139235                  } 
    140236 
    141                   $this->html .= "            </ul>\n     </li>\n"; 
     237                  $html .= "            </ul>\n     </li>\n"; 
    142238            } 
    143239 
    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' ); 
    161256      } 
    162257} 
     
    169264function car_total_posts() { 
    170265      global $CleanArchivesReloaded; 
    171       $CleanArchivesReloaded->GenerateDataArray(); 
    172       $CleanArchivesReloaded->GenerateHTML(); 
    173       return $CleanArchivesReloaded->postcount; 
     266      return $CleanArchivesReloaded->PostCount(); 
    174267} 
    175268function clean_archives_reloaded() { 
    176269      global $CleanArchivesReloaded; 
    177       $CleanArchivesReloaded->GenerateDataArray(); 
    178       $CleanArchivesReloaded->GenerateHTML(); 
    179       echo $CleanArchivesReloaded->html; 
     270      echo $CleanArchivesReloaded->PostList(); 
    180271} 
    181272function car_regenerate() { 
  • clean-archives-reloaded/trunk/readme.txt

    r33848 r45021  
    33Donate link: http://www.viper007bond.com/donate/ 
    44Tags: archive, archives, posts 
    5 Requires at least: 2.0 
    6 Tested up to: 2.5 
     5Requires at least: 2.5 
    76Stable tag: trunk 
    87 
     
    1110== Description == 
    1211 
    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. 
     12Clean 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. 
    1413 
    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/)
     14It's highly efficient and won't kill your server with tons of MySQL queries
    1615 
    1716= Demo = 
    1817 
    1918Check out [my blog's archive page](http://www.viper007bond.com/archives/). 
     19 
     20= Legacy Version = 
     21 
     22The 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! 
    2023 
    2124== Installation == 
     
    5154[cleanarchivesreloaded]` 
    5255 
     56Configure options via Settings -> Clean Archives. 
     57 
    5358== Frequently Asked Questions == 
    5459 
     
    6166Sure! 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/). 
    6267 
     68== Shortcode Tag Parameters == 
     69 
     70You 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 
     78No Javascript: 
     79 
     80`[cleanarchivesreloaded usejs="0"]` 
     81 
     82Oldest months first, oldest posts first: 
     83 
     84`[cleanarchivesreloaded monthorder="old" postorder="old"]` 
     85 
    6386== 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). 
    6495 
    6596**Version 2.0.0**