Changeset 2402625
- Timestamp:
- 10/19/2020 02:46:21 PM (4 years ago)
- Location:
- wp-post-series
- Files:
-
- 290 added
- 6 deleted
- 8 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
wp-post-series/assets/banner-772x250.png
-
Property
svn:mime-type
changed from
application/octet-stream
toimage/png
-
Property
svn:mime-type
changed from
-
wp-post-series/assets/screenshot-1.png
-
Property
svn:mime-type
changed from
application/octet-stream
toimage/png
-
Property
svn:mime-type
changed from
-
wp-post-series/tags/2.0.0/readme.txt
r1384460 r2402625 2 2 Contributors: mikejolley 3 3 Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=mike.jolley@me.com¤cy_code=&amount=&return=&item_name=Buy+me+a+coffee+for+WP+Post+Series 4 Tags: series, posts, post series, post 5 Requires at least: 3.8 6 Tested up to: 4.5 7 Stable tag: 1.1.0 4 Tags: series, post series, organize, course, book 5 Requires at least: 5.4 6 Tested up to: 5.6 7 Requires PHP: 5.6 8 Stable tag: 2.0.0 8 9 9 Setup a series of posts using a new taxonomy. Posts within a series will show an info box above the content with links to other posts in the series.10 . 10 11 11 12 == Description == 12 13 13 WP Post Series is a _lightweight_ plugin for making a series of posts and showing information about the series on the post page. The information box is prepended to the post content, and it can work with any theme (given a bit of CSS styling) - no setup required. 14 WP Post Series is a _lightweight_ plugin for making a series of posts and showing information about the series on the post page. 15 16 Posts in a series will automatically show a series box (prepended before the post content), or you can insert them manually using the Post Series Block. 14 17 15 18 = Features = … … 18 21 * Assign post series to your posts. 19 22 * Filter posts in the backend by series. 20 * Show s the series above the post content.23 * Show. 21 24 * Developer friendly code — Custom taxonomies & template files. 22 25 … … 37 40 Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New. 38 41 39 In the search field type "WP Post Series" and click Search Plugins. Once you've found the plugin you can view details about it such as the thepoint release, rating and description. Most importantly of course, you can install it by clicking _Install Now_.42 In the search field type "WP Post Series" and click Search Plugins. Once you've found the plugin you can view details about it such as the point release, rating and description. Most importantly of course, you can install it by clicking _Install Now_. 40 43 41 44 = Manual installation = … … 44 47 45 48 * Download the plugin file to your computer and unzip it 46 * Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's`wp-content/plugins/` directory.49 * Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress `wp-content/plugins/` directory. 47 50 * Activate the plugin from the Plugins menu within the WordPress admin. 48 51 49 52 == Screenshots == 50 53 51 1. The series information box 54 1. Post Series Display 55 2. Post Series Block Settings 52 56 53 57 == Changelog == 58 59 60 61 62 63 64 65 54 66 55 67 = 1.1.0 = -
wp-post-series/tags/2.0.0/templates/series-box.php
r1295134 r2402625 1 <aside class="<?php echo $post_series_box_class; ?>"> 2 <p class="wp-post-series-name"> 3 <?php 4 if ( apply_filters( 'wp_post_series_enable_archive', false ) ) { 5 $series_name = '<a href="' . get_term_link( $series->term_id, 'post_series' ) . '">' . esc_html( $series->name ) . '</a>'; 6 } else { 7 $series_name = esc_html( $series->name ); 8 } 9 printf( __( 'This is post %d of %d in the series <em>“%s”</em>', 'wp-post-series' ), $post_in_series, sizeof( $posts_in_series ), $series_name ); 10 ?> 11 </p> 1 <?php 2 /** 3 * Post Series Information Template. 4 * 5 * @package MJ/PostSeries 6 */ 12 7 13 <?php if ( is_single() && sizeof( $posts_in_series ) > 1 ) : ?> 8 $toggle_id = uniqid( 'collapsible-series-' . $series->slug ); 9 ?> 10 <div class="<?php echo esc_attr( $post_series_box_class ); ?>"> 11 <?php if ( ! $show_posts ) : ?> 12 <input id="<?php echo esc_attr( $toggle_id ); ?>" class="wp-post-series-box__toggle_checkbox" type="checkbox"> 13 <?php endif; ?> 14 14 15 <nav class="wp-post-series-nav"> 15 <label 16 class="wp-post-series-box__label" 17 <?php if ( ! $show_posts ) : ?> 18 for="<?php echo esc_attr( $toggle_id ); ?>" 19 tabindex="0" 20 <?php endif; ?> 21 > 22 <p class="wp-post-series-box__name wp-post-series-name"> 23 <?php echo wp_kses_post( $series_label ); ?> 24 </p> 25 <?php if ( $show_description ) : ?> 26 <div class="wp-post-series-box__description wp-post-series-description"> 27 <?php echo wp_kses_post( $description ); ?> 28 </div> 29 <?php endif; ?> 30 </label> 31 32 <?php if ( $has_multiple_posts ) : ?> 33 <div class="wp-post-series-box__posts"> 16 34 <ol> 17 <?php foreach ( $posts_in_series as $key => $post_id ) : ?> 18 <li> 19 <?php if ( ! is_single( $post_id ) && 'publish' === get_post_status( $post_id ) ) echo '<a href="' . get_permalink( $post_id ) . '">'; ?> 20 <?php echo 'publish' === get_post_status( $post_id ) ? get_the_title( $post_id ) : sprintf( __( '%s – <em>Scheduled for %s</em>', 'wp-post-series' ), get_the_title( $post_id ), get_post_time( get_option( 'date_format' ), false, $post_id ) ); ?> 21 <?php if ( ! is_single( $post_id ) && 'publish' === get_post_status( $post_id ) ) echo '</a>'; ?> 22 </li> 35 <?php foreach ( $posts_in_series_links as $link ) : ?> 36 <li><?php echo wp_kses_post( $link ); ?></li> 23 37 <?php endforeach; ?> 24 38 </ol> 25 </ nav>39 </v> 26 40 <?php endif; ?> 27 28 <?php if ( is_single() ) : ?> 29 <?php if ( $description ) : ?> 30 <div class="wp-post-series-description"><?php echo wpautop( wptexturize( $description ) ); ?></div> 31 <?php endif; ?> 32 33 <?php endif; ?> 34 </aside> 41 </div> -
wp-post-series/tags/2.0.0/wp-post-series.php
r1384460 r2402625 1 1 <?php 2 2 /** 3 * Plugin Name: WP Post Series 4 * Plugin URI: https://github.com/mikejolley/wp-post-series 5 * Description: Lets you setup a simple series of posts using taxonomies. Posts within a series will show an information box above the content automatically with links to other posts in the series and a description. 6 * Version: 1.1.0 7 * Author: Mike Jolley 8 * Author URI: http://mikejolley.com 9 * Requires at least: 3.8 10 * Tested up to: 4.5 3 * WP Post Series 11 4 * 12 * Text Domain: wp-post-series 13 * Domain Path: /languages/ 5 * @package MJ/PostSeries 6 * @author Mike Jolley 7 * @copyright 2020 Mike Jolley 8 * @license GPL-3.0-or-later 9 * 10 * @wordpress-plugin 11 * Plugin Name: WP Post Series 12 * Plugin URI: https://wordpress.org/plugins/wp-post-series/ 13 * Description: Publish and link together a series of posts using a new "series" taxonomy. Automatically display links to other posts in a series above your content. 14 * Version: 2.0.0 15 * Author: Mike Jolley 16 * Author URI: http://mikejolley.com 17 * Requires at least: 5.4 18 * Tested up to: 5.6 19 * Requires PHP: 5.6 20 * Text Domain: wp-post-series 21 * Domain Path: /languages/ 14 22 */ 15 if ( ! defined( 'ABSPATH' ) )16 exit;17 23 18 class WP_Post_Series { 24 defined( 'ABSPATH' ) || exit; 19 25 20 /** 21 * Constructor for the class 22 */ 23 public function __construct() { 24 // Define constants 25 define( 'WP_POST_SERIES_VERSION', '1.1.0' ); 26 define( 'WP_POST_SERIES_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) ); 27 define( 'WP_POST_SERIES_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) ); 28 29 // Init 30 add_action( 'init', array( $this, 'load_textdomain' ) ); 31 add_action( 'init', array( $this, 'register_taxonomies' ) ); 32 33 // Admin columns 34 add_filter( 'manage_edit-post_columns', array( $this, 'columns' ) ); 35 add_action( 'manage_post_posts_custom_column', array( $this, 'custom_columns' ), 2 ); 36 37 // Admin filtering 38 add_action( "restrict_manage_posts", array( $this, "posts_in_series" ) ); 39 40 // Frontend display 41 add_filter( 'the_content', array( $this, "add_series_to_content" ) ); 42 add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) ); 43 } 44 45 /** 46 * Load the plugin textdomain for localistion 47 */ 48 public function load_textdomain() { 49 load_plugin_textdomain( 'wp-post-series', false, plugin_basename( dirname( __FILE__ ) ) . "/languages" ); 50 } 51 52 /** 53 * Register the taxonomies 54 */ 55 public function register_taxonomies() { 56 57 $plural = __( 'Post series', 'wp-post-series' ); 58 $singular = __( 'Post series', 'wp-post-series' ); 59 60 register_taxonomy( "post_series", 61 array( "post" ), 62 array( 63 'hierarchical' => false, 64 'label' => $plural, 65 'labels' => array( 66 'menu_name' => __( 'Series', 'wp-post-series' ), 67 'name' => $plural, 68 'singular_name' => $singular, 69 'search_items' => sprintf( __( 'Search %s', 'wp-post-series' ), $plural ), 70 'all_items' => sprintf( __( 'All %s', 'wp-post-series' ), $plural ), 71 'parent_item' => sprintf( __( '%s', 'wp-post-series' ), $singular ), 72 'parent_item_colon' => sprintf( __( '%s:', 'wp-post-series' ), $singular ), 73 'edit_item' => sprintf( __( 'Edit %s', 'wp-post-series' ), $singular ), 74 'update_item' => sprintf( __( 'Update %s', 'wp-post-series' ), $singular ), 75 'add_new_item' => sprintf( __( 'Add New %s', 'wp-post-series' ), $singular ), 76 'new_item_name' => sprintf( __( 'New %s Name', 'wp-post-series' ), $singular ) 77 ), 78 'show_ui' => true, 79 'query_var' => true, 80 'rewrite' => apply_filters( 'wp_post_series_enable_archive', false ), 81 'meta_box_cb' => array( $this, 'post_series_meta_box' ) 82 ) 83 ); 84 } 85 86 /** 87 * Get a post's series 88 * @param int $post_id post ID 89 * @return object the term object 90 */ 91 public function get_post_series( $post_id ) { 92 $series = wp_get_post_terms( $post_id, 'post_series' ); 93 94 if ( ! is_wp_error( $series ) && ! empty( $series ) && is_array( $series ) ) { 95 $series = current( $series ); 96 } else { 97 $series = false; 98 } 99 100 return $series; 101 } 102 103 /** 104 * Get the ID of a post's series 105 * @param int $post_id post ID 106 * @return int series ID 107 */ 108 public function get_post_series_id( $post_id ) { 109 $series = $this->get_post_series( $post_id ); 110 111 if ( $series ) { 112 return $series->term_id; 113 } else { 114 return 0; 115 } 116 } 117 118 /** 119 * Output the list of post series and allow admin to assign to a post. Uses a select box. 120 * @param array $post Post being edited 121 */ 122 public function post_series_meta_box( $post ) { 123 124 // Get the current series for the post if set 125 $current_series = $this->get_post_series_id( $post->ID ); 126 127 // Get list of all series and the taxonomy 128 $tax = get_taxonomy( 'post_series' ); 129 $all_series = get_terms( 'post_series', array( 'hide_empty' => false, 'orderby' => 'name' ) ); 130 131 ?> 132 <div id="taxonomy-<?php echo $tax->name; ?>" class="categorydiv"> 133 <label class="screen-reader-text" for="new_post_series_parent"> 134 <?php echo $tax->labels->parent_item_colon; ?> 135 </label> 136 <select name="tax_input[post_series]" style="width:100%"> 137 <option value="0"><?php echo '— ' . $tax->labels->parent_item . ' —'; ?></option> 138 <?php foreach ( $all_series as $series ) : ?> 139 <option value="<?php echo esc_attr( $series->slug ); ?>" <?php selected( $current_series, $series->term_id ); ?>><?php echo esc_html( $series->name ); ?></option> 140 <?php endforeach; ?> 141 </select> 142 </div> 143 <?php 144 } 145 146 /** 147 * Output admin column headers 148 * @param array $columns existing columns 149 * @return array new columns 150 */ 151 public function columns( $columns ) { 152 if ( ! is_array( $columns ) ) { 153 $new_columns = array(); 154 } 155 156 foreach ( $columns as $key => $column ) { 157 $new_columns[ $key ] = $column; 158 159 if ( 'categories' == $key ) { 160 $new_columns['post_series'] = __( 'Series', 'wp-post-series' ); 161 } 162 } 163 164 return $new_columns; 165 } 166 167 /** 168 * Output admin column values 169 * @param string $column key for the column 170 */ 171 public function custom_columns( $column ) { 172 global $post; 173 174 if ( 'post_series' == $column ) { 175 $current_series = $this->get_post_series( $post->ID ); 176 177 if ( $current_series ) { 178 echo '<a href="' . esc_url( admin_url( 'edit.php?post_series=' . $current_series->slug ) ) . '">' . esc_html( $current_series->name ) . '</a>'; 179 } else { 180 _e( 'N/A', 'wp-post-series' ); 181 } 182 } 183 } 184 185 /** 186 * Filter posts by a particular series 187 */ 188 public function posts_in_series() { 189 global $typenow, $wp_query; 190 191 if ( $typenow != 'post' ) { 192 return; 193 } 194 195 $current_series = isset( $_REQUEST['post_series'] ) ? sanitize_text_field( $_REQUEST['post_series'] ) : ''; 196 $all_series = get_terms( 'post_series', array( 'hide_empty' => true, 'orderby' => 'name' ) ); 197 198 if ( empty( $all_series ) ) { 199 return; 200 } 201 ?> 202 <select name="post_series"> 203 <option value=""><?php _e( 'Show all series', 'wp-post-series' ) ?></option> 204 <?php foreach ( $all_series as $series ) : ?> 205 <option value="<?php echo esc_attr( $series->slug ); ?>" <?php selected( $current_series, $series->slug ); ?>><?php echo esc_html( $series->name ); ?></option> 206 <?php endforeach; ?> 207 </select> 208 <?php 209 } 210 211 /** 212 * Append/Prepend the series info box to the post content 213 * @param string $content Post content 214 * @return string Ammended post content 215 */ 216 public function add_series_to_content( $content ) { 217 global $post; 218 219 if ( 'post' !== $post->post_type || ! is_main_query() ) { 220 return $content; 221 } 222 223 $series = $this->get_post_series( $post->ID ); 224 225 if ( ! $series ) { 226 return $content; 227 } 228 229 wp_enqueue_script( 'wp-post-series' ); 230 231 // Create series info box 232 $term_description = term_description( $series->term_id, 'post_series' ); 233 $posts_in_series = get_posts( array( 234 'post_type' => 'post', 235 'posts_per_page' => -1, 236 'fields' => 'ids', 237 'no_found_rows' => true, 238 'orderby' => 'date', 239 'order' => 'asc', 240 'post_status' => array( 'publish', 'future' ), 241 'tax_query' => array( 242 array( 243 'taxonomy' => 'post_series', 244 'field' => 'slug', 245 'terms' => $series->slug 246 ) 247 ) 248 ) ); 249 250 $post_in_series = 1; 251 252 foreach ( $posts_in_series as $post_id ) { 253 if ( $post_id == $post->ID ) { 254 break; 255 } 256 $post_in_series ++; 257 } 258 259 // add the series slug to the post series box class 260 $post_series_box_class = 'wp-post-series-box series-'. $series->slug; 261 262 if ( is_single() && sizeof( $posts_in_series ) > 1 ) { 263 $post_series_box_class .= ' expandable'; 264 } 265 266 ob_start(); 267 268 $this->get_template( 'series-box.php', array( 269 'series' => $series, 270 'description' => $term_description, 271 'posts_in_series' => $posts_in_series, 272 'post_in_series' => $post_in_series, 273 'post_series_box_class' => $post_series_box_class 274 ) ); 275 276 $info_box = ob_get_clean(); 277 278 // Append or prepend 279 $append = apply_filters( 'wp_post_series_append_info', false ); 280 281 if ( $append ) { 282 $content = $content . $info_box; 283 } else { 284 $content = $info_box . $content; 285 } 286 287 return $content; 288 } 289 290 /** 291 * Get and include template files. 292 * 293 * @param mixed $template_name 294 * @param array $args (default: array()) 295 * @param string $template_path (default: '') 296 * @param string $default_path (default: '') 297 */ 298 public function get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) { 299 if ( $args && is_array( $args ) ) { 300 extract( $args ); 301 } 302 include( $this->locate_template( $template_name, $template_path, $default_path ) ); 303 } 304 305 /** 306 * Locate a template and return the path for inclusion. 307 * 308 * This is the load order: 309 * 310 * yourtheme / $template_path / $template_name 311 * yourtheme / $template_name 312 * $default_path / $template_name 313 * 314 * @param mixed $template_name 315 * @param string $template_path (default: '') 316 * @param string $default_path (default: '') 317 * @return string 318 */ 319 public function locate_template( $template_name, $template_path = '', $default_path = '' ) { 320 if ( ! $template_path ) { 321 $template_path = 'wp_post_series'; 322 } 323 if ( ! $default_path ) { 324 $default_path = WP_POST_SERIES_PLUGIN_DIR . '/templates/'; 325 } 326 327 // Look within passed path within the theme - this is priority 328 $template = locate_template( 329 array( 330 trailingslashit( $template_path ) . $template_name, 331 $template_name 332 ) 333 ); 334 335 // Get default template 336 if ( ! $template ) { 337 $template = $default_path . $template_name; 338 } 339 340 // Return what we found 341 return apply_filters( 'wp_post_series_locate_template', $template, $template_name, $template_path ); 342 } 343 344 /** 345 * frontend_scripts function. 346 * 347 * @access public 348 * @return void 349 */ 350 public function frontend_scripts() { 351 wp_register_script( 'wp-post-series', WP_POST_SERIES_PLUGIN_URL . '/assets/js/post-series.js', array( 'jquery' ), WP_POST_SERIES_VERSION, true ); 352 wp_enqueue_style( 'wp-post-series-frontend', WP_POST_SERIES_PLUGIN_URL . '/assets/css/post-series.css' ); 353 } 26 /** 27 * Bail early if PHP version dependency is not met. 28 */ 29 if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { 30 return; 354 31 } 355 32 356 new WP_Post_Series();33 ; -
wp-post-series/trunk/readme.txt
r1384460 r2402625 2 2 Contributors: mikejolley 3 3 Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=mike.jolley@me.com¤cy_code=&amount=&return=&item_name=Buy+me+a+coffee+for+WP+Post+Series 4 Tags: series, posts, post series, post 5 Requires at least: 3.8 6 Tested up to: 4.5 7 Stable tag: 1.1.0 4 Tags: series, post series, organize, course, book 5 Requires at least: 5.4 6 Tested up to: 5.6 7 Requires PHP: 5.6 8 Stable tag: 2.0.0 8 9 9 Setup a series of posts using a new taxonomy. Posts within a series will show an info box above the content with links to other posts in the series.10 . 10 11 11 12 == Description == 12 13 13 WP Post Series is a _lightweight_ plugin for making a series of posts and showing information about the series on the post page. The information box is prepended to the post content, and it can work with any theme (given a bit of CSS styling) - no setup required. 14 WP Post Series is a _lightweight_ plugin for making a series of posts and showing information about the series on the post page. 15 16 Posts in a series will automatically show a series box (prepended before the post content), or you can insert them manually using the Post Series Block. 14 17 15 18 = Features = … … 18 21 * Assign post series to your posts. 19 22 * Filter posts in the backend by series. 20 * Show s the series above the post content.23 * Show. 21 24 * Developer friendly code — Custom taxonomies & template files. 22 25 … … 37 40 Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New. 38 41 39 In the search field type "WP Post Series" and click Search Plugins. Once you've found the plugin you can view details about it such as the thepoint release, rating and description. Most importantly of course, you can install it by clicking _Install Now_.42 In the search field type "WP Post Series" and click Search Plugins. Once you've found the plugin you can view details about it such as the point release, rating and description. Most importantly of course, you can install it by clicking _Install Now_. 40 43 41 44 = Manual installation = … … 44 47 45 48 * Download the plugin file to your computer and unzip it 46 * Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's`wp-content/plugins/` directory.49 * Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress `wp-content/plugins/` directory. 47 50 * Activate the plugin from the Plugins menu within the WordPress admin. 48 51 49 52 == Screenshots == 50 53 51 1. The series information box 54 1. Post Series Display 55 2. Post Series Block Settings 52 56 53 57 == Changelog == 58 59 60 61 62 63 64 65 54 66 55 67 = 1.1.0 = -
wp-post-series/trunk/templates/series-box.php
r1295134 r2402625 1 <aside class="<?php echo $post_series_box_class; ?>"> 2 <p class="wp-post-series-name"> 3 <?php 4 if ( apply_filters( 'wp_post_series_enable_archive', false ) ) { 5 $series_name = '<a href="' . get_term_link( $series->term_id, 'post_series' ) . '">' . esc_html( $series->name ) . '</a>'; 6 } else { 7 $series_name = esc_html( $series->name ); 8 } 9 printf( __( 'This is post %d of %d in the series <em>“%s”</em>', 'wp-post-series' ), $post_in_series, sizeof( $posts_in_series ), $series_name ); 10 ?> 11 </p> 1 <?php 2 /** 3 * Post Series Information Template. 4 * 5 * @package MJ/PostSeries 6 */ 12 7 13 <?php if ( is_single() && sizeof( $posts_in_series ) > 1 ) : ?> 8 $toggle_id = uniqid( 'collapsible-series-' . $series->slug ); 9 ?> 10 <div class="<?php echo esc_attr( $post_series_box_class ); ?>"> 11 <?php if ( ! $show_posts ) : ?> 12 <input id="<?php echo esc_attr( $toggle_id ); ?>" class="wp-post-series-box__toggle_checkbox" type="checkbox"> 13 <?php endif; ?> 14 14 15 <nav class="wp-post-series-nav"> 15 <label 16 class="wp-post-series-box__label" 17 <?php if ( ! $show_posts ) : ?> 18 for="<?php echo esc_attr( $toggle_id ); ?>" 19 tabindex="0" 20 <?php endif; ?> 21 > 22 <p class="wp-post-series-box__name wp-post-series-name"> 23 <?php echo wp_kses_post( $series_label ); ?> 24 </p> 25 <?php if ( $show_description ) : ?> 26 <div class="wp-post-series-box__description wp-post-series-description"> 27 <?php echo wp_kses_post( $description ); ?> 28 </div> 29 <?php endif; ?> 30 </label> 31 32 <?php if ( $has_multiple_posts ) : ?> 33 <div class="wp-post-series-box__posts"> 16 34 <ol> 17 <?php foreach ( $posts_in_series as $key => $post_id ) : ?> 18 <li> 19 <?php if ( ! is_single( $post_id ) && 'publish' === get_post_status( $post_id ) ) echo '<a href="' . get_permalink( $post_id ) . '">'; ?> 20 <?php echo 'publish' === get_post_status( $post_id ) ? get_the_title( $post_id ) : sprintf( __( '%s – <em>Scheduled for %s</em>', 'wp-post-series' ), get_the_title( $post_id ), get_post_time( get_option( 'date_format' ), false, $post_id ) ); ?> 21 <?php if ( ! is_single( $post_id ) && 'publish' === get_post_status( $post_id ) ) echo '</a>'; ?> 22 </li> 35 <?php foreach ( $posts_in_series_links as $link ) : ?> 36 <li><?php echo wp_kses_post( $link ); ?></li> 23 37 <?php endforeach; ?> 24 38 </ol> 25 </ nav>39 </v> 26 40 <?php endif; ?> 27 28 <?php if ( is_single() ) : ?> 29 <?php if ( $description ) : ?> 30 <div class="wp-post-series-description"><?php echo wpautop( wptexturize( $description ) ); ?></div> 31 <?php endif; ?> 32 33 <?php endif; ?> 34 </aside> 41 </div> -
wp-post-series/trunk/wp-post-series.php
r1384460 r2402625 1 1 <?php 2 2 /** 3 * Plugin Name: WP Post Series 4 * Plugin URI: https://github.com/mikejolley/wp-post-series 5 * Description: Lets you setup a simple series of posts using taxonomies. Posts within a series will show an information box above the content automatically with links to other posts in the series and a description. 6 * Version: 1.1.0 7 * Author: Mike Jolley 8 * Author URI: http://mikejolley.com 9 * Requires at least: 3.8 10 * Tested up to: 4.5 3 * WP Post Series 11 4 * 12 * Text Domain: wp-post-series 13 * Domain Path: /languages/ 5 * @package MJ/PostSeries 6 * @author Mike Jolley 7 * @copyright 2020 Mike Jolley 8 * @license GPL-3.0-or-later 9 * 10 * @wordpress-plugin 11 * Plugin Name: WP Post Series 12 * Plugin URI: https://wordpress.org/plugins/wp-post-series/ 13 * Description: Publish and link together a series of posts using a new "series" taxonomy. Automatically display links to other posts in a series above your content. 14 * Version: 2.0.0 15 * Author: Mike Jolley 16 * Author URI: http://mikejolley.com 17 * Requires at least: 5.4 18 * Tested up to: 5.6 19 * Requires PHP: 5.6 20 * Text Domain: wp-post-series 21 * Domain Path: /languages/ 14 22 */ 15 if ( ! defined( 'ABSPATH' ) )16 exit;17 23 18 class WP_Post_Series { 24 defined( 'ABSPATH' ) || exit; 19 25 20 /** 21 * Constructor for the class 22 */ 23 public function __construct() { 24 // Define constants 25 define( 'WP_POST_SERIES_VERSION', '1.1.0' ); 26 define( 'WP_POST_SERIES_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) ); 27 define( 'WP_POST_SERIES_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) ); 28 29 // Init 30 add_action( 'init', array( $this, 'load_textdomain' ) ); 31 add_action( 'init', array( $this, 'register_taxonomies' ) ); 32 33 // Admin columns 34 add_filter( 'manage_edit-post_columns', array( $this, 'columns' ) ); 35 add_action( 'manage_post_posts_custom_column', array( $this, 'custom_columns' ), 2 ); 36 37 // Admin filtering 38 add_action( "restrict_manage_posts", array( $this, "posts_in_series" ) ); 39 40 // Frontend display 41 add_filter( 'the_content', array( $this, "add_series_to_content" ) ); 42 add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) ); 43 } 44 45 /** 46 * Load the plugin textdomain for localistion 47 */ 48 public function load_textdomain() { 49 load_plugin_textdomain( 'wp-post-series', false, plugin_basename( dirname( __FILE__ ) ) . "/languages" ); 50 } 51 52 /** 53 * Register the taxonomies 54 */ 55 public function register_taxonomies() { 56 57 $plural = __( 'Post series', 'wp-post-series' ); 58 $singular = __( 'Post series', 'wp-post-series' ); 59 60 register_taxonomy( "post_series", 61 array( "post" ), 62 array( 63 'hierarchical' => false, 64 'label' => $plural, 65 'labels' => array( 66 'menu_name' => __( 'Series', 'wp-post-series' ), 67 'name' => $plural, 68 'singular_name' => $singular, 69 'search_items' => sprintf( __( 'Search %s', 'wp-post-series' ), $plural ), 70 'all_items' => sprintf( __( 'All %s', 'wp-post-series' ), $plural ), 71 'parent_item' => sprintf( __( '%s', 'wp-post-series' ), $singular ), 72 'parent_item_colon' => sprintf( __( '%s:', 'wp-post-series' ), $singular ), 73 'edit_item' => sprintf( __( 'Edit %s', 'wp-post-series' ), $singular ), 74 'update_item' => sprintf( __( 'Update %s', 'wp-post-series' ), $singular ), 75 'add_new_item' => sprintf( __( 'Add New %s', 'wp-post-series' ), $singular ), 76 'new_item_name' => sprintf( __( 'New %s Name', 'wp-post-series' ), $singular ) 77 ), 78 'show_ui' => true, 79 'query_var' => true, 80 'rewrite' => apply_filters( 'wp_post_series_enable_archive', false ), 81 'meta_box_cb' => array( $this, 'post_series_meta_box' ) 82 ) 83 ); 84 } 85 86 /** 87 * Get a post's series 88 * @param int $post_id post ID 89 * @return object the term object 90 */ 91 public function get_post_series( $post_id ) { 92 $series = wp_get_post_terms( $post_id, 'post_series' ); 93 94 if ( ! is_wp_error( $series ) && ! empty( $series ) && is_array( $series ) ) { 95 $series = current( $series ); 96 } else { 97 $series = false; 98 } 99 100 return $series; 101 } 102 103 /** 104 * Get the ID of a post's series 105 * @param int $post_id post ID 106 * @return int series ID 107 */ 108 public function get_post_series_id( $post_id ) { 109 $series = $this->get_post_series( $post_id ); 110 111 if ( $series ) { 112 return $series->term_id; 113 } else { 114 return 0; 115 } 116 } 117 118 /** 119 * Output the list of post series and allow admin to assign to a post. Uses a select box. 120 * @param array $post Post being edited 121 */ 122 public function post_series_meta_box( $post ) { 123 124 // Get the current series for the post if set 125 $current_series = $this->get_post_series_id( $post->ID ); 126 127 // Get list of all series and the taxonomy 128 $tax = get_taxonomy( 'post_series' ); 129 $all_series = get_terms( 'post_series', array( 'hide_empty' => false, 'orderby' => 'name' ) ); 130 131 ?> 132 <div id="taxonomy-<?php echo $tax->name; ?>" class="categorydiv"> 133 <label class="screen-reader-text" for="new_post_series_parent"> 134 <?php echo $tax->labels->parent_item_colon; ?> 135 </label> 136 <select name="tax_input[post_series]" style="width:100%"> 137 <option value="0"><?php echo '— ' . $tax->labels->parent_item . ' —'; ?></option> 138 <?php foreach ( $all_series as $series ) : ?> 139 <option value="<?php echo esc_attr( $series->slug ); ?>" <?php selected( $current_series, $series->term_id ); ?>><?php echo esc_html( $series->name ); ?></option> 140 <?php endforeach; ?> 141 </select> 142 </div> 143 <?php 144 } 145 146 /** 147 * Output admin column headers 148 * @param array $columns existing columns 149 * @return array new columns 150 */ 151 public function columns( $columns ) { 152 if ( ! is_array( $columns ) ) { 153 $new_columns = array(); 154 } 155 156 foreach ( $columns as $key => $column ) { 157 $new_columns[ $key ] = $column; 158 159 if ( 'categories' == $key ) { 160 $new_columns['post_series'] = __( 'Series', 'wp-post-series' ); 161 } 162 } 163 164 return $new_columns; 165 } 166 167 /** 168 * Output admin column values 169 * @param string $column key for the column 170 */ 171 public function custom_columns( $column ) { 172 global $post; 173 174 if ( 'post_series' == $column ) { 175 $current_series = $this->get_post_series( $post->ID ); 176 177 if ( $current_series ) { 178 echo '<a href="' . esc_url( admin_url( 'edit.php?post_series=' . $current_series->slug ) ) . '">' . esc_html( $current_series->name ) . '</a>'; 179 } else { 180 _e( 'N/A', 'wp-post-series' ); 181 } 182 } 183 } 184 185 /** 186 * Filter posts by a particular series 187 */ 188 public function posts_in_series() { 189 global $typenow, $wp_query; 190 191 if ( $typenow != 'post' ) { 192 return; 193 } 194 195 $current_series = isset( $_REQUEST['post_series'] ) ? sanitize_text_field( $_REQUEST['post_series'] ) : ''; 196 $all_series = get_terms( 'post_series', array( 'hide_empty' => true, 'orderby' => 'name' ) ); 197 198 if ( empty( $all_series ) ) { 199 return; 200 } 201 ?> 202 <select name="post_series"> 203 <option value=""><?php _e( 'Show all series', 'wp-post-series' ) ?></option> 204 <?php foreach ( $all_series as $series ) : ?> 205 <option value="<?php echo esc_attr( $series->slug ); ?>" <?php selected( $current_series, $series->slug ); ?>><?php echo esc_html( $series->name ); ?></option> 206 <?php endforeach; ?> 207 </select> 208 <?php 209 } 210 211 /** 212 * Append/Prepend the series info box to the post content 213 * @param string $content Post content 214 * @return string Ammended post content 215 */ 216 public function add_series_to_content( $content ) { 217 global $post; 218 219 if ( 'post' !== $post->post_type || ! is_main_query() ) { 220 return $content; 221 } 222 223 $series = $this->get_post_series( $post->ID ); 224 225 if ( ! $series ) { 226 return $content; 227 } 228 229 wp_enqueue_script( 'wp-post-series' ); 230 231 // Create series info box 232 $term_description = term_description( $series->term_id, 'post_series' ); 233 $posts_in_series = get_posts( array( 234 'post_type' => 'post', 235 'posts_per_page' => -1, 236 'fields' => 'ids', 237 'no_found_rows' => true, 238 'orderby' => 'date', 239 'order' => 'asc', 240 'post_status' => array( 'publish', 'future' ), 241 'tax_query' => array( 242 array( 243 'taxonomy' => 'post_series', 244 'field' => 'slug', 245 'terms' => $series->slug 246 ) 247 ) 248 ) ); 249 250 $post_in_series = 1; 251 252 foreach ( $posts_in_series as $post_id ) { 253 if ( $post_id == $post->ID ) { 254 break; 255 } 256 $post_in_series ++; 257 } 258 259 // add the series slug to the post series box class 260 $post_series_box_class = 'wp-post-series-box series-'. $series->slug; 261 262 if ( is_single() && sizeof( $posts_in_series ) > 1 ) { 263 $post_series_box_class .= ' expandable'; 264 } 265 266 ob_start(); 267 268 $this->get_template( 'series-box.php', array( 269 'series' => $series, 270 'description' => $term_description, 271 'posts_in_series' => $posts_in_series, 272 'post_in_series' => $post_in_series, 273 'post_series_box_class' => $post_series_box_class 274 ) ); 275 276 $info_box = ob_get_clean(); 277 278 // Append or prepend 279 $append = apply_filters( 'wp_post_series_append_info', false ); 280 281 if ( $append ) { 282 $content = $content . $info_box; 283 } else { 284 $content = $info_box . $content; 285 } 286 287 return $content; 288 } 289 290 /** 291 * Get and include template files. 292 * 293 * @param mixed $template_name 294 * @param array $args (default: array()) 295 * @param string $template_path (default: '') 296 * @param string $default_path (default: '') 297 */ 298 public function get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) { 299 if ( $args && is_array( $args ) ) { 300 extract( $args ); 301 } 302 include( $this->locate_template( $template_name, $template_path, $default_path ) ); 303 } 304 305 /** 306 * Locate a template and return the path for inclusion. 307 * 308 * This is the load order: 309 * 310 * yourtheme / $template_path / $template_name 311 * yourtheme / $template_name 312 * $default_path / $template_name 313 * 314 * @param mixed $template_name 315 * @param string $template_path (default: '') 316 * @param string $default_path (default: '') 317 * @return string 318 */ 319 public function locate_template( $template_name, $template_path = '', $default_path = '' ) { 320 if ( ! $template_path ) { 321 $template_path = 'wp_post_series'; 322 } 323 if ( ! $default_path ) { 324 $default_path = WP_POST_SERIES_PLUGIN_DIR . '/templates/'; 325 } 326 327 // Look within passed path within the theme - this is priority 328 $template = locate_template( 329 array( 330 trailingslashit( $template_path ) . $template_name, 331 $template_name 332 ) 333 ); 334 335 // Get default template 336 if ( ! $template ) { 337 $template = $default_path . $template_name; 338 } 339 340 // Return what we found 341 return apply_filters( 'wp_post_series_locate_template', $template, $template_name, $template_path ); 342 } 343 344 /** 345 * frontend_scripts function. 346 * 347 * @access public 348 * @return void 349 */ 350 public function frontend_scripts() { 351 wp_register_script( 'wp-post-series', WP_POST_SERIES_PLUGIN_URL . '/assets/js/post-series.js', array( 'jquery' ), WP_POST_SERIES_VERSION, true ); 352 wp_enqueue_style( 'wp-post-series-frontend', WP_POST_SERIES_PLUGIN_URL . '/assets/css/post-series.css' ); 353 } 26 /** 27 * Bail early if PHP version dependency is not met. 28 */ 29 if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { 30 return; 354 31 } 355 32 356 new WP_Post_Series();33 ;
Note: See TracChangeset
for help on using the changeset viewer.