Useful WordPress Components For Any Custom Theme Project

By August 7, 2017Blog, Sage, Wordpress
WordPress Tutorials by Allure Web Solutions

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 (As a Custom Meta Box)

Page Options 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 WP Customizer

/**
 * 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>

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>

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);
    });
})();

Number Page Navigation WordPress
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"';
}
Mike Doubintchik

Author Mike Doubintchik

More posts by Mike Doubintchik

Leave a Reply