Display Posts Shortcode - Version 3.0.0

Version Description

Download this release

Release Info

Developer billerickson
Plugin Icon 128x128 Display Posts Shortcode
Version 3.0.0
Comparing to
See all releases

Code changes from version 2.9.0 to 3.0.0

Files changed (3) hide show
  1. CHANGELOG.md +18 -0
  2. display-posts-shortcode.php +152 -28
  3. readme.txt +64 -13
CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
  # Change Log
2
  All notable changes to this project will be documented in this file, formatted via [this recommendation](http://keepachangelog.com/).
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  ### [2.9.0]
5
  #### Added
6
  * New parameter `exclude` for excluding specific post IDs, see #154
1
  # Change Log
2
  All notable changes to this project will be documented in this file, formatted via [this recommendation](http://keepachangelog.com/).
3
 
4
+ ### [3.0.0]
5
+ #### Added
6
+ * Added author_id parameter, see #195
7
+ * Added has_password parameter
8
+ * Added s parameter for performing a site search, see #184
9
+ * Added date_format="relative" format option (ex: 2 days ago), see #194
10
+ * Added post_parent__in and post_parent__not_in parameters, see #193
11
+ * Added excerpt_dash="false" option to disable dash in excerpt, see #204
12
+ * Added additional parameters to the `display_posts_shortcode_output` filter
13
+ * Added additional parameters to the `display_posts_shortcode_category_display` filter, see #185
14
+ * $dps_listing loop now accessible globally, see #198
15
+ * $dps_listing loop now accessible in open/close filters
16
+ * Added .excerpt-more class to excerpt more text, see #205
17
+
18
+ #### Changed
19
+ * excerpt_more text is always appended to end of excerpt, see #197
20
+ * In parameters that support multiple terms, they can now be separated with a comma or comma-space, see #183
21
+
22
  ### [2.9.0]
23
  #### Added
24
  * New parameter `exclude` for excluding specific post IDs, see #154
display-posts-shortcode.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * Plugin Name: Display Posts Shortcode
4
- * Plugin URI: http://www.billerickson.net/shortcode-to-display-posts/
5
  * Description: Display a listing of posts using the [display-posts] shortcode
6
- * Version: 2.9.0
7
  * Author: Bill Erickson
8
- * Author URI: http://www.billerickson.net
9
  *
10
  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
11
  * General Public License version 2, as published by the Free Software Foundation. You may NOT assume
@@ -15,7 +15,7 @@
15
  * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
  *
17
  * @package Display Posts
18
- * @version 2.9.0
19
  * @author Bill Erickson <bill@billerickson.net>
20
  * @copyright Copyright (c) 2011, Bill Erickson
21
  * @link http://www.billerickson.net/shortcode-to-display-posts/
@@ -25,7 +25,7 @@
25
 
26
  /**
27
  * To Customize, use the following filters:
28
- * @link https://github.com/billerickson/display-posts-shortcode/wiki#customization-with-filters
29
  */
30
 
31
  // Create the shortcode
@@ -38,6 +38,7 @@ function be_display_posts_shortcode( $atts ) {
38
  // Pull in shortcode attributes and set defaults
39
  $atts = shortcode_atts( array(
40
  'author' => '',
 
41
  'category' => '',
42
  'category_display' => '',
43
  'category_id' => false,
@@ -57,6 +58,7 @@ function be_display_posts_shortcode( $atts ) {
57
  'excerpt_more_link' => false,
58
  'exclude' => false,
59
  'exclude_current' => false,
 
60
  'id' => false,
61
  'ignore_sticky_posts' => false,
62
  'image_size' => false,
@@ -65,6 +67,7 @@ function be_display_posts_shortcode( $atts ) {
65
  'include_date' => false,
66
  'include_date_modified'=> false,
67
  'include_excerpt' => false,
 
68
  'include_link' => true,
69
  'include_title' => true,
70
  'meta_key' => '',
@@ -74,9 +77,12 @@ function be_display_posts_shortcode( $atts ) {
74
  'order' => 'DESC',
75
  'orderby' => 'date',
76
  'post_parent' => false,
 
 
77
  'post_status' => 'publish',
78
  'post_type' => 'post',
79
  'posts_per_page' => '10',
 
80
  'tag' => '',
81
  'tax_operator' => 'IN',
82
  'tax_include_children' => true,
@@ -94,6 +100,7 @@ function be_display_posts_shortcode( $atts ) {
94
  return;
95
 
96
  $author = sanitize_text_field( $atts['author'] );
 
97
  $category = sanitize_text_field( $atts['category'] );
98
  $category_display = 'true' == $atts['category_display'] ? 'category' : sanitize_text_field( $atts['category_display'] );
99
  $category_id = intval( $atts['category_id'] );
@@ -112,6 +119,7 @@ function be_display_posts_shortcode( $atts ) {
112
  $excerpt_more_link = filter_var( $atts['excerpt_more_link'], FILTER_VALIDATE_BOOLEAN );
113
  $exclude = $atts['exclude']; // Sanitized later as an array of integers
114
  $exclude_current = filter_var( $atts['exclude_current'], FILTER_VALIDATE_BOOLEAN );
 
115
  $id = $atts['id']; // Sanitized later as an array of integers
116
  $ignore_sticky_posts = filter_var( $atts['ignore_sticky_posts'], FILTER_VALIDATE_BOOLEAN );
117
  $image_size = sanitize_key( $atts['image_size'] );
@@ -121,6 +129,7 @@ function be_display_posts_shortcode( $atts ) {
121
  $include_date = filter_var( $atts['include_date'], FILTER_VALIDATE_BOOLEAN );
122
  $include_date_modified= filter_var( $atts['include_date_modified'], FILTER_VALIDATE_BOOLEAN );
123
  $include_excerpt = filter_var( $atts['include_excerpt'], FILTER_VALIDATE_BOOLEAN );
 
124
  $include_link = filter_var( $atts['include_link'], FILTER_VALIDATE_BOOLEAN );
125
  $meta_key = sanitize_text_field( $atts['meta_key'] );
126
  $meta_value = sanitize_text_field( $atts['meta_value'] );
@@ -129,9 +138,12 @@ function be_display_posts_shortcode( $atts ) {
129
  $order = sanitize_key( $atts['order'] );
130
  $orderby = sanitize_key( $atts['orderby'] );
131
  $post_parent = $atts['post_parent']; // Validated later, after check for 'current'
 
 
132
  $post_status = $atts['post_status']; // Validated later as one of a few values
133
  $post_type = sanitize_text_field( $atts['post_type'] );
134
  $posts_per_page = intval( $atts['posts_per_page'] );
 
135
  $tag = sanitize_text_field( $atts['tag'] );
136
  $tax_operator = $atts['tax_operator']; // Validated later as one of a few values
137
  $tax_include_children = filter_var( $atts['tax_include_children'], FILTER_VALIDATE_BOOLEAN );
@@ -155,8 +167,9 @@ function be_display_posts_shortcode( $atts ) {
155
  'order' => $order,
156
  'orderby' => $orderby,
157
  'perm' => 'readable',
158
- 'post_type' => explode( ',', $post_type ),
159
  'posts_per_page' => $posts_per_page,
 
160
  'tag' => $tag,
161
  );
162
 
@@ -244,6 +257,10 @@ function be_display_posts_shortcode( $atts ) {
244
  if( $ignore_sticky_posts )
245
  $args['ignore_sticky_posts'] = true;
246
 
 
 
 
 
247
  // Meta key (for ordering)
248
  if( !empty( $meta_key ) )
249
  $args['meta_key'] = $meta_key;
@@ -254,14 +271,14 @@ function be_display_posts_shortcode( $atts ) {
254
 
255
  // If Post IDs
256
  if( $id ) {
257
- $posts_in = array_map( 'intval', explode( ',', $id ) );
258
  $args['post__in'] = $posts_in;
259
  }
260
 
261
  // If Exclude
262
  $post__not_in = array();
263
  if( !empty( $exclude ) ) {
264
- $post__not_in = array_map( 'intval', explode( ',', $exclude ) );
265
  }
266
  if( is_singular() && $exclude_current ) {
267
  $post__not_in[] = get_the_ID();
@@ -278,6 +295,8 @@ function be_display_posts_shortcode( $atts ) {
278
  $args['meta_key'] = 'dps_no_results';
279
  else
280
  $args['author_name'] = $author;
 
 
281
  }
282
 
283
  // Offset
@@ -285,7 +304,7 @@ function be_display_posts_shortcode( $atts ) {
285
  $args['offset'] = $offset;
286
 
287
  // Post Status
288
- $post_status = explode( ', ', $post_status );
289
  $validated = array();
290
  $available = array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash', 'any' );
291
  foreach ( $post_status as $unvalidated )
@@ -307,7 +326,7 @@ function be_display_posts_shortcode( $atts ) {
307
  }
308
  }else{
309
  // Term string to array
310
- $tax_term = explode( ', ', $tax_term );
311
  }
312
 
313
  // Validate operator
@@ -337,7 +356,7 @@ function be_display_posts_shortcode( $atts ) {
337
  // Sanitize values
338
  $more_tax_queries = true;
339
  $taxonomy = sanitize_key( $original_atts['taxonomy_' . $count] );
340
- $terms = explode( ', ', sanitize_text_field( $original_atts['tax_' . $count . '_term'] ) );
341
  $tax_operator = isset( $original_atts['tax_' . $count . '_operator'] ) ? $original_atts['tax_' . $count . '_operator'] : 'IN';
342
  $tax_operator = in_array( $tax_operator, array( 'IN', 'NOT IN', 'AND' ) ) ? $tax_operator : 'IN';
343
  $tax_include_children = isset( $original_atts['tax_' . $count . '_include_children'] ) ? filter_var( $atts['tax_' . $count . '_include_children'], FILTER_VALIDATE_BOOLEAN ) : true;
@@ -373,6 +392,11 @@ function be_display_posts_shortcode( $atts ) {
373
  $args['post_parent'] = intval( $post_parent );
374
  }
375
 
 
 
 
 
 
376
  // Set up html elements used to wrap the posts.
377
  // Default is ul/li, but can also be ol/li and div/div
378
  $wrapper_options = array( 'ul', 'ol', 'div' );
@@ -388,8 +412,9 @@ function be_display_posts_shortcode( $atts ) {
388
  * @param array $args Parsed arguments to pass to WP_Query.
389
  * @param array $original_atts Original attributes passed to the shortcode.
390
  */
391
- $listing = new WP_Query( apply_filters( 'display_posts_shortcode_args', $args, $original_atts ) );
392
- if ( ! $listing->have_posts() ) {
 
393
  /**
394
  * Filter content to display if no posts match the current query.
395
  *
@@ -401,7 +426,7 @@ function be_display_posts_shortcode( $atts ) {
401
  }
402
 
403
  $inner = '';
404
- while ( $listing->have_posts() ): $listing->the_post(); global $post;
405
 
406
  $image = $date = $author = $excerpt = $content = '';
407
 
@@ -425,9 +450,12 @@ function be_display_posts_shortcode( $atts ) {
425
  }
426
 
427
  if ( $include_date ) {
428
- $date = ' <span class="date">' . get_the_date( $date_format ) . '</span>';
429
  } elseif ( $include_date_modified ) {
430
- $date = ' <span class="date">' . get_the_modified_date( $date_format ) . '</span>';
 
 
 
431
  }
432
 
433
  if( $include_author )
@@ -447,14 +475,14 @@ function be_display_posts_shortcode( $atts ) {
447
 
448
  $length = $excerpt_length ? $excerpt_length : apply_filters( 'excerpt_length', 55 );
449
  $more = $excerpt_more ? $excerpt_more : apply_filters( 'excerpt_more', '' );
450
- $more = $excerpt_more_link ? ' <a href="' . get_permalink() . '">' . $more . '</a>' : ' ' . $more;
451
 
452
  if( has_excerpt() && apply_filters( 'display_posts_shortcode_full_manual_excerpt', false ) ) {
453
  $excerpt = $post->post_excerpt . $more;
454
  } elseif( has_excerpt() ) {
455
- $excerpt = wp_trim_words( strip_shortcodes( $post->post_excerpt ), $length, $more );
456
  } else {
457
- $excerpt = wp_trim_words( strip_shortcodes( $post->post_content ), $length, $more );
458
  }
459
 
460
 
@@ -463,8 +491,10 @@ function be_display_posts_shortcode( $atts ) {
463
  $excerpt = get_the_excerpt();
464
  }
465
 
466
- $excerpt = ' <span class="excerpt-dash">-</span> <span class="excerpt">' . $excerpt . '</span>';
467
-
 
 
468
 
469
  }
470
 
@@ -491,7 +521,7 @@ function be_display_posts_shortcode( $atts ) {
491
  *
492
  * @param string $category_display Current Category Display text
493
  */
494
- $category_display_text = apply_filters( 'display_posts_shortcode_category_display', $category_display_text );
495
 
496
  }
497
 
@@ -504,10 +534,10 @@ function be_display_posts_shortcode( $atts ) {
504
  *
505
  * @param array $class Post classes.
506
  * @param WP_Post $post Post object.
507
- * @param WP_Query $listing WP_Query object for the posts listing.
508
  * @param array $original_atts Original attributes passed to the shortcode.
509
  */
510
- $class = array_map( 'sanitize_html_class', apply_filters( 'display_posts_shortcode_post_class', $class, $post, $listing, $original_atts ) );
511
  $output = '<' . $inner_wrapper . ' class="' . implode( ' ', $class ) . '">' . $image . $title . $date . $author . $category_display_text . $excerpt . $content . '</' . $inner_wrapper . '>';
512
 
513
  /**
@@ -524,8 +554,10 @@ function be_display_posts_shortcode( $atts ) {
524
  * @param string $inner_wrapper Type of container to use for the post's inner wrapper element.
525
  * @param string $content The post's content.
526
  * @param string $class Space-separated list of post classes to supply to the $inner_wrapper element.
 
 
527
  */
528
- $inner .= apply_filters( 'display_posts_shortcode_output', $output, $original_atts, $image, $title, $date, $excerpt, $inner_wrapper, $content, $class );
529
 
530
  endwhile; wp_reset_postdata();
531
 
@@ -536,8 +568,9 @@ function be_display_posts_shortcode( $atts ) {
536
  *
537
  * @param string $wrapper_open HTML markup for the opening outer wrapper element.
538
  * @param array $original_atts Original attributes passed to the shortcode.
 
539
  */
540
- $open = apply_filters( 'display_posts_shortcode_wrapper_open', '<' . $wrapper . $wrapper_class . $wrapper_id . '>', $original_atts );
541
 
542
  /**
543
  * Filter the shortcode output's closing outer wrapper element.
@@ -546,8 +579,9 @@ function be_display_posts_shortcode( $atts ) {
546
  *
547
  * @param string $wrapper_close HTML markup for the closing outer wrapper element.
548
  * @param array $original_atts Original attributes passed to the shortcode.
 
549
  */
550
- $close = apply_filters( 'display_posts_shortcode_wrapper_close', '</' . $wrapper . '>', $original_atts );
551
 
552
  $return = '';
553
 
@@ -691,3 +725,93 @@ function be_display_posts_off( $out, $pairs, $atts ) {
691
  $out['display_posts_off'] = apply_filters( 'display_posts_shortcode_inception_override', true );
692
  return $out;
693
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  /**
3
+ * Plugin Name: Display Posts
4
+ * Plugin URI: https://displayposts.com
5
  * Description: Display a listing of posts using the [display-posts] shortcode
6
+ * Version: 3.0.0
7
  * Author: Bill Erickson
8
+ * Author URI: https://www.billerickson.net
9
  *
10
  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
11
  * General Public License version 2, as published by the Free Software Foundation. You may NOT assume
15
  * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
  *
17
  * @package Display Posts
18
+ * @version 2.9.1
19
  * @author Bill Erickson <bill@billerickson.net>
20
  * @copyright Copyright (c) 2011, Bill Erickson
21
  * @link http://www.billerickson.net/shortcode-to-display-posts/
25
 
26
  /**
27
  * To Customize, use the following filters:
28
+ * @link https://displayposts.com/docs/filters/
29
  */
30
 
31
  // Create the shortcode
38
  // Pull in shortcode attributes and set defaults
39
  $atts = shortcode_atts( array(
40
  'author' => '',
41
+ 'author_id' => '',
42
  'category' => '',
43
  'category_display' => '',
44
  'category_id' => false,
58
  'excerpt_more_link' => false,
59
  'exclude' => false,
60
  'exclude_current' => false,
61
+ 'has_password' => null,
62
  'id' => false,
63
  'ignore_sticky_posts' => false,
64
  'image_size' => false,
67
  'include_date' => false,
68
  'include_date_modified'=> false,
69
  'include_excerpt' => false,
70
+ 'include_excerpt_dash' => true,
71
  'include_link' => true,
72
  'include_title' => true,
73
  'meta_key' => '',
77
  'order' => 'DESC',
78
  'orderby' => 'date',
79
  'post_parent' => false,
80
+ 'post_parent__in' => false,
81
+ 'post_parent__not_in' => false,
82
  'post_status' => 'publish',
83
  'post_type' => 'post',
84
  'posts_per_page' => '10',
85
+ 's' => false,
86
  'tag' => '',
87
  'tax_operator' => 'IN',
88
  'tax_include_children' => true,
100
  return;
101
 
102
  $author = sanitize_text_field( $atts['author'] );
103
+ $author_id = intval( $atts['author_id'] );
104
  $category = sanitize_text_field( $atts['category'] );
105
  $category_display = 'true' == $atts['category_display'] ? 'category' : sanitize_text_field( $atts['category_display'] );
106
  $category_id = intval( $atts['category_id'] );
119
  $excerpt_more_link = filter_var( $atts['excerpt_more_link'], FILTER_VALIDATE_BOOLEAN );
120
  $exclude = $atts['exclude']; // Sanitized later as an array of integers
121
  $exclude_current = filter_var( $atts['exclude_current'], FILTER_VALIDATE_BOOLEAN );
122
+ $has_password = null !== $atts['has_password'] ? filter_var( $atts['has_password'], FILTER_VALIDATE_BOOLEAN ) : null;
123
  $id = $atts['id']; // Sanitized later as an array of integers
124
  $ignore_sticky_posts = filter_var( $atts['ignore_sticky_posts'], FILTER_VALIDATE_BOOLEAN );
125
  $image_size = sanitize_key( $atts['image_size'] );
129
  $include_date = filter_var( $atts['include_date'], FILTER_VALIDATE_BOOLEAN );
130
  $include_date_modified= filter_var( $atts['include_date_modified'], FILTER_VALIDATE_BOOLEAN );
131
  $include_excerpt = filter_var( $atts['include_excerpt'], FILTER_VALIDATE_BOOLEAN );
132
+ $include_excerpt_dash = filter_var( $atts['include_excerpt_dash'], FILTER_VALIDATE_BOOLEAN );
133
  $include_link = filter_var( $atts['include_link'], FILTER_VALIDATE_BOOLEAN );
134
  $meta_key = sanitize_text_field( $atts['meta_key'] );
135
  $meta_value = sanitize_text_field( $atts['meta_value'] );
138
  $order = sanitize_key( $atts['order'] );
139
  $orderby = sanitize_key( $atts['orderby'] );
140
  $post_parent = $atts['post_parent']; // Validated later, after check for 'current'
141
+ $post_parent__in = $atts['post_parent__in'];
142
+ $post_parent__not_in = $atts['post_parent__not_in'];
143
  $post_status = $atts['post_status']; // Validated later as one of a few values
144
  $post_type = sanitize_text_field( $atts['post_type'] );
145
  $posts_per_page = intval( $atts['posts_per_page'] );
146
+ $s = sanitize_text_field( $atts['s'] );
147
  $tag = sanitize_text_field( $atts['tag'] );
148
  $tax_operator = $atts['tax_operator']; // Validated later as one of a few values
149
  $tax_include_children = filter_var( $atts['tax_include_children'], FILTER_VALIDATE_BOOLEAN );
167
  'order' => $order,
168
  'orderby' => $orderby,
169
  'perm' => 'readable',
170
+ 'post_type' => be_dps_explode( $post_type ),
171
  'posts_per_page' => $posts_per_page,
172
+ 's' => $s,
173
  'tag' => $tag,
174
  );
175
 
257
  if( $ignore_sticky_posts )
258
  $args['ignore_sticky_posts'] = true;
259
 
260
+ // Password protected content
261
+ if( null !== $has_password )
262
+ $args['has_password'] = $has_password;
263
+
264
  // Meta key (for ordering)
265
  if( !empty( $meta_key ) )
266
  $args['meta_key'] = $meta_key;
271
 
272
  // If Post IDs
273
  if( $id ) {
274
+ $posts_in = array_map( 'intval', be_dps_explode( $id ) );
275
  $args['post__in'] = $posts_in;
276
  }
277
 
278
  // If Exclude
279
  $post__not_in = array();
280
  if( !empty( $exclude ) ) {
281
+ $post__not_in = array_map( 'intval', be_dps_explode( $exclude ) );
282
  }
283
  if( is_singular() && $exclude_current ) {
284
  $post__not_in[] = get_the_ID();
295
  $args['meta_key'] = 'dps_no_results';
296
  else
297
  $args['author_name'] = $author;
298
+ } elseif( !empty( $author_id ) ) {
299
+ $args['author'] = $author_id;
300
  }
301
 
302
  // Offset
304
  $args['offset'] = $offset;
305
 
306
  // Post Status
307
+ $post_status = be_dps_explode( $post_status );
308
  $validated = array();
309
  $available = array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash', 'any' );
310
  foreach ( $post_status as $unvalidated )
326
  }
327
  }else{
328
  // Term string to array
329
+ $tax_term = be_dps_explode( $tax_term );
330
  }
331
 
332
  // Validate operator
356
  // Sanitize values
357
  $more_tax_queries = true;
358
  $taxonomy = sanitize_key( $original_atts['taxonomy_' . $count] );
359
+ $terms = be_dps_explode( sanitize_text_field( $original_atts['tax_' . $count . '_term'] ) );
360
  $tax_operator = isset( $original_atts['tax_' . $count . '_operator'] ) ? $original_atts['tax_' . $count . '_operator'] : 'IN';
361
  $tax_operator = in_array( $tax_operator, array( 'IN', 'NOT IN', 'AND' ) ) ? $tax_operator : 'IN';
362
  $tax_include_children = isset( $original_atts['tax_' . $count . '_include_children'] ) ? filter_var( $atts['tax_' . $count . '_include_children'], FILTER_VALIDATE_BOOLEAN ) : true;
392
  $args['post_parent'] = intval( $post_parent );
393
  }
394
 
395
+ if( $post_parent__in !== false )
396
+ $args['post_parent__in'] = array_map( 'intval', be_dps_explode( $atts['post_parent__in'] ) );
397
+ if( $post_parent__not_in !== false )
398
+ $args['post_parent__not_in'] = array_map( 'intval', be_dps_explode( $atts['post_parent__in'] ) );
399
+
400
  // Set up html elements used to wrap the posts.
401
  // Default is ul/li, but can also be ol/li and div/div
402
  $wrapper_options = array( 'ul', 'ol', 'div' );
412
  * @param array $args Parsed arguments to pass to WP_Query.
413
  * @param array $original_atts Original attributes passed to the shortcode.
414
  */
415
+ global $dps_listing;
416
+ $dps_listing = new WP_Query( apply_filters( 'display_posts_shortcode_args', $args, $original_atts ) );
417
+ if ( ! $dps_listing->have_posts() ) {
418
  /**
419
  * Filter content to display if no posts match the current query.
420
  *
426
  }
427
 
428
  $inner = '';
429
+ while ( $dps_listing->have_posts() ): $dps_listing->the_post(); global $post;
430
 
431
  $image = $date = $author = $excerpt = $content = '';
432
 
450
  }
451
 
452
  if ( $include_date ) {
453
+ $date = 'relative' == $date_format ? be_dps_relative_date( get_the_date( 'U' ) ) : get_the_date( $date_format );
454
  } elseif ( $include_date_modified ) {
455
+ $date = 'relative' == $date_format ? be_dps_relative_date( get_the_modified_time( 'U' ) ) : get_the_modified_date( $date_format );
456
+ }
457
+ if( !empty( $date ) ) {
458
+ $date = ' <span class="date">' . $date . '</span>';
459
  }
460
 
461
  if( $include_author )
475
 
476
  $length = $excerpt_length ? $excerpt_length : apply_filters( 'excerpt_length', 55 );
477
  $more = $excerpt_more ? $excerpt_more : apply_filters( 'excerpt_more', '' );
478
+ $more = $excerpt_more_link ? ' <a class="excerpt-more" href="' . get_permalink() . '">' . $more . '</a>' : ' <span class="excerpt-more">' . $more . '</span>';
479
 
480
  if( has_excerpt() && apply_filters( 'display_posts_shortcode_full_manual_excerpt', false ) ) {
481
  $excerpt = $post->post_excerpt . $more;
482
  } elseif( has_excerpt() ) {
483
+ $excerpt = wp_trim_words( strip_shortcodes( $post->post_excerpt ), $length ) . $more;
484
  } else {
485
+ $excerpt = wp_trim_words( strip_shortcodes( $post->post_content ), $length ) . $more;
486
  }
487
 
488
 
491
  $excerpt = get_the_excerpt();
492
  }
493
 
494
+ $excerpt = '<span class="excerpt">' . $excerpt . '</span>';
495
+ if( $include_excerpt_dash ) {
496
+ $excerpt = '<span class="excerpt-dash">-</span> ' . $excerpt;
497
+ }
498
 
499
  }
500
 
521
  *
522
  * @param string $category_display Current Category Display text
523
  */
524
+ $category_display_text = apply_filters( 'display_posts_shortcode_category_display', $category_display_text, $terms, $category_display, $original_atts );
525
 
526
  }
527
 
534
  *
535
  * @param array $class Post classes.
536
  * @param WP_Post $post Post object.
537
+ * @param WP_Query $dps_listing WP_Query object for the posts listing.
538
  * @param array $original_atts Original attributes passed to the shortcode.
539
  */
540
+ $class = array_map( 'sanitize_html_class', apply_filters( 'display_posts_shortcode_post_class', $class, $post, $dps_listing, $original_atts ) );
541
  $output = '<' . $inner_wrapper . ' class="' . implode( ' ', $class ) . '">' . $image . $title . $date . $author . $category_display_text . $excerpt . $content . '</' . $inner_wrapper . '>';
542
 
543
  /**
554
  * @param string $inner_wrapper Type of container to use for the post's inner wrapper element.
555
  * @param string $content The post's content.
556
  * @param string $class Space-separated list of post classes to supply to the $inner_wrapper element.
557
+ * @param string $author HTML markup for the post's author.
558
+ * @param string $category_display_text
559
  */
560
+ $inner .= apply_filters( 'display_posts_shortcode_output', $output, $original_atts, $image, $title, $date, $excerpt, $inner_wrapper, $content, $class, $author, $category_display_text );
561
 
562
  endwhile; wp_reset_postdata();
563
 
568
  *
569
  * @param string $wrapper_open HTML markup for the opening outer wrapper element.
570
  * @param array $original_atts Original attributes passed to the shortcode.
571
+ * @param object $dps_listing, WP Query object
572
  */
573
+ $open = apply_filters( 'display_posts_shortcode_wrapper_open', '<' . $wrapper . $wrapper_class . $wrapper_id . '>', $original_atts, $dps_listing );
574
 
575
  /**
576
  * Filter the shortcode output's closing outer wrapper element.
579
  *
580
  * @param string $wrapper_close HTML markup for the closing outer wrapper element.
581
  * @param array $original_atts Original attributes passed to the shortcode.
582
+ * @param object $dps_listing, WP Query object
583
  */
584
+ $close = apply_filters( 'display_posts_shortcode_wrapper_close', '</' . $wrapper . '>', $original_atts, $dps_listing );
585
 
586
  $return = '';
587
 
725
  $out['display_posts_off'] = apply_filters( 'display_posts_shortcode_inception_override', true );
726
  return $out;
727
  }
728
+
729
+ /**
730
+ * Explode list using "," and ", "
731
+ *
732
+ */
733
+ function be_dps_explode( $string = '' ) {
734
+
735
+ $string = str_replace( ', ', ',', $string );
736
+ return explode( ',', $string );
737
+ }
738
+
739
+ /**
740
+ * Relative date
741
+ *
742
+ */
743
+ function be_dps_relative_date( $date ) {
744
+ return human_time_diff( $date ) . ' ' . __( 'ago', 'display-posts' );
745
+ }
746
+
747
+ /**
748
+ * Survey admin notice
749
+ *
750
+ */
751
+ function be_dps_survey_admin_notice() {
752
+
753
+ if( ! is_super_admin() )
754
+ return;
755
+
756
+
757
+ $survey = get_option( 'display_posts_survey' );
758
+ $time = time();
759
+ $load = false;
760
+ if ( ! $survey ) {
761
+ $survey = array(
762
+ 'time' => $time,
763
+ 'dismissed' => false,
764
+ );
765
+ update_option( 'display_posts_survey', $survey );
766
+ } else {
767
+ // Check if it has been dismissed or not.
768
+ if ( ( isset( $survey['dismissed'] ) && ! $survey['dismissed'] ) ) {
769
+ $load = true;
770
+ }
771
+ }
772
+ // If we cannot load, return early.
773
+ if ( ! $load ) {
774
+ return;
775
+ }
776
+
777
+
778
+ ?>
779
+ <div class="notice notice-info is-dismissible display-posts-survey-notice">
780
+ <p><?php esc_html_e( 'Thank you so much for using Display Posts! Could you please do me a BIG favor and answer four quick questions on how I can improve the plugin for you?', 'display-posts' ); ?></p>
781
+ <p><?php esc_html_e( 'In 2019 I\'ll be working on new features, including the possibility of a premium version. As a valued Display Posts user, your feedback is important and appreciated!', 'display-posts' ); ?></p>
782
+ <p><strong><?php echo wp_kses( __( '~ Bill Erickson<br>Developer of Display Posts', 'display-posts' ), array( 'br' => array() ) ); ?></strong></p>
783
+ <p>
784
+ <a href="https://displayposts.com/user-survey?utm_source=displaypostsplugin&utm_medium=link&utm_campaign=survey_notice" class="display-posts-dismiss-survey-notice display-posts-survey-out" target="_blank" rel="noopener"><?php esc_html_e( 'Yes, I will!', 'display-posts' ); ?></a><br>
785
+ <a href="#" class="display-posts-dismiss-survey-notice" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Nope, maybe later', 'display-posts' ); ?></a><br>
786
+ <a href="#" class="display-posts-dismiss-survey-notice" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'I already did', 'display-posts' ); ?></a>
787
+ </p>
788
+ </div>
789
+ <script type="text/javascript">
790
+ jQuery( document ).ready( function ( $ ) {
791
+ $( document ).on( 'click', '.display-posts-dismiss-survey-notice, .display-posts-survey-notice button', function ( event ) {
792
+ if ( ! $( this ).hasClass( 'display-posts-survey-out' ) ) {
793
+ event.preventDefault();
794
+ }
795
+ $.post( ajaxurl, {
796
+ action: 'display_posts_survey_dismiss'
797
+ } );
798
+ $( '.display-posts-survey-notice' ).remove();
799
+ } );
800
+ } );
801
+ </script>
802
+ <?php
803
+ }
804
+ add_action( 'admin_notices', 'be_dps_survey_admin_notice' );
805
+
806
+ /**
807
+ * Dismiss the admin notice
808
+ *
809
+ */
810
+ function be_dps_survey_dismiss() {
811
+
812
+ $survey = get_option( 'display_posts_survey', array() );
813
+ $survey['time'] = time();
814
+ $survey['dismissed'] = true;
815
+ update_option( 'display_posts_survey', $survey );
816
+ }
817
+ add_action( 'wp_ajax_display_posts_survey_dismiss', 'be_dps_survey_dismiss' );
readme.txt CHANGED
@@ -1,35 +1,86 @@
1
- === Display Posts Shortcode ===
2
  Contributors: billerickson
3
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MQKRBRFVRUV8C
4
  Tags: shortcode, pages, posts, page, query, display, list
5
  Requires at least: 3.0
6
- Tested up to: 4.8
7
- Stable tag: 2.9.0
8
 
9
- Display a listing of posts using the [display-posts] shortcode
10
 
11
  == Description ==
12
 
13
- The *Display Posts Shortcode* was written to allow users to easily display listings of posts without knowing PHP or editing template files.
14
 
15
- Add the shortcode in a post or page, and use the arguments to query based on tag, category, post type, and many other possibilities. You can also customize the output with parameters like: include_date, include_excerpt, and image_size.
16
 
17
- * [Available Parameters](https://github.com/billerickson/display-posts-shortcode/blob/master/README.md#parameters)
18
- * [Customization with Filters](https://github.com/billerickson/display-posts-shortcode/wiki#customization-with-filters)
19
- * [Extension Plugins](https://github.com/billerickson/display-posts-shortcode/wiki#extension-plugins)
20
- * [Full Change Log](https://github.com/billerickson/display-posts-shortcode/blob/master/CHANGELOG.md)
21
- * [View on GitHub](https://github.com/billerickson/display-posts-shortcode)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  == Installation ==
25
 
26
  1. Upload `display-posts-shortcode` to the `/wp-content/plugins/` directory.
27
  1. Activate the plugin through the *Plugins* menu in WordPress.
28
- 1. Add the shortcode to a post or page.
29
 
30
 
31
  == Changelog ==
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  **Version 2.9.0**
34
  * New parameter `exclude` for excluding specific post IDs, see [#154](https://github.com/billerickson/display-posts-shortcode/issues/154)
35
  * New parameter `category_id` for specifying category by ID (note: only accepts a single ID), see [#156](https://github.com/billerickson/display-posts-shortcode/issues/156)
1
+ === Display Posts - Easy lists, grids, navigation, and more ===
2
  Contributors: billerickson
 
3
  Tags: shortcode, pages, posts, page, query, display, list
4
  Requires at least: 3.0
5
+ Tested up to: 5.0
6
+ Stable tag: 3.0.0
7
 
8
+ Add a listing of content on your website using a simple shortcode. Filter the results by category, author, and more.
9
 
10
  == Description ==
11
 
12
+ Display Posts allows you easily list content from all across your website. Start by adding this shortcode in the content editor to display a list of your most recent posts:
13
 
14
+ `[display-posts]`
15
 
16
+ **Filter by Category**
17
+
18
+ To only show posts within a certain category, use the category parameter:
19
+
20
+ `[display-posts category="news"]`
21
+
22
+ **Display as Post Grid**
23
+
24
+ You can create a great looking, column-based grid of posts with a bit of styling. [Here's how!](https://displayposts.com/2019/01/04/post-grid-styling/)
25
+
26
+ **List Popular Posts**
27
+ You can highlight your popular content in multiple ways. If you want to feature the posts with the most comments, use:
28
+
29
+ `[display-posts orderby="comment_count"]`
30
+
31
+ You can also list [most popular posts by social shares](https://displayposts.com/2019/01/04/most-popular-posts-by-social-shares/).
32
+
33
+ **Include thumbnails, excerpts, and more**
34
+ The [display parameters](https://displayposts.com/docs/parameters/#display-parameters) let you control what information is displayed for each post. To include an image and summary, use:
35
+
36
+ `[display-posts include_excerpt="true" image_size="thumbnail"]`
37
+
38
+ You can use any image size added by WordPress (thumbnail, medium, medium_large, large) OR any custom image size added by your theme or other plugins.
39
+
40
+ **Sort the list however you like**
41
+ By default the listing will list the newest content first, but you can order by title, menu order, relevance, content type, metadata, and more.
42
+
43
+ **List upcoming events**
44
+ You can easily list upcoming events from any event calendar. Each plugin will require slightly different code.
45
+
46
+ Here are [tutorials for popular event calendar plugins](https://displayposts.com/tag/events/). If your plugin is not listed here, submit a support request and I'll add it!
47
+
48
+ **Tutorials**
49
+ [Our tutorials](https://displayposts.com/tutorials/) cover common customization requests, and are updated often.
50
+
51
+ **Full Documentation**
52
+
53
+ * [Query parameters](https://displayposts.com/docs/parameters/#query-parameters) for customizing which posts are listed (filter by category, tag, date...)
54
+ * [Display parameters](https://displayposts.com/docs/parameters/#display-parameters) determine how the posts appear (title, excerpt, image...)
55
+ * [Template parts](https://displayposts.com/2019/01/04/use-template-parts-to-match-your-themes-styling/) for Display Posts to perfectly match your theme's post listings
56
+ * [Output filter](https://displayposts.com/docs/the-output-filter/) for complete control over how the listing looks on your site
57
+ * [Filters](https://displayposts.com/docs/parameters/#display-parameters) for even more powerful customizations for developers
58
 
59
 
60
  == Installation ==
61
 
62
  1. Upload `display-posts-shortcode` to the `/wp-content/plugins/` directory.
63
  1. Activate the plugin through the *Plugins* menu in WordPress.
64
+ 1. Add the `[display-posts]` shortcode to a post or page.
65
 
66
 
67
  == Changelog ==
68
 
69
+ **Version 3.0.0**
70
+ * Added author_id parameter, see [#195](https://github.com/billerickson/display-posts-shortcode/issues/195)
71
+ * Added has_password parameter
72
+ * Added s parameter for performing a site search, see [#184](https://github.com/billerickson/display-posts-shortcode/issues/184)
73
+ * Added date_format="relative" format option (ex: 2 days ago), see [#194](https://github.com/billerickson/display-posts-shortcode/issues/194)
74
+ * Added post_parent__in and post_parent__not_in parameters, see [#193](https://github.com/billerickson/display-posts-shortcode/issues/193)
75
+ * Added excerpt_dash="false" option to disable dash in excerpt, see [#204](https://github.com/billerickson/display-posts-shortcode/issues/204)
76
+ * Added additional parameters to the `display_posts_shortcode_output` filter
77
+ * Added additional parameters to the `display_posts_shortcode_category_display` filter, see [#185](https://github.com/billerickson/display-posts-shortcode/issues/185)
78
+ * $dps_listing loop now accessible globally, see [#198](https://github.com/billerickson/display-posts-shortcode/issues/198)
79
+ * $dps_listing loop now accessible in open/close filters
80
+ * Added .excerpt-more class to excerpt more text, see [#205](https://github.com/billerickson/display-posts-shortcode/issues/205)
81
+ * Now excerpt_more text is always appended to end of excerpt, see [#197](https://github.com/billerickson/display-posts-shortcode/issues/197)
82
+ * In parameters that support multiple terms, they can now be separated with a comma or comma-space, see [#183](https://github.com/billerickson/display-posts-shortcode/issues/183)
83
+
84
  **Version 2.9.0**
85
  * New parameter `exclude` for excluding specific post IDs, see [#154](https://github.com/billerickson/display-posts-shortcode/issues/154)
86
  * New parameter `category_id` for specifying category by ID (note: only accepts a single ID), see [#156](https://github.com/billerickson/display-posts-shortcode/issues/156)