| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: Category Posts Widget |
| 4 |
Plugin URI: http://jameslao.com/ |
| 5 |
Description: Adds a widget that can display a specified number of posts from a single category. Can also set how many widgets to show. |
| 6 |
Author: James Lao |
| 7 |
Version: 1.3 |
| 8 |
Author URI: http://jameslao.com/ |
| 9 |
*/ |
| 10 |
|
| 11 |
// Displays widget on blag |
| 12 |
// $widget_args: number |
| 13 |
// number: which of the several widgets of this type do we mean |
| 14 |
function jl_cat_posts_widget( $args, $widget_args = 1 ) { |
| 15 |
extract( $args, EXTR_SKIP ); |
| 16 |
if ( is_numeric($widget_args) ) |
| 17 |
$widget_args = array( 'number' => $widget_args ); |
| 18 |
$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); |
| 19 |
extract( $widget_args, EXTR_SKIP ); |
| 20 |
|
| 21 |
// Data should be stored as array: array( number => data for that instance of the widget, ... ) |
| 22 |
$options = get_option('widget_cat_posts'); |
| 23 |
if ( !isset($options[$number]) ) |
| 24 |
return; |
| 25 |
|
| 26 |
$cat_id = empty($options[$number]['cat']) ? 1 : $options[$number]['cat']; |
| 27 |
$title_link = (bool) $options[$number]['title_link']; |
| 28 |
$excerpt = (bool) $options[$number]['excerpt']; |
| 29 |
$num = $options[$number]['num']; // Number of posts to show. |
| 30 |
|
| 31 |
// If not title, use the name of the category. |
| 32 |
if( empty($options[$number]['title']) ) { |
| 33 |
$category_info = get_category($cat_id); |
| 34 |
$title = $category_info->name; |
| 35 |
} else { |
| 36 |
$title = $options[$number]['title']; |
| 37 |
} |
| 38 |
|
| 39 |
// Get array of post info. |
| 40 |
$cat_posts = get_posts('numberposts='.$num.'&category='.$cat_id); |
| 41 |
|
| 42 |
echo $before_widget; |
| 43 |
echo $before_title; |
| 44 |
|
| 45 |
if( $title_link ) { |
| 46 |
echo '<a href="' . get_category_link($cat_id) . '">' . $title . '</a>'; |
| 47 |
} else { |
| 48 |
echo $title; |
| 49 |
} |
| 50 |
|
| 51 |
echo $after_title; |
| 52 |
echo '<ul>'; |
| 53 |
foreach($cat_posts as $post) { |
| 54 |
setup_postdata($post); |
| 55 |
echo '<li class="cat-posts-item-' . $post->ID . '"><a href="' . get_permalink($post) . '">' . $post->post_title . '</a>'; |
| 56 |
if( $excerpt ) { |
| 57 |
echo '<br />'; |
| 58 |
the_excerpt(); |
| 59 |
} |
| 60 |
echo '</li>'; |
| 61 |
} |
| 62 |
echo '</ul>'; |
| 63 |
echo $after_widget; |
| 64 |
} |
| 65 |
|
| 66 |
// Displays form for a particular instance of the widget. Also updates the data after a POST submit |
| 67 |
// $widget_args: number |
| 68 |
// number: which of the several widgets of this type do we mean |
| 69 |
function jl_cat_posts_control( $widget_args = 1 ) { |
| 70 |
global $wp_registered_widgets; |
| 71 |
static $updated = false; // Whether or not we have already updated the data after a POST submit |
| 72 |
|
| 73 |
if ( is_numeric($widget_args) ) |
| 74 |
$widget_args = array( 'number' => $widget_args ); |
| 75 |
$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); |
| 76 |
extract( $widget_args, EXTR_SKIP ); |
| 77 |
|
| 78 |
// Data should be stored as array: array( number => data for that instance of the widget, ... ) |
| 79 |
$options = get_option('widget_cat_posts'); |
| 80 |
if ( !is_array($options) ) |
| 81 |
$options = array(); |
| 82 |
|
| 83 |
// We need to update the data |
| 84 |
if ( !$updated && !empty($_POST['sidebar']) ) { |
| 85 |
// Tells us what sidebar to put the data in |
| 86 |
$sidebar = (string) $_POST['sidebar']; |
| 87 |
|
| 88 |
$sidebars_widgets = wp_get_sidebars_widgets(); |
| 89 |
if ( isset($sidebars_widgets[$sidebar]) ) |
| 90 |
$this_sidebar =& $sidebars_widgets[$sidebar]; |
| 91 |
else |
| 92 |
$this_sidebar = array(); |
| 93 |
|
| 94 |
foreach ( $this_sidebar as $_widget_id ) { |
| 95 |
// Remove all widgets of this type from the sidebar. We'll add the new data in a second. This makes sure we don't get any duplicate data |
| 96 |
// since widget ids aren't necessarily persistent across multiple updates |
| 97 |
if ( 'jl_cat_posts_widget' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { |
| 98 |
$widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; |
| 99 |
if ( !in_array( "cat-posts-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed. "many-$widget_number" is "{id_base}-{widget_number} |
| 100 |
unset($options[$widget_number]); |
| 101 |
} |
| 102 |
} |
| 103 |
|
| 104 |
foreach ( (array) $_POST['cat-posts'] as $widget_number => $cat_posts_instance ) { |
| 105 |
// compile data from $widget_many_instance |
| 106 |
$title = wp_specialchars( $cat_posts_instance['title'] ); |
| 107 |
$options[$widget_number] = array( 'title' => $title, 'cat' => (int) $cat_posts_instance['cat'], 'num' => (int) $cat_posts_instance['num'], 'title_link' => (bool) $cat_posts_instance['title_link'], 'excerpt' => (bool) $cat_posts_instance['excerpt'] ); |
| 108 |
} |
| 109 |
|
| 110 |
update_option('widget_cat_posts', $options); |
| 111 |
|
| 112 |
$updated = true; // So that we don't go through this more than once |
| 113 |
} |
| 114 |
|
| 115 |
|
| 116 |
// Here we echo out the form |
| 117 |
if ( -1 == $number ) { // We echo out a template for a form which can be converted to a specific form later via JS |
| 118 |
$title = ''; |
| 119 |
$cat = ''; |
| 120 |
$num = 5; |
| 121 |
$link = false; |
| 122 |
$excerpt = false; |
| 123 |
$number = '%i%'; |
| 124 |
} else { |
| 125 |
$title = attribute_escape($options[$number]['title']); |
| 126 |
$cat = (int) $options[$number]['cat']; |
| 127 |
$num = (int) $options[$number]['num']; |
| 128 |
$link = (bool) $options[$number]['title_link']; |
| 129 |
$excerpt = (bool) $options[$number]['excerpt']; |
| 130 |
} |
| 131 |
|
| 132 |
// The form has inputs with names like widget-many[$number][something] so that all data for that instance of |
| 133 |
// the widget are stored in one $_POST variable: $_POST['widget-many'][$number] |
| 134 |
?> |
| 135 |
<p> |
| 136 |
<label for="cat-posts-title-<?php echo $number; ?>"> |
| 137 |
<?php _e( 'Title:' ); ?> |
| 138 |
<input class="widefat" id="cat-posts-title-<?php echo $number; ?>" name="cat-posts[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" /> |
| 139 |
</label> |
| 140 |
</p> |
| 141 |
|
| 142 |
<p> |
| 143 |
<label> |
| 144 |
<?php _e( 'Category:' ); ?><br /> |
| 145 |
<?php wp_dropdown_categories( array( 'name' => 'cat-posts[' . $number . '][cat]', 'selected' => $cat ) ); ?> |
| 146 |
</label> |
| 147 |
</p> |
| 148 |
|
| 149 |
<p> |
| 150 |
<label for="cat-posts-number-<?php echo $number; ?>"> |
| 151 |
<?php _e('Number of posts to show:'); ?> |
| 152 |
<input style="width: 25px; text-align: center;" id="cat-posts-number-<?php echo $number; ?>" name="cat-posts[<?php echo $number; ?>][num]" type="text" value="<?php echo $num; ?>" /> |
| 153 |
</label> |
| 154 |
</p> |
| 155 |
|
| 156 |
<p> |
| 157 |
<label for="cat-posts-link-<?php echo $number; ?>"> |
| 158 |
<input type="checkbox" class="checkbox" id="cat-posts-link-<?php echo $number; ?>" name="cat-posts[<?php echo $number; ?>][title_link]"<?php checked( (bool) $link, true ); ?> /> |
| 159 |
<?php _e( 'Make widget title link' ); ?> |
| 160 |
</label> |
| 161 |
</p> |
| 162 |
|
| 163 |
<p> |
| 164 |
<label for="cat-posts-excerpt-<?php echo $number; ?>"> |
| 165 |
<input type="checkbox" class="checkbox" id="cat-posts-excerpt-<?php echo $number; ?>" name="cat-posts[<?php echo $number; ?>][excerpt]"<?php checked( (bool) $excerpt, true ); ?> /> |
| 166 |
<?php _e( 'Show post excerpt' ); ?> |
| 167 |
</label> |
| 168 |
</p> |
| 169 |
|
| 170 |
<input type="hidden" id="cat-posts-<?php echo $number; ?>" name="cat-posts[<?php echo $number; ?>][submit]" value="1" /> |
| 171 |
<?php |
| 172 |
|
| 173 |
} |
| 174 |
|
| 175 |
// Registers each instance of our widget on startup |
| 176 |
function jl_cat_posts_register() { |
| 177 |
if ( !$options = get_option('widget_cat_posts') ) |
| 178 |
$options = array(); |
| 179 |
|
| 180 |
$widget_ops = array('classname' => 'cat_posts', 'description' => __('Widget that shows posts from a specific category.')); |
| 181 |
$control_ops = array('id_base' => 'cat-posts'); |
| 182 |
$name = __('Category Posts'); |
| 183 |
|
| 184 |
$registered = false; |
| 185 |
foreach ( array_keys($options) as $o ) { |
| 186 |
// Old widgets can have null values for some reason |
| 187 |
if ( !isset($options[$o]['cat']) ) // we used 'something' above in our exampple. Replace with with whatever your real data are. |
| 188 |
continue; |
| 189 |
|
| 190 |
// $id should look like {$id_base}-{$o} |
| 191 |
$id = "cat-posts-$o"; // Never never never translate an id |
| 192 |
$registered = true; |
| 193 |
wp_register_sidebar_widget( $id, $name, 'jl_cat_posts_widget', $widget_ops, array( 'number' => $o ) ); |
| 194 |
wp_register_widget_control( $id, $name, 'jl_cat_posts_control', $control_ops, array( 'number' => $o ) ); |
| 195 |
} |
| 196 |
|
| 197 |
// If there are none, we register the widget's existance with a generic template |
| 198 |
if ( !$registered ) { |
| 199 |
wp_register_sidebar_widget( 'cat-posts-1', $name, 'jl_cat_posts_widget', $widget_ops, array( 'number' => -1 ) ); |
| 200 |
wp_register_widget_control( 'cat-posts-1', $name, 'jl_cat_posts_control', $control_ops, array( 'number' => -1 ) ); |
| 201 |
} |
| 202 |
} |
| 203 |
|
| 204 |
// This is important |
| 205 |
add_action( 'widgets_init', 'jl_cat_posts_register' ); |
| 206 |
|
| 207 |
?> |