- Timestamp:
- 09/30/2019 05:40:14 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-content/themes/twentytwenty/inc/template-tags.php
r46271 r46357 16 16 */ 17 17 18 if ( ! function_exists( 'twentytwenty_site_logo' ) ) { 18 /** 19 * Displays the site logo, either text or image. 20 * 21 * @param array $args Arguments for displaying the site logo either as an image or text. 22 * @param boolean $echo Echo or return the html. 23 */ 24 function twentytwenty_site_logo( $args = array(), $echo = true ) { 25 $logo = get_custom_logo(); 26 $site_title = get_bloginfo( 'name' ); 27 $contents = ''; 28 $classname = ''; 29 30 $defaults = array( 31 'logo' => '%1$s<span class="screen-reader-text">%2$s</span>', 32 'logo_class' => 'site-logo', 33 'title' => '<a href="%1$s">%2$s</a>', 34 'title_class' => 'site-title', 35 'home_wrap' => '<h1 class="%1$s">%2$s</h1>', 36 'single_wrap' => '<div class="%1$s faux-heading">%2$s</div>', 37 'condition' => ( is_front_page() || is_home() ) && ! is_page(), 38 ); 39 40 $args = wp_parse_args( $args, $defaults ); 41 19 42 /** 20 * Displays the site logo, either text or image.21 * 22 * @param array $args Arguments for displaying the site logo either as an image or text.23 * @param boolean $echo Echo or return the html.43 * Filters the arguments for `twentytwenty_site_logo()`. 44 * 45 * @param array $args Parsed arguments. 46 * @param array $defaults Function's default arguments. 24 47 */ 25 function twentytwenty_site_logo( $args = array(), $echo = true ) { 26 $logo = get_custom_logo(); 27 $site_title = get_bloginfo( 'name' ); 28 $contents = ''; 29 $classname = ''; 30 31 $defaults = array( 32 'logo' => '%1$s<span class="screen-reader-text">%2$s</span>', 33 'logo_class' => 'site-logo', 34 'title' => '<a href="%1$s">%2$s</a>', 35 'title_class' => 'site-title', 36 'home_wrap' => '<h1 class="%1$s">%2$s</h1>', 37 'single_wrap' => '<div class="%1$s faux-heading">%2$s</div>', 38 'condition' => is_front_page() || is_home(), 48 $args = apply_filters( 'twentytwenty_site_logo_args', $args, $defaults ); 49 50 if ( has_custom_logo() ) { 51 $contents = sprintf( $args['logo'], $logo, esc_html( $site_title ) ); 52 $classname = $args['logo_class']; 53 } else { 54 $contents = sprintf( $args['title'], esc_url( get_home_url( null, '/' ) ), esc_html( $site_title ) ); 55 $classname = $args['title_class']; 56 } 57 58 $wrap = $args['condition'] ? 'home_wrap' : 'single_wrap'; 59 60 $html = sprintf( $args[ $wrap ], $classname, $contents ); 61 62 /** 63 * Filters the arguments for `twentytwenty_site_logo()`. 64 * 65 * @param string $html Compiled html based on our arguments. 66 * @param array $args Parsed arguments. 67 * @param string $classname Class name based on current view, home or single. 68 * @param string $contents HTML for site title or logo. 69 */ 70 $html = apply_filters( 'twentytwenty_site_logo', $html, $args, $classname, $contents ); 71 72 if ( ! $echo ) { 73 return $html; 74 } 75 76 echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 77 78 } 79 80 /** 81 * Displays the site description. 82 * 83 * @param boolean $echo Echo or return the html. 84 */ 85 function twentytwenty_site_description( $echo = true ) { 86 $description = get_bloginfo( 'description' ); 87 88 if ( ! $description ) { 89 return; 90 } 91 92 $wrapper = '<div class="site-description">%s</div><!-- .site-description -->'; 93 94 $html = sprintf( $wrapper, esc_html( $description ) ); 95 96 /** 97 * Filters the html for the site description. 98 * 99 * @since 1.0.0 100 * 101 * @param string $html The HTML to display. 102 * @param string $description Site description via `bloginfo()`. 103 * @param string $wrapper The format used in case you want to reuse it in a `sprintf()`. 104 */ 105 $html = apply_filters( 'twentytwenty_site_description', $html, $description, $wrapper ); 106 107 if ( ! $echo ) { 108 return $html; 109 } 110 111 echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 112 } 113 114 /** 115 * Comments 116 */ 117 /** 118 * Check if the specified comment is written by the author of the post commented on. 119 * 120 * @param object $comment Comment data. 121 */ 122 function twentytwenty_is_comment_by_post_author( $comment = null ) { 123 124 if ( is_object( $comment ) && $comment->user_id > 0 ) { 125 126 $user = get_userdata( $comment->user_id ); 127 $post = get_post( $comment->comment_post_ID ); 128 129 if ( ! empty( $user ) && ! empty( $post ) ) { 130 131 return $comment->user_id === $post->post_author; 132 133 } 134 } 135 return false; 136 137 } 138 139 /** 140 * Filter comment reply link to not JS scroll. 141 * Filter the comment reply link to add a class indicating it should not use JS slow-scroll, as it 142 * makes it scroll to the wrong position on the page. 143 * 144 * @param string $link Link to the top of the page. 145 */ 146 function twentytwenty_filter_comment_reply_link( $link ) { 147 148 $link = str_replace( 'class=\'', 'class=\'do-not-scroll ', $link ); 149 return $link; 150 151 } 152 153 add_filter( 'comment_reply_link', 'twentytwenty_filter_comment_reply_link' ); 154 155 /** 156 * Post Meta 157 */ 158 /** 159 * Get and Output Post Meta. 160 * If it's a single post, output the post meta values specified in the Customizer settings. 161 * 162 * @param int $post_id The ID of the post for which the post meta should be output. 163 * @param string $location Which post meta location to output – single or preview. 164 */ 165 function twentytwenty_the_post_meta( $post_id = null, $location = 'single-top' ) { 166 167 echo twentytwenty_get_post_meta( $post_id, $location ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in twentytwenty_get_post_meta(). 168 169 } 170 171 /** 172 * Get the post meta. 173 * 174 * @param int $post_id The iD of the post. 175 * @param string $location The location where the meta is shown. 176 */ 177 function twentytwenty_get_post_meta( $post_id = null, $location = 'single-top' ) { 178 179 // Require post ID. 180 if ( ! $post_id ) { 181 return; 182 } 183 184 $page_template = get_page_template_slug( $post_id ); 185 186 /** 187 * Filters post types array 188 * 189 * This filter can be used to hide post meta information of post, page or custom post type registerd by child themes or plugins 190 * 191 * @since 1.0.0 192 * 193 * @param array Array of post types 194 */ 195 $disallowed_post_types = apply_filters( 'twentytwenty_disallowed_post_types_for_meta_output', array( 'page' ) ); 196 // Check whether the post type is allowed to output post meta. 197 if ( in_array( get_post_type( $post_id ), $disallowed_post_types, true ) ) { 198 return; 199 } 200 201 $post_meta_wrapper_classes = ''; 202 $post_meta_classes = ''; 203 204 // Get the post meta settings for the location specified. 205 if ( 'single-top' === $location ) { 206 /** 207 * Filters post meta info visibility 208 * 209 * Use this filter to hide post meta information like Author, Post date, Comments, Is stiky status 210 * 211 * @since 1.0.0 212 * 213 * @param array $args { 214 * @type string 'author' 215 * @type string 'post-date' 216 * @type string 'comments' 217 * @type string 'sticky' 218 * } 219 */ 220 $post_meta = apply_filters( 221 'twentytwenty_post_meta_location_single_top', 222 array( 223 'author', 224 'post-date', 225 'comments', 226 'sticky', 227 ) 39 228 ); 40 41 $args = wp_parse_args( $args, $defaults ); 229 $post_meta_wrapper_classes = ' post-meta-single post-meta-single-top'; 230 231 } elseif ( 'single-bottom' === $location ) { 42 232 43 233 /** 44 * Filters the arguments for `twentytwenty_site_logo()`. 45 * 46 * @param array $args Parsed arguments. 47 * @param array $defaults Function's default arguments. 48 */ 49 $args = apply_filters( 'twentytwenty_site_logo_args', $args, $defaults ); 50 51 if ( has_custom_logo() ) { 52 $contents = sprintf( $args['logo'], $logo, esc_html( $site_title ) ); 53 $classname = $args['logo_class']; 54 } else { 55 $contents = sprintf( $args['title'], esc_url( get_home_url( null, '/' ) ), esc_html( $site_title ) ); 56 $classname = $args['title_class']; 57 } 58 59 $wrap = $args['condition'] ? 'home_wrap' : 'single_wrap'; 60 61 $html = sprintf( $args[ $wrap ], $classname, $contents ); 62 63 /** 64 * Filters the arguments for `twentytwenty_site_logo()`. 65 * 66 * @param string $html Compiled html based on our arguments. 67 * @param array $args Parsed arguments. 68 * @param string $classname Class name based on current view, home or single. 69 * @param string $contents HTML for site title or logo. 70 */ 71 $html = apply_filters( 'twentytwenty_site_logo', $html, $args, $classname, $contents ); 72 73 if ( ! $echo ) { 74 return $html; 75 } 76 77 echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 78 79 } 80 } 81 82 if ( ! function_exists( 'twentytwenty_site_description' ) ) { 83 /** 84 * Displays the site description. 85 * 86 * @param boolean $echo Echo or return the html. 87 */ 88 function twentytwenty_site_description( $echo = true ) { 89 $description = get_bloginfo( 'description' ); 90 91 if ( ! $description ) { 92 return; 93 } 94 95 $wrapper = '<div class="site-description">%s</div><!-- .site-description -->'; 96 97 $html = sprintf( $wrapper, esc_html( $description ) ); 98 99 /** 100 * Filters the html for the site description. 101 * 102 * @param string $html The HTML to display. 103 * @param string $description Site description via `bloginfo()`. 104 * @param string $wrapper The format used in case you want to reuse it in a `sprintf()`. 105 */ 106 $html = apply_filters( 'twentytwenty_site_description', $html, $description, $wrapper ); 107 108 if ( ! $echo ) { 109 return $html; 110 } 111 112 echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 113 } 114 } 115 116 /** 117 * Comments 118 */ 119 if ( ! function_exists( 'twentytwenty_is_comment_by_post_author' ) ) { 120 /** 121 * Check if the specified comment is written by the author of the post commented on. 122 * 123 * @param object $comment Comment data. 124 */ 125 function twentytwenty_is_comment_by_post_author( $comment = null ) { 126 127 if ( is_object( $comment ) && $comment->user_id > 0 ) { 128 129 $user = get_userdata( $comment->user_id ); 130 $post = get_post( $comment->comment_post_ID ); 131 132 if ( ! empty( $user ) && ! empty( $post ) ) { 133 134 return $comment->user_id === $post->post_author; 135 136 } 137 } 138 return false; 139 140 } 141 } 142 143 if ( ! function_exists( 'twentytwenty_filter_comment_reply_link' ) ) { 144 145 /** 146 * Filter comment reply link to not JS scroll. 147 * Filter the comment reply link to add a class indicating it should not use JS slow-scroll, as it 148 * makes it scroll to the wrong position on the page. 149 * 150 * @param string $link Link to the top of the page. 151 */ 152 function twentytwenty_filter_comment_reply_link( $link ) { 153 154 $link = str_replace( 'class=\'', 'class=\'do-not-scroll ', $link ); 155 return $link; 156 157 } 158 159 add_filter( 'comment_reply_link', 'twentytwenty_filter_comment_reply_link' ); 160 161 } 162 163 /** 164 * Post Meta 165 */ 166 if ( ! function_exists( 'twentytwenty_the_post_meta' ) ) { 167 /** 168 * Get and Output Post Meta. 169 * If it's a single post, output the post meta values specified in the Customizer settings. 170 * 171 * @param int $post_id The ID of the post for which the post meta should be output. 172 * @param string $location Which post meta location to output – single or preview. 173 */ 174 function twentytwenty_the_post_meta( $post_id = null, $location = 'single-top' ) { 175 176 echo twentytwenty_get_post_meta( $post_id, $location ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in twentytwenty_get_post_meta(). 177 178 } 179 } 180 181 if ( ! function_exists( 'twentytwenty_get_post_meta' ) ) { 182 183 /** 184 * Get the post meta. 185 * 186 * @param int $post_id The iD of the post. 187 * @param string $location The location where the meta is shown. 188 */ 189 function twentytwenty_get_post_meta( $post_id = null, $location = 'single-top' ) { 190 191 // Require post ID. 192 if ( ! $post_id ) { 193 return; 194 } 195 196 $page_template = get_page_template_slug( $post_id ); 197 198 // Check whether the post type is allowed to output post meta. 199 $disallowed_post_types = apply_filters( 'twentytwenty_disallowed_post_types_for_meta_output', array( 'page' ) ); 200 if ( in_array( get_post_type( $post_id ), $disallowed_post_types, true ) ) { 201 return; 202 } 203 204 $post_meta_wrapper_classes = ''; 205 $post_meta_classes = ''; 206 207 // Get the post meta settings for the location specified. 208 if ( 'single-top' === $location ) { 209 210 $post_meta = apply_filters( 211 'twentytwenty_post_meta_location_single_top', 212 array( 213 'author', 214 'post-date', 215 'comments', 216 'sticky', 217 ) 218 ); 219 $post_meta_wrapper_classes = ' post-meta-single post-meta-single-top'; 220 221 } elseif ( 'single-bottom' === $location ) { 222 223 $post_meta = apply_filters( 224 'twentytwenty_post_meta_location_single_bottom', 225 array( 226 'tags', 227 ) 228 ); 229 $post_meta_wrapper_classes = ' post-meta-single post-meta-single-bottom'; 230 231 } 232 233 // If the post meta setting has the value 'empty', it's explicitly empty and the default post meta shouldn't be output. 234 if ( $post_meta && ! in_array( 'empty', $post_meta, true ) ) { 235 236 // Make sure we don't output an empty container. 237 $has_meta = false; 238 239 global $post; 240 $the_post = get_post( $post_id ); 241 setup_postdata( $the_post ); 242 243 ob_start(); 244 245 ?> 246 247 <div class="post-meta-wrapper<?php echo esc_attr( $post_meta_wrapper_classes ); ?>"> 248 249 <ul class="post-meta<?php echo esc_attr( $post_meta_classes ); ?>"> 250 234 * Filters post tags visibility 235 * 236 * Use this filter to hide post tags 237 * 238 * @since 1.0.0 239 * 240 * @param array $args { 241 * @type string 'tags' 242 * } 243 */ 244 $post_meta = apply_filters( 245 'twentytwenty_post_meta_location_single_bottom', 246 array( 247 'tags', 248 ) 249 ); 250 $post_meta_wrapper_classes = ' post-meta-single post-meta-single-bottom'; 251 252 } 253 254 // If the post meta setting has the value 'empty', it's explicitly empty and the default post meta shouldn't be output. 255 if ( $post_meta && ! in_array( 'empty', $post_meta, true ) ) { 256 257 // Make sure we don't output an empty container. 258 $has_meta = false; 259 260 global $post; 261 $the_post = get_post( $post_id ); 262 setup_postdata( $the_post ); 263 264 ob_start(); 265 266 ?> 267 268 <div class="post-meta-wrapper<?php echo esc_attr( $post_meta_wrapper_classes ); ?>"> 269 270 <ul class="post-meta<?php echo esc_attr( $post_meta_classes ); ?>"> 271 272 <?php 273 274 /** 275 * Fires before post meta html display. 276 * 277 * Allow output of additional post meta info to be added by child themes and plugins. 278 * 279 * @since 1.0.0 280 * 281 * @param int $post_ID Post ID. 282 */ 283 do_action( 'twentytwenty_start_of_post_meta_list', $post_id ); 284 285 // Author. 286 if ( in_array( 'author', $post_meta, true ) ) { 287 288 $has_meta = true; 289 ?> 290 <li class="post-author meta-wrapper"> 291 <span class="meta-icon"> 292 <span class="screen-reader-text"><?php _e( 'Post author', 'twentytwenty' );// phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 293 <?php twentytwenty_the_theme_svg( 'user' ); ?> 294 </span> 295 <span class="meta-text"> 296 <?php 297 printf( 298 // Translators: %s = the author name. 299 _x( 'By %s', '%s = author name', 'twentytwenty' ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- core trusts translations 300 '<a href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . esc_html( get_the_author_meta( 'display_name' ) ) . '</a>' 301 ); 302 ?> 303 </span> 304 </li> 251 305 <?php 252 306 253 // Allow output of additional meta items to be added by child themes and plugins.254 do_action( 'twentytwenty_start_of_post_meta_list', $post_meta, $post_id ); 255 256 // Author.257 if ( in_array( 'author', $post_meta, true ) ) { 258 259 $has_meta = true;260 ?>261 < li class="post-author meta-wrapper">307 } 308 309 // Post date. 310 if ( in_array( 'post-date', $post_meta, true ) ) { 311 312 $has_meta = true; 313 ?> 314 <li class="post-date"> 315 <a class="meta-wrapper" href="<?php the_permalink(); ?>"> 262 316 <span class="meta-icon"> 263 <span class="screen-reader-text"><?php _e( 'Post author', 'twentytwenty' );// phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span>264 <?php twentytwenty_the_theme_svg( ' user' ); ?>317 <span class="screen-reader-text"><?php _e( 'Post date', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 318 <?php twentytwenty_the_theme_svg( 'calendar' ); ?> 265 319 </span> 266 320 <span class="meta-text"> 267 <?php 268 printf( 269 // Translators: %s = the author name. 270 _x( 'By %s', '%s = author name', 'twentytwenty' ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- core trusts translations 271 '<a href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . esc_html( get_the_author_meta( 'display_name' ) ) . '</a>' 272 ); 273 ?> 321 <?php the_time( get_option( 'date_format' ) ); ?> 274 322 </span> 275 </li> 276 <?php 277 278 } 279 280 // Post date. 281 if ( in_array( 'post-date', $post_meta, true ) ) { 282 283 $has_meta = true; 284 ?> 285 <li class="post-date"> 286 <a class="meta-wrapper" href="<?php the_permalink(); ?>"> 287 <span class="meta-icon"> 288 <span class="screen-reader-text"><?php _e( 'Post date', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 289 <?php twentytwenty_the_theme_svg( 'calendar' ); ?> 290 </span> 291 <span class="meta-text"> 292 <?php the_time( get_option( 'date_format' ) ); ?> 293 </span> 294 </a> 295 </li> 296 <?php 297 298 } 299 300 // Categories. 301 if ( in_array( 'categories', $post_meta, true ) && has_category() ) { 302 303 $has_meta = true; 304 ?> 305 <li class="post-categories meta-wrapper"> 306 <span class="meta-icon"> 307 <span class="screen-reader-text"><?php _e( 'Categories', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 308 <?php twentytwenty_the_theme_svg( 'folder' ); ?> 309 </span> 310 <span class="meta-text"> 311 <?php _e( 'In', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?> <?php the_category( ', ' ); ?> 312 </span> 313 </li> 314 <?php 315 316 } 317 318 // Tags. 319 if ( in_array( 'tags', $post_meta, true ) && has_tag() ) { 320 321 $has_meta = true; 322 ?> 323 <li class="post-tags meta-wrapper"> 324 <span class="meta-icon"> 325 <span class="screen-reader-text"><?php _e( 'Tags', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 326 <?php twentytwenty_the_theme_svg( 'tag' ); ?> 327 </span> 328 <span class="meta-text"> 329 <?php the_tags( '', ', ', '' ); ?> 330 </span> 331 </li> 332 <?php 333 334 } 335 336 // Comments link. 337 if ( in_array( 'comments', $post_meta, true ) && ! post_password_required() && ( comments_open() || get_comments_number() ) ) { 338 339 $has_meta = true; 340 ?> 341 <li class="post-comment-link meta-wrapper"> 342 <span class="meta-icon"> 343 <?php twentytwenty_the_theme_svg( 'comment' ); ?> 344 </span> 345 <span class="meta-text"> 346 <?php comments_popup_link(); ?> 347 </span> 348 </li> 349 <?php 350 351 } 352 353 // Sticky. 354 if ( in_array( 'sticky', $post_meta, true ) && is_sticky() ) { 355 356 $has_meta = true; 357 ?> 358 <li class="post-sticky meta-wrapper"> 359 <span class="meta-icon"> 360 <?php twentytwenty_the_theme_svg( 'bookmark' ); ?> 361 </span> 362 <span class="meta-text"> 363 <?php _e( 'Sticky post', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?> 364 </span> 365 </li> 366 <?php 367 368 } 369 370 // Allow output of additional post meta types to be added by child themes and plugins. 371 do_action( 'twentytwenty_end_of_post_meta_list', $post_meta, $post_id ); 372 323 </a> 324 </li> 325 <?php 326 327 } 328 329 // Categories. 330 if ( in_array( 'categories', $post_meta, true ) && has_category() ) { 331 332 $has_meta = true; 373 333 ?> 374 375 </ul><!-- .post-meta --> 376 377 </div><!-- .post-meta-wrapper --> 378 379 <?php 380 381 wp_reset_postdata(); 382 383 $meta_output = ob_get_clean(); 384 385 // If there is meta to output, return it. 386 if ( $has_meta && $meta_output ) { 387 388 return $meta_output; 389 390 } 334 <li class="post-categories meta-wrapper"> 335 <span class="meta-icon"> 336 <span class="screen-reader-text"><?php _e( 'Categories', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 337 <?php twentytwenty_the_theme_svg( 'folder' ); ?> 338 </span> 339 <span class="meta-text"> 340 <?php _e( 'In', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?> <?php the_category( ', ' ); ?> 341 </span> 342 </li> 343 <?php 344 345 } 346 347 // Tags. 348 if ( in_array( 'tags', $post_meta, true ) && has_tag() ) { 349 350 $has_meta = true; 351 ?> 352 <li class="post-tags meta-wrapper"> 353 <span class="meta-icon"> 354 <span class="screen-reader-text"><?php _e( 'Tags', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span> 355 <?php twentytwenty_the_theme_svg( 'tag' ); ?> 356 </span> 357 <span class="meta-text"> 358 <?php the_tags( '', ', ', '' ); ?> 359 </span> 360 </li> 361 <?php 362 363 } 364 365 // Comments link. 366 if ( in_array( 'comments', $post_meta, true ) && ! post_password_required() && ( comments_open() || get_comments_number() ) ) { 367 368 $has_meta = true; 369 ?> 370 <li class="post-comment-link meta-wrapper"> 371 <span class="meta-icon"> 372 <?php twentytwenty_the_theme_svg( 'comment' ); ?> 373 </span> 374 <span class="meta-text"> 375 <?php comments_popup_link(); ?> 376 </span> 377 </li> 378 <?php 379 380 } 381 382 // Sticky. 383 if ( in_array( 'sticky', $post_meta, true ) && is_sticky() ) { 384 385 $has_meta = true; 386 ?> 387 <li class="post-sticky meta-wrapper"> 388 <span class="meta-icon"> 389 <?php twentytwenty_the_theme_svg( 'bookmark' ); ?> 390 </span> 391 <span class="meta-text"> 392 <?php _e( 'Sticky post', 'twentytwenty' ); // phpcs:ignore WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?> 393 </span> 394 </li> 395 <?php 396 397 } 398 399 /** 400 * Fires after post meta html display. 401 * 402 * Allow output of additional post meta info to be added by child themes and plugins. 403 * 404 * @since 1.0.0 405 * 406 * @param int $post_ID Post ID. 407 */ 408 do_action( 'twentytwenty_end_of_post_meta_list', $post_id ); 409 410 ?> 411 412 </ul><!-- .post-meta --> 413 414 </div><!-- .post-meta-wrapper --> 415 416 <?php 417 418 wp_reset_postdata(); 419 420 $meta_output = ob_get_clean(); 421 422 // If there is meta to output, return it. 423 if ( $has_meta && $meta_output ) { 424 425 return $meta_output; 426 391 427 } 392 393 } 428 } 429 394 430 } 395 431 … … 397 433 * Menus 398 434 */ 399 if ( ! function_exists( 'twentytwenty_filter_wp_list_pages_item_classes' ) ) { 435 /** 436 * Filter Classes of wp_list_pages items to match menu items. 437 * Filter the class applied to wp_list_pages() items with children to match the menu class, to simplify. 438 * styling of sub levels in the fallback. Only applied if the match_menu_classes argument is set. 439 * 440 * @param string $css_class CSS Class names. 441 * @param string $item Comment. 442 * @param int $depth Depth of the current comment. 443 * @param array $args An array of arguments. 444 * @param string $current_page Wether or not the item is the current item. 445 */ 446 function twentytwenty_filter_wp_list_pages_item_classes( $css_class, $item, $depth, $args, $current_page ) { 447 448 // Only apply to wp_list_pages() calls with match_menu_classes set to true. 449 $match_menu_classes = isset( $args['match_menu_classes'] ); 450 451 if ( ! $match_menu_classes ) { 452 return $css_class; 453 } 454 455 // Add current menu item class. 456 if ( in_array( 'current_page_item', $css_class, true ) ) { 457 $css_class[] = 'current-menu-item'; 458 } 459 460 // Add menu item has children class. 461 if ( in_array( 'page_item_has_children', $css_class, true ) ) { 462 $css_class[] = 'menu-item-has-children'; 463 } 464 465 return $css_class; 466 467 } 468 469 add_filter( 'page_css_class', 'twentytwenty_filter_wp_list_pages_item_classes', 10, 5 ); 470 471 /** 472 * Add a Sub Nav Toggle to the Expanded Menu and Mobile Menu. 473 * 474 * @param array $args An array of arguments. 475 * @param string $item Menu item. 476 * @param int $depth Depth of the current menu item. 477 */ 478 function twentytwenty_add_sub_toggles_to_main_menu( $args, $item, $depth ) { 479 480 // Add sub menu toggles to the Expanded Menu with toggles. 481 if ( isset( $args->show_toggles ) && $args->show_toggles ) { 482 483 // Wrap the menu item link contents in a div, used for positioning. 484 $args->before = '<div class="ancestor-wrapper">'; 485 $args->after = ''; 486 487 // Add a toggle to items with children. 488 if ( in_array( 'menu-item-has-children', $item->classes, true ) ) { 489 490 $toggle_target_string = '.menu-modal .menu-item-' . $item->ID . ' > .sub-menu'; 491 $toggle_duration = twentytwenty_toggle_duration(); 492 493 // Add the sub menu toggle. 494 $args->after .= '<button class="toggle sub-menu-toggle fill-children-current-color" data-toggle-target="' . $toggle_target_string . '" data-toggle-type="slidetoggle" data-toggle-duration="' . absint( $toggle_duration ) . '"><span class="screen-reader-text">' . __( 'Show sub menu', 'twentytwenty' ) . '</span>' . twentytwenty_get_theme_svg( 'chevron-down' ) . '</button>'; 495 496 } 497 498 // Close the wrapper. 499 $args->after .= '</div><!-- .ancestor-wrapper -->'; 500 501 // Add sub menu icons to the primary menu without toggles. 502 } elseif ( 'primary' === $args->theme_location ) { 503 if ( in_array( 'menu-item-has-children', $item->classes, true ) ) { 504 $args->after = '<span class="icon"></span>'; 505 } else { 506 $args->after = ''; 507 } 508 } 509 510 return $args; 511 512 } 513 514 add_filter( 'nav_menu_item_args', 'twentytwenty_add_sub_toggles_to_main_menu', 10, 3 ); 515 516 /** 517 * Classes 518 */ 519 /** 520 * Add No-JS Class. 521 * If we're missing JavaScript support, the HTML element will have a no-js class. 522 */ 523 function twentytwenty_no_js_class() { 524 525 ?> 526 <script>document.documentElement.className = document.documentElement.className.replace( 'no-js', 'js' );</script> 527 <?php 528 529 } 530 531 add_action( 'wp_head', 'twentytwenty_no_js_class' ); 532 533 /** 534 * Filters the archive title and styles the word before the first colon. 535 * 536 * @param string $title Current archive title. 537 */ 538 function twentytwenty_get_the_archive_title( $title ) { 539 540 $regex = apply_filters( 541 'twentytwenty_get_the_archive_title_regex', 542 array( 543 'pattern' => '/(\A[^\:]+\:)/', 544 'replacement' => '<span class="color-accent">$1</span>', 545 ) 546 ); 547 548 if ( empty( $regex ) ) { 549 550 return $title; 551 552 } 553 554 return preg_replace( $regex['pattern'], $regex['replacement'], $title ); 555 556 } 557 558 add_filter( 'get_the_archive_title', 'twentytwenty_get_the_archive_title' ); 559 560 /** 561 * Filters the edit post link to add an icon and use the post meta structure. 562 * 563 * @param string $link Anchor tag for the edit link. 564 * @param int $post_id Post ID. 565 * @param string $text Anchor text. 566 */ 567 function twentytwenty_edit_post_link( $link, $post_id, $text ) { 568 569 $edit_url = get_edit_post_link( $post_id ); 570 571 if ( ! $edit_url ) { 572 return; 573 } 574 575 return '<div class="post-meta-wrapper post-meta-edit-link-wrapper"><ul class="post-meta"><li class="post-edit meta-wrapper"><span class="meta-icon">' . twentytwenty_get_theme_svg( 'edit' ) . '</span><span class="meta-text"><a href="' . esc_url( $edit_url ) . '">' . $text . '</a></span></li></ul><!-- .post-meta --></div><!-- .post-meta-wrapper -->'; 576 577 } 578 579 add_filter( 'edit_post_link', 'twentytwenty_edit_post_link', 10, 3 ); 580 581 /** 582 * Add conditional body classes. 583 * 584 * @param string $classes Classes added to the body tag. 585 */ 586 function twentytwenty_body_classes( $classes ) { 587 588 global $post; 589 $post_type = isset( $post ) ? $post->post_type : false; 590 591 // Check whether we're singular. 592 if ( is_singular() ) { 593 $classes[] = 'singular'; 594 } 595 596 // Check whether the current page should have an overlay header. 597 if ( is_page_template( array( 'templates/template-cover.php' ) ) ) { 598 $classes[] = 'overlay-header'; 599 } 600 601 // Check whether the current page has full-width content. 602 if ( is_page_template( array( 'templates/template-full-width.php' ) ) ) { 603 $classes[] = 'has-full-width-content'; 604 } 605 606 // Check for enabled search. 607 if ( true === get_theme_mod( 'enable_header_search', true ) ) { 608 $classes[] = 'enable-search-modal'; 609 } 610 611 // Check for post thumbnail. 612 if ( is_singular() && has_post_thumbnail() ) { 613 $classes[] = 'has-post-thumbnail'; 614 } elseif ( is_singular() ) { 615 $classes[] = 'missing-post-thumbnail'; 616 } 617 618 // Check whether we're in the customizer preview. 619 if ( is_customize_preview() ) { 620 $classes[] = 'customizer-preview'; 621 } 622 623 // Check if posts have single pagination. 624 if ( is_single() && ( get_next_post() || get_previous_post() ) ) { 625 $classes[] = 'has-single-pagination'; 626 } else { 627 $classes[] = 'has-no-pagination'; 628 } 629 630 // Check if we're showing comments. 631 if ( $post && ( ( 'post' === $post_type || comments_open() || get_comments_number() ) && ! post_password_required() ) ) { 632 $classes[] = 'showing-comments'; 633 } else { 634 $classes[] = 'not-showing-comments'; 635 } 636 637 // Check if avatars are visible. 638 $classes[] = get_option( 'show_avatars' ) ? 'show-avatars' : 'hide-avatars'; 639 640 // Slim page template class names (class = name - file suffix). 641 if ( is_page_template() ) { 642 $classes[] = basename( get_page_template_slug(), '.php' ); 643 } 644 645 // Check for the elements output in the top part of the footer. 646 $has_footer_menu = has_nav_menu( 'footer' ); 647 $has_social_menu = has_nav_menu( 'social' ); 648 $has_sidebar_1 = is_active_sidebar( 'sidebar-1' ); 649 $has_sidebar_2 = is_active_sidebar( 'sidebar-2' ); 650 651 // Add a class indicating whether those elements are output. 652 if ( $has_footer_menu || $has_social_menu || $has_sidebar_1 || $has_sidebar_2 ) { 653 $classes[] = 'footer-top-visible'; 654 } else { 655 $classes[] = 'footer-top-hidden'; 656 } 657 658 // Get header/footer background color. 659 $header_footer_background = get_theme_mod( 'header_footer_background_color', '#ffffff' ); 660 $header_footer_background = strtolower( '#' . ltrim( $header_footer_background, '#' ) ); 661 662 // Get content background color. 663 $background_color = get_theme_mod( 'background_color', 'f5efe0' ); 664 $background_color = strtolower( '#' . ltrim( $background_color, '#' ) ); 665 666 // Add extra class if main background and header/footer background are the same color. 667 if ( $background_color === $header_footer_background ) { 668 $classes[] = 'reduced-spacing'; 669 } 670 671 return $classes; 672 673 } 674 675 add_filter( 'body_class', 'twentytwenty_body_classes' ); 676 677 /** 678 * Toggle animation duration in milliseconds. 679 * 680 * @return integer Duration in milliseconds 681 */ 682 function twentytwenty_toggle_duration() { 400 683 /** 401 * Filter Classes of wp_list_pages items to match menu items. 402 * Filter the class applied to wp_list_pages() items with children to match the menu class, to simplify. 403 * styling of sub levels in the fallback. Only applied if the match_menu_classes argument is set. 404 * 405 * @param string $css_class CSS Class names. 406 * @param string $item Comment. 407 * @param int $depth Depth of the current comment. 408 * @param array $args An array of arguments. 409 * @param string $current_page Wether or not the item is the current item. 684 * Filters the animation duration/speed used usually for submenu toggles. 685 * 686 * @since 1.0 687 * 688 * @param integer $duration Duration in milliseconds. 410 689 */ 411 function twentytwenty_filter_wp_list_pages_item_classes( $css_class, $item, $depth, $args, $current_page ) { 412 413 // Only apply to wp_list_pages() calls with match_menu_classes set to true. 414 $match_menu_classes = isset( $args['match_menu_classes'] ); 415 416 if ( ! $match_menu_classes ) { 417 return $css_class; 418 } 419 420 // Add current menu item class. 421 if ( in_array( 'current_page_item', $css_class, true ) ) { 422 $css_class[] = 'current-menu-item'; 423 } 424 425 // Add menu item has children class. 426 if ( in_array( 'page_item_has_children', $css_class, true ) ) { 427 $css_class[] = 'menu-item-has-children'; 428 } 429 430 return $css_class; 431 432 } 433 434 add_filter( 'page_css_class', 'twentytwenty_filter_wp_list_pages_item_classes', 10, 5 ); 435 436 } 437 438 if ( ! function_exists( 'twentytwenty_add_sub_toggles_to_main_menu' ) ) { 439 /** 440 * Add a Sub Nav Toggle to the Expanded Menu and Mobile Menu. 441 * 442 * @param array $args An array of arguments. 443 * @param string $item Menu item. 444 * @param int $depth Depth of the current menu item. 445 */ 446 function twentytwenty_add_sub_toggles_to_main_menu( $args, $item, $depth ) { 447 448 // Add sub menu toggles to the Expanded Menu with toggles. 449 if ( isset( $args->show_toggles ) && $args->show_toggles ) { 450 451 // Wrap the menu item link contents in a div, used for positioning. 452 $args->before = '<div class="ancestor-wrapper">'; 453 $args->after = ''; 454 455 // Add a toggle to items with children. 456 if ( in_array( 'menu-item-has-children', $item->classes, true ) ) { 457 458 $toggle_target_string = '.menu-modal .menu-item-' . $item->ID . ' > .sub-menu'; 459 460 // Add the sub menu toggle. 461 $args->after .= '<button class="toggle sub-menu-toggle fill-children-current-color" data-toggle-target="' . $toggle_target_string . '" data-toggle-type="slidetoggle" data-toggle-duration="250"><span class="screen-reader-text">' . __( 'Show sub menu', 'twentytwenty' ) . '</span>' . twentytwenty_get_theme_svg( 'chevron-down' ) . '</button>'; 462 463 } 464 465 // Close the wrapper. 466 $args->after .= '</div><!-- .ancestor-wrapper -->'; 467 468 // Add sub menu icons to the primary menu without toggles. 469 } elseif ( 'primary' === $args->theme_location ) { 470 if ( in_array( 'menu-item-has-children', $item->classes, true ) ) { 471 $args->after = '<span class="icon"></span>'; 472 } else { 473 $args->after = ''; 474 } 475 } 476 477 return $args; 478 479 } 480 481 add_filter( 'nav_menu_item_args', 'twentytwenty_add_sub_toggles_to_main_menu', 10, 3 ); 482 483 } 484 485 /** 486 * Classes 487 */ 488 489 if ( ! function_exists( 'twentytwenty_no_js_class' ) ) { 490 /** 491 * Add No-JS Class. 492 * If we're missing JavaScript support, the HTML element will have a no-js class. 493 */ 494 function twentytwenty_no_js_class() { 495 496 ?> 497 <script>document.documentElement.className = document.documentElement.className.replace( 'no-js', 'js' );</script> 498 <?php 499 500 } 501 502 add_action( 'wp_head', 'twentytwenty_no_js_class' ); 503 504 } 505 506 if ( ! function_exists( 'twentytwenty_get_the_archive_title' ) ) { 507 508 /** 509 * Filters the archive title and styles the word before the first colon. 510 * 511 * @param string $title Current archive title. 512 */ 513 function twentytwenty_get_the_archive_title( $title ) { 514 515 $regex = apply_filters( 516 'twentytwenty_get_the_archive_title_regex', 517 array( 518 'pattern' => '/(\A[^\:]+\:)/', 519 'replacement' => '<span class="color-accent">$1</span>', 520 ) 521 ); 522 523 if ( empty( $regex ) ) { 524 525 return $title; 526 527 } 528 529 return preg_replace( $regex['pattern'], $regex['replacement'], $title ); 530 531 } 532 533 add_filter( 'get_the_archive_title', 'twentytwenty_get_the_archive_title' ); 534 535 } 536 537 if ( ! function_exists( 'twentytwenty_body_classes' ) ) { 538 /** 539 * Add conditional body classes. 540 * 541 * @param string $classes Classes added to the body tag. 542 */ 543 function twentytwenty_body_classes( $classes ) { 544 545 global $post; 546 $post_type = isset( $post ) ? $post->post_type : false; 547 548 // Check whether we're singular. 549 if ( is_singular() ) { 550 $classes[] = 'singular'; 551 } 552 553 // Check whether the current page should have an overlay header. 554 if ( is_page_template( array( 'templates/template-cover.php' ) ) ) { 555 $classes[] = 'overlay-header'; 556 } 557 558 // Check whether the current page has full-width content. 559 if ( is_page_template( array( 'templates/template-full-width.php' ) ) ) { 560 $classes[] = 'has-full-width-content'; 561 } 562 563 // Check for enabled search. 564 if ( true === get_theme_mod( 'enable_header_search', true ) ) { 565 $classes[] = 'enable-search-modal'; 566 } 567 568 // Check for post thumbnail. 569 if ( is_singular() && has_post_thumbnail() ) { 570 $classes[] = 'has-post-thumbnail'; 571 } elseif ( is_singular() ) { 572 $classes[] = 'missing-post-thumbnail'; 573 } 574 575 // Check whether we're in the customizer preview. 576 if ( is_customize_preview() ) { 577 $classes[] = 'customizer-preview'; 578 } 579 580 // Check if posts have single pagination. 581 if ( is_single() && ( get_next_post() || get_previous_post() ) ) { 582 $classes[] = 'has-single-pagination'; 583 } else { 584 $classes[] = 'has-no-pagination'; 585 } 586 587 // Check if we're showing comments. 588 if ( $post && ( ( 'post' === $post_type || comments_open() || get_comments_number() ) && ! post_password_required() ) ) { 589 $classes[] = 'showing-comments'; 590 } else { 591 $classes[] = 'not-showing-comments'; 592 } 593 594 // Check if avatars are visible. 595 $classes[] = get_option( 'show_avatars' ) ? 'show-avatars' : 'hide-avatars'; 596 597 // Slim page template class names (class = name - file suffix). 598 if ( is_page_template() ) { 599 $classes[] = basename( get_page_template_slug(), '.php' ); 600 } 601 602 return $classes; 603 604 } 605 606 add_filter( 'body_class', 'twentytwenty_body_classes' ); 607 608 } 690 $duration = apply_filters( 'twentytwenty_toggle_duration', 250 ); 691 692 return $duration; 693 }
Note: See TracChangeset
for help on using the changeset viewer.