Changeset 2849072
- Timestamp:
- 01/16/2023 10:46:12 AM (19 months ago)
- Location:
- list-pages-shortcode/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
list-pages-shortcode/trunk/list-pages-shortcode.php
r2846366 r2849072 1 1 <?php 2 2 3 /* 4 Plugin Name: List Pages Shortcode5 Plugin URI: http://wordpress.org/extend/plugins/list-pages-shortcode/6 Description: Introduces the [list-pages], [sibling-pages] and [child-pages] <a href="http://codex.wordpress.org/Shortcode_API">shortcodes</a> for easily displaying a list of pages within a post or page. Both shortcodes accept all parameters that you can pass to the <a href="http://codex.wordpress.org/Template_Tags/wp_list_pages">wp_list_pages()</a> function. For example, to show a page's child pages sorted by title simply add [child-pages sort_column="post_title"] in the page's content.7 Author: Ben Huson, Aaron Harp8 Version: 1.7.5 9 Author URI: http://www.aaronharp.com10 */3 /* 4 Plugin Name: List Pages Shortcode 5 Plugin URI: http://wordpress.org/extend/plugins/list-pages-shortcode/ 6 Description: Introduces the [list-pages], [sibling-pages] and [child-pages] <a href="http://codex.wordpress.org/Shortcode_API">shortcodes</a> for easily displaying a list of pages within a post or page. Both shortcodes accept all parameters that you can pass to the <a href="http://codex.wordpress.org/Template_Tags/wp_list_pages">wp_list_pages()</a> function. For example, to show a page's child pages sorted by title simply add [child-pages sort_column="post_title"] in the page's content. 7 Author: Ben Huson, Aaron Harp 8 * Version: 1.7.6 9 Author URI: http://www.aaronharp.com 10 */ 11 11 12 12 add_shortcode( 'child-pages', array( 'List_Pages_Shortcode', 'shortcode_list_pages' ) ); … … 25 25 } 26 26 27 static function shortcode_list_pages( $atts, $content, $tag ) { 27 public static function shortcode_list_pages( $atts, $content, $tag ) { 28 28 29 global $post; 29 30 31 32 33 30 34 do_action( 'shortcode_list_pages_before', $atts, $content, $tag ); 31 35 32 // Child Pages 33 $child_of = 0; 34 if ( $tag == 'child-pages' ) { 35 $child_of = $post->ID; 36 } 37 if ( $tag == 'sibling-pages' ) { 38 $child_of = $post->post_parent; 39 } 40 41 // Set defaults 36 // Catch <ul> tags in wp_list_pages(). 37 if ( 'ul' !== $atts['list_type'] ) { 38 add_filter( 'wp_list_pages', array( 'List_Pages_Shortcode', 'ul2list_type' ), 10, 2 ); 39 } 40 41 // Create output. 42 $atts = self::prepare_list_pages_atts( $atts, $tag ); 43 $out = wp_list_pages( $atts ); 44 remove_filter( 'wp_list_pages', array( 'List_Pages_Shortcode', 'ul2list_type' ), 10 ); 45 if ( ! empty( $out ) && ! empty( $atts['list_type'] ) ) { 46 $out = '<' . sanitize_key( $atts['list_type'] ) . ' class="' . esc_attr( $atts['class'] ) . '">' . $out . '</' . sanitize_key( $atts['list_type'] ) . '>'; 47 } 48 $out = apply_filters( 'shortcode_list_pages', $out, $atts, $content, $tag ); 49 50 do_action( 'shortcode_list_pages_after', $atts, $content, $tag ); 51 52 return $out; 53 54 } 55 56 protected static function parse_shortcode_atts( $atts, $tag ) { 57 58 // Allowed shortcode attributes. 42 59 $defaults = array( 43 60 'class' => 'list-pages-shortcode ' . $tag, … … 47 64 'exclude' => '', 48 65 'include' => '', 49 'child_of' => $child_of,66 'child_of' => , 50 67 'list_type' => 'ul', 51 68 'title_li' => '', … … 58 75 'meta_key' => '', 59 76 'meta_value' => '', 60 'walker' => new List_Pages_Shortcode_Walker_Page,61 77 'post_type' => 'page', 62 78 'offset' => '', 63 'post_status' => 'publish',64 79 'exclude_current_page' => 0, 65 'excerpt' => 0 80 'excerpt' => 0 66 81 ); 67 82 68 // Merge user provided atts with defaults69 83 $atts = shortcode_atts( $defaults, $atts ); 70 $atts['title_li'] = html_entity_decode( $atts['title_li'] ); 71 72 // Set necessary params 84 85 // Validate/sanitize attributes. 86 $atts['class'] = self::sanitize_html_classes( $atts['class'] ); 87 $atts['depth'] = absint( $atts['depth'] ); 88 $atts['show_date'] = sanitize_text_field( $atts['show_date'] ); 89 $atts['date_format'] = sanitize_text_field( $atts['date_format'] ); 90 $atts['exclude'] = '' !== $atts['exclude'] ? self::sanitize_absints_string( $atts['exclude'] ) : ''; 91 $atts['include'] = '' !== $atts['include'] ? self::sanitize_absints_string( $atts['include'] ) : ''; 92 $atts['child_of'] = absint( $atts['child_of'] ); 93 $atts['list_type'] = self::validate_list_type( $atts['list_type'] ); 94 $atts['title_li'] = '' !== $atts['title_li'] ? wp_kses_post( $atts['title_li'] ) : ''; 95 $atts['authors'] = '' !== $atts['authors'] ? self::sanitize_absints_string( $atts['authors'] ) : ''; 96 $atts['sort_column'] = self::validate_sort_column( $atts['sort_column'] ); 97 $atts['sort_order'] = 'DESC' === strtoupper( $atts['sort_order'] ) ? 'DESC' : 'ASC'; 98 $atts['link_before'] = '' !== $atts['link_before'] ? wp_kses_post( $atts['link_before'] ) : ''; 99 $atts['link_after'] = '' !== $atts['link_after'] ? wp_kses_post( $atts['link_after'] ) : ''; 100 $atts['exclude_tree'] = '' !== $atts['exclude_tree'] ? self::sanitize_absints_string( $atts['exclude_tree'] ) : ''; 101 $atts['meta_key'] = sanitize_key( $atts['meta_key'] ); 102 $atts['meta_value'] = sanitize_text_field( $atts['meta_value'] ); 103 $atts['post_type'] = self::validate_post_type( $atts['post_type'] ); 104 $atts['offset'] = absint( $atts['offset'] ); 105 $atts['exclude_current_page'] = absint( $atts['exclude_current_page'] ); 106 $atts['excerpt'] = absint( $atts['excerpt'] ); 107 108 // Extra attributes. 109 $atts['walker'] = new List_Pages_Shortcode_Walker_Page(); 110 111 return $atts; 112 113 } 114 115 protected static function prepare_list_pages_atts( $atts, $tag ) { 116 117 global $post; 118 119 // Don't echo list pages output. 73 120 $atts['echo'] = 0; 121 122 74 123 if ( $atts['exclude_current_page'] && absint( $post->ID ) ) { 75 124 if ( ! empty( $atts['exclude'] ) ) { 76 125 $atts['exclude'] .= ','; 77 126 } 78 $atts['exclude'] .= $post->ID; 79 } 80 81 $atts = apply_filters( 'shortcode_list_pages_attributes', $atts, $content, $tag ); 82 83 $classes = explode( ' ', $atts['class'] ); 84 $atts['class'] = implode( ' ', array_map( 'sanitize_html_class', $classes ) ); 85 86 // Catch <ul> tags in wp_list_pages() 87 $atts['list_type'] = self::validate_list_type( $atts['list_type'] ); 88 if ( 'ul' != $atts['list_type'] ) { 89 add_filter( 'wp_list_pages', array( 'List_Pages_Shortcode', 'ul2list_type' ), 10, 2 ); 90 } 91 92 // Create output 93 $list_pages_atts = $atts; 94 if ( empty( $list_pages_atts['list_type'] ) ) { 95 $list_pages_atts['list_type'] = 'ul'; 96 } 97 $out = wp_list_pages( $list_pages_atts ); 98 remove_filter( 'wp_list_pages', array( 'List_Pages_Shortcode', 'ul2list_type' ), 10 ); 99 if ( ! empty( $out ) && ! empty( $atts['list_type'] ) ) { 100 $out = '<' . $atts['list_type'] . ' class="' . esc_attr( $atts['class'] ) . '">' . $out . '</' . $atts['list_type'] . '>'; 101 } 102 $out = apply_filters( 'shortcode_list_pages', $out, $atts, $content, $tag ); 103 104 do_action( 'shortcode_list_pages_after', $atts, $content, $tag ); 105 106 return $out; 127 $atts['exclude'] .= absint( $post->ID ); 128 } 129 130 return $atts; 131 132 } 133 134 protected static function sanitize_html_classes( $class ) { 135 136 $class = array_map( 'sanitize_html_class', explode( ' ', $class ) ); 137 138 return implode( ' ', $class ); 139 140 } 141 142 protected static function sanitize_absints_string( $value ) { 143 144 if ( '' !== $value ) { 145 $values = explode( ',', $value ); 146 $values = array_map( 'absint', array_map( 'trim', $values ) ); 147 return implode( ',', array_filter( $values ) ); 148 } 149 150 return $value; 151 152 } 153 154 protected static function validate_sort_column( $sort_column ) { 155 156 $valid_columns = array( 157 'post_author', 158 'post_date', 159 'post_title', 160 'post_name', 161 'post_modified', 162 'post_modified_gmt', 163 'menu_order', 164 'post_parent', 165 'ID', 166 'rand', 167 'comment_count', 168 'post_title', 169 ); 170 171 if ( in_array( $sort_column, $valid_columns ) ) { 172 return $sort_column; 173 } 174 175 return 'post_title'; 176 177 } 178 179 protected static function validate_post_type( $post_type ) { 180 181 $post_type = sanitize_key( $post_type ); 182 183 if ( post_type_exists( $post_type ) && is_post_type_viewable( $post_type ) ) { 184 return $post_type; 185 } 186 187 return ''; 188 189 } 190 191 protected static function get_default_child_of( $tag ) { 192 193 $post = get_post(); 194 195 if ( 'child-pages' === $tag ) { 196 return $post->ID; 197 } elseif ( 'sibling-pages' === $tag ) { 198 return $post->post_parent; 199 } 200 201 return 0; 202 107 203 } 108 204 … … 111 207 * Replaces all <ul> tags with <{list_type}> tags. 112 208 * 113 * @param string $output Output of wp_list_pages().114 * @param array$args shortcode_list_pages() args.209 * @param string $output Output of wp_list_pages(). 210 * @param $args shortcode_list_pages() args. 115 211 * @return string HTML output. 116 212 */ 117 static function ul2list_type( $output, $args = null ) {213 static function ul2list_type( $output, $args = null ) { 118 214 119 215 $list_type = self::validate_list_type( $args['list_type'] ); 120 216 121 if ( 'ul' != $list_type ) {217 if ( 'ul' != $list_type ) { 122 218 123 219 // <ul> … … 127 223 128 224 // <li> 129 $list_type = 'span' == $list_type ? 'span' : 'div'; 130 $output = str_replace( '<li>', '<' . $list_type . '>', $output ); 131 $output = str_replace( '<li ', '<' . $list_type . ' ', $output ); 132 $output = str_replace( '</li> ', '</' . $list_type . '>', $output ); 225 if ( 'ol' !== $list_type ) { 226 $list_type = 'span' === $list_type ? 'span' : 'div'; 227 $output = str_replace( '<li>', '<' . $list_type . '>', $output ); 228 $output = str_replace( '<li ', '<' . $list_type . ' ', $output ); 229 $output = str_replace( '</li> ', '</' . $list_type . '>', $output ); 230 } 133 231 134 232 } … … 142 240 * Add a <div> around the excerpt by default. 143 241 * 144 * @param string $ excerpt Excerpt.242 * @param string $t Excerpt. 145 243 * @return string Filtered excerpt. 146 244 */ 147 static function excerpt_filter( $text ) {245 static function excerpt_filter( $text ) { 148 246 if ( ! empty( $text ) ) { 149 247 return ' <div class="excerpt">' . wp_kses( $text, 'post' ) . '</div>'; … … 155 253 * Validate List Type 156 254 * 157 * @param string$list_type List type tag.158 * @return 255 * @param $list_type List type tag. 256 * @return string Valid tag. 159 257 */ 160 258 public static function validate_list_type( $list_type ) { 161 259 162 if ( empty( $list_type ) || ! in_array( $list_type, array( 'ul', 'div', 'span', 'article', 'aside', 'section' )) ) {163 $list_type = 'ul';164 } 165 166 return $list_type;260 if ( ) ) { 261 ; 262 } 263 264 return ; 167 265 168 266 } … … 181 279 * 182 280 * @param string $output Passed by reference. Used to append additional content. 183 * @param int $depth Depth of page. Used for padding.184 */ 185 function start_lvl( &$output, $depth = 0, $args = array() ) {186 $indent = str_repeat( "\t", $depth );281 * @param int $depth Depth of page. Used for padding. 282 */ 283 function start_lvl( &$output, $depth = 0, $args = array() ) { 284 $indent = str_repeat( "\t", $depth ); 187 285 $list_type = List_Pages_Shortcode::validate_list_type( $args['list_type'] ); 188 $output .= "\n$indent<" . $list_type . " class='children'>\n";286 $output .= "\n$indent<" . $list_type . " class='children'>\n"; 189 287 } 190 288 … … 194 292 * 195 293 * @param string $output Passed by reference. Used to append additional content. 196 * @param int $depth Depth of page. Used for padding.197 */ 198 function end_lvl( &$output, $depth = 0, $args = array() ) {199 $indent = str_repeat( "\t", $depth );294 * @param int $depth Depth of page. Used for padding. 295 */ 296 function end_lvl( &$output, $depth = 0, $args = array() ) { 297 $indent = str_repeat( "\t", $depth ); 200 298 $list_type = List_Pages_Shortcode::validate_list_type( $args['list_type'] ); 201 $output .= "$indent</" . $list_type . ">\n";299 $output .= "$indent</" . $list_type . ">\n"; 202 300 } 203 301 … … 208 306 * @param string $output Passed by reference. Used to append additional content. 209 307 * @param object $page Page data object. 210 * @param int $depth Depth of page. Used for padding.211 * @param int $current_page Page ID.212 * @param array $args213 */ 214 function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {308 * @param int $depth Depth of page. Used for padding. 309 * @param 310 * @param 311 */ 312 function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { 215 313 if ( $depth ) { 216 314 $indent = str_repeat( "\t", $depth ); … … 219 317 } 220 318 221 extract( $args, EXTR_SKIP );222 319 $css_class = array( 'page_item', 'page-item-' . $page->ID ); 223 320 … … 228 325 if ( ! empty( $current_page ) ) { 229 326 $_current_page = get_page( $current_page ); 230 if ( in_array( $page->ID, $_current_page->ancestors ) ) {327 if ( in_array( $page->ID, $_current_page->ancestors ) ) { 231 328 $css_class[] = 'current_page_ancestor'; 232 329 } 233 if ( $page->ID == $current_page ) {330 if ( $page->ID == $current_page ) { 234 331 $css_class[] = 'current_page_item'; 235 } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {332 } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) { 236 333 $css_class[] = 'current_page_parent'; 237 334 } 238 } elseif ( $page->ID == get_option( 'page_for_posts' )) {335 } elseif ( ) { 239 336 $css_class[] = 'current_page_parent'; 240 337 } … … 246 343 } 247 344 248 $item = '<a href="' . get_permalink( $page->ID ) . '">' . $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after . '</a>'; 249 250 if ( ! empty( $show_date ) ) { 251 if ( 'modified' == $show_date ) { 345 $args['link_before'] = empty( $args['link_before'] ) ? '' : wp_kses_post( $args['link_before'] ); 346 $args['link_after'] = empty( $args['link_after'] ) ? '' : wp_kses_post( $args['link_after'] ); 347 348 $item = '<a href="' . get_permalink( $page->ID ) . '">' . $args['link_before'] . apply_filters( 'the_title', $page->post_title, $page->ID ) . $args['link_after'] . '</a>'; 349 350 if ( ! empty( $args['show_date'] ) ) { 351 if ( 'modified' === $args['show_date'] ) { 252 352 $time = $page->post_modified; 253 353 } else { … … 255 355 } 256 356 257 $item .= ' ' . mysql2date( $date_format, $time ); 258 } 259 260 // Excerpt 357 $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; 358 $item .= ' ' . mysql2date( $date_format, $time ); 359 } 360 361 // Excerpt. 261 362 if ( $args['excerpt'] ) { 262 363 $item .= apply_filters( 'list_pages_shortcode_excerpt', $page->post_excerpt, $page, $depth, $args, $current_page ); 263 364 } 264 365 265 $output .= $indent . '<li class="' . $css_class. '">' . apply_filters( 'list_pages_shortcode_item', $item, $page, $depth, $args, $current_page );366 $output .= $indent . '<li class="' . . '">' . apply_filters( 'list_pages_shortcode_item', $item, $page, $depth, $args, $current_page ); 266 367 } 267 368 -
list-pages-shortcode/trunk/readme.txt
r2846366 r2849072 3 3 Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=aaron%40freshwebs%2enet&item_name=Fotobook%20Donation&no_shipping=0&no_note=1&tax=0¤cy_code=USD&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8 4 4 Tags: shortcodes, pages, list pages, sibling pages, child pages, subpages 5 Requires at least: 3.55 Requires at least: 6 6 Tested up to: 6.1.1 7 Stable tag: 1.7. 57 Stable tag: 1.7. 8 8 License: GPLv2 or later 9 9 … … 70 70 71 71 == Changelog == 72 73 74 75 72 76 73 77 = 1.7.5 = … … 140 144 == Upgrade Notice == 141 145 146 147 148 149 142 150 = 1.7.5 = 143 151
Note: See TracChangeset
for help on using the changeset viewer.