I’m keeping a running list of useful WordPress components that I use often across many custom theme projects. I usually work with the Sage starter theme, but these components can be used with any theme. However, I’ll be showing code for Sage in most cases which uses blade templates, so replace {{...}}
with <?php ...; ?>
. Also, you can remove __NAMESPACE__ . '\\
in most cases. I’ll be adding, editing, and updating the components as time goes on.
- Toggle Title
- Custom Logo
- Bootstrap 4 Header with Nav walker
- Automatic Footer Columns (Bootstrap Ready)
- Numeric Page Navigation (Bootstrap Ready)
Toggle Title (As a Custom Meta Box)
/** * Add Page Options Meta Box */ function page_options_add_metabox() { $post_types = Array('page'); foreach ($post_types as $post_type) { add_meta_box('pageoptions', __('Page Options', 'text-domain'), __NAMESPACE__ . '\\page_options_metabox', $post_type, 'side', 'low'); } } add_action('add_meta_boxes', __NAMESPACE__ . '\\page_options_add_metabox'); /** * * Page Options Meta Box * * @param $post */ function page_options_metabox($post) { wp_nonce_field(basename(__FILE__), 'prfx_nonce'); $prfx_stored_meta = get_post_meta($post->ID); ?> <div class="prfx-row-content"> <label for="_hide_title"> <input type="checkbox" name="_hide_title" id="_hide_title" value="yes" <?php if (isset ($prfx_stored_meta['_hide_title'])) checked($prfx_stored_meta['_hide_title'][0], 'yes'); ?> /> <?php _e('Hide Title', 'prfx-textdomain') ?> </label> </div> <?php } /** * * Save Page Options Meta Boxes * * @param $post_id */ function page_options_meta_box_save($post_id) { // Hide Title if (isset($_POST['_hide_title'])) { update_post_meta($post_id, '_hide_title', 'yes'); } else { update_post_meta($post_id, '_hide_title', ''); } } add_action('save_post', __NAMESPACE__ . '\\page_options_meta_box_save', 10, 1);
Hide Title Function
/** * Hide Title function */ function hide_title() { global $wp_query; $post = $wp_query->post; if ( empty( get_post_meta( $post->ID, '_hide_title', true ) ) ) { return false; } else { return true; } }
Usage
@if(!App\hide_title()) <h1>{!! App\title() !!}</h1> @endif
Custom Logo
/** * Enable Custom Logo in Appearance > Customize */ add_theme_support( 'custom-logo' ); /** * Custom function for displaying the logo */ function sage_custom_logo() { if ( function_exists( 'the_custom_logo' ) ) { $custom_logo = '<img src="' . wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'full' ) . '" alt="' . get_bloginfo( 'name' ) . '" />'; echo $custom_logo; } }
Usage
<a class="site-logo" href="{{ home_url('/') }}">{{has_custom_logo() ? App\sage_custom_logo() : bloginfo('name')}}</a>
Bootstrap 4 Header with Nav walker (for sage)
Add walker.php to your theme. In Sage 9 it should go into the app folder and then should be called in resources/functions.php in the array_map
function like so ['helpers', 'setup', 'filters', 'admin', 'walker']
<div class="header"> <div class="navbar navbar-toggleable-sm navbar-light"> <div class="container"> <!-- logo --> <div class="navbar-brand"> <a class="site-logo align-middle" href="{{ home_url('/') }}">{{has_custom_logo() ? App\sage_custom_logo() : bloginfo('name')}}</a> </div> <!-- required spacer --> <ul class="mr-auto"></ul> <!-- main menu --> <nav class="navbar navbar-toggleable-sm navbar-light navbar-menu"> <!-- mobile toggle --> <button class="navbar-toggler mx-auto" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="">Menu</span> </button> <!-- menu --> <div class="container"> <div class="collapse navbar-collapse" id="navbarSupportedContent"> @if (has_nav_menu('primary_navigation')) {!! wp_nav_menu(['theme_location' => 'primary_navigation', 'menu_class' => 'navbar-nav mr-auto', 'depth' => '2']) !!} @endif </div> </div> </nav> </div> </div> </div>
Automatic Footer Columns
This functionality automatically creates bootstrap columns depending on how many widgets you have in the footer. For example, if you have 3 widgets, this code will make 3 columns. Make sure you use the correct selector in line 5. If you want to change the breakpoint for when the columns become a single column (as you’d want on mobile), then change the md in line 9 to lg/sm/xs.
/** * Automatic Footer Columns */ (function footerColumns() { var footerCols = $('footer section'); var footerColsNum = parseInt(footerCols.length); var columnWidth = (footerColsNum === 5) ? 15 : 12 / footerColsNum; footerCols.each(function () { $(this).addClass('col-md-' + columnWidth); }); })();
Numeric Page Navigation (Bootstrap Ready)
Add to your template with {!! App\page_navi() !!}
/** * Numeric page navigation * * Use this function to create pagingation links that are styleable with Twitter Bootstrap * http://www.lanexa.net/2012/09/add-twitter-bootstrap-pagination-to-your-wordpress-theme/ */ if (!function_exists('page_navi')) : function page_navi($before = '', $after = '') { global $wpdb, $wp_query; $request = $wp_query->request; $posts_per_page = intval(get_query_var('posts_per_page')); $paged = intval(get_query_var('paged')); $numposts = $wp_query->found_posts; $max_page = $wp_query->max_num_pages; if ($numposts <= $posts_per_page) { return; } if (empty($paged) || $paged == 0) { $paged = 1; } $pages_to_show = 7; $pages_to_show_minus_1 = $pages_to_show - 1; $half_page_start = floor($pages_to_show_minus_1 / 2); $half_page_end = ceil($pages_to_show_minus_1 / 2); $start_page = $paged - $half_page_start; if ($start_page <= 0) { $start_page = 1; } $end_page = $paged + $half_page_end; if (($end_page - $start_page) != $pages_to_show_minus_1) { $end_page = $start_page + $pages_to_show_minus_1; } if ($end_page > $max_page) { $start_page = $max_page - $pages_to_show_minus_1; $end_page = $max_page; } if ($start_page <= 0) { $start_page = 1; } echo $before . '<ul class="pagination">' . ""; $prevposts = get_previous_posts_link('<i class="fa fa-chevron-left" aria-hidden="true"></i>Prev'); if ($prevposts) { echo '<li class="page-item">' . $prevposts . '</li>'; } else {// if there are no prev posts } for ($i = $start_page; $i <= $end_page; $i++) { if ($i == $paged) { echo '<li class="page-item active"><a class="page-link" href="#">' . $i . '</a></li>'; } else { echo '<li class="page-item"><a class="page-link" href="' . get_pagenum_link($i) . '">' . $i . '</a></li>'; } } echo '<li class="page-item">'; next_posts_link('Next<i class="fa fa-chevron-right" aria-hidden="true"></i>'); echo '</li>'; echo '</ul>' . $after . ""; } endif; add_filter('next_posts_link_attributes', __NAMESPACE__ . '\\posts_link_attributes'); add_filter('previous_posts_link_attributes', __NAMESPACE__ . '\\posts_link_attributes'); function posts_link_attributes() { return 'class="page-link page-jump"'; }