/*!
* WP_HEAD cleanup
* This removes bogus markup, stylesheets, and scripts from the `<head>`-tag in WordPress installations.
* It also unregisters the built-in version of jQuery, so you can register your own, updated version of jQuery.
*/
function moso_cleanup() {
remove_action('wp_head', 'feed_links_extra', 3); // Category feeds
remove_action('wp_head', 'feed_links', 2); // Post and comment feeds
remove_action('wp_head', 'rsd_link'); // EditURI link
remove_action('wp_head', 'wlwmanifest_link'); // Windows Live Writer
remove_action('wp_head', 'index_rel_link'); // Index link
remove_action('wp_head', 'parent_post_rel_link', 10, 0); // Previous link
remove_action('wp_head', 'start_post_rel_link', 10, 0); // Start link
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); // Links for adjacent posts
remove_action('wp_head', 'wp_generator'); // WP version for security reasons
remove_action('wp_head', 'rest_output_link_wp_head'); // JSON API links
remove_action('wp_head', 'wp_oembed_add_discovery_links'); // JSON discovery links
remove_action('wp_head', 'wp_resource_hints', 2); // DNS prefetch
remove_action('wp_head', 'print_emoji_detection_script', 7); // Emoji part 1
remove_action('wp_print_styles', 'print_emoji_styles'); // Emoji part 2
wp_deregister_script('jquery'); // De-register jQuery
wp_deregister_script('wp-embed'); // De-register WP Embed
}
add_action('init', 'moso_cleanup');
/*!
* Webpack-friendly stylesheet and script enqueues.
* If you compile your resources with, eg, Laravel Mix's way of working with webpack,
* and you autoload jQuery, then Bootstrap's JS, then this is for you.
* The '0' at the add_action is to make sure this loads before any plugins load their scripts,
* as some of them can be dependent on jQuery.
*
* Change the folders, and change the name 'app' to whatever your theme styles and scrips use.
*/
function add_theme_scripts() {
// STYLES
wp_enqueue_style('app', get_template_directory_uri() . '/css/app.css', array());
// SCRIPTS
wp_enqueue_script('manifest', get_template_directory_uri() . '/js/manifest.js', array(), '', true);
wp_enqueue_script('vendor', get_template_directory_uri() . '/js/vendor.js', array(), '', true);
wp_enqueue_script('app', get_template_directory_uri() . '/js/app.js', array(), '', true);
}
add_action('wp_enqueue_scripts', 'add_theme_scripts', 0);
/*!
* Register custom navigation locations
*/
register_nav_menu('topbar', __('Topbar', 'theme_name'));
register_nav_menu('navbar', __('Navbar', 'theme_name'));
/*!
* Register Bootstrap Nav-Walker
* As Bootstrap has a different markup for their navbars and navigation items, one needs a socalled 'walker'.
* Download/copy one, and insert it in your theme root folder.
*
* For Bootstrap 3 see: https://github.com/wp-bootstrap/wp-bootstrap-navwalker/blob/master/wp-bootstrap-navwalker.php
* For Bootstrap 4 see: https://gist.github.com/moso/d2dbdbb278cc016dfd8a4a0930b7e767
*/
require_once('wp_bootstrap_navwalker.php');
To implement it, use the following markup inside your <navbar>
.
Check Bootstrap's documentation for an exact location.
To align the menu to the right, add navbar-right
to 'menu_class'
.
<div class="collapse navbar-collapse" id="navbar-mobile">
<?php
wp_nav_menu( array(
'menu' => 'navbar',
'theme_location' => 'navbar',
'container' => false,
'menu_class' => 'nav navbar-nav',
'fallback_cb' => '__return_false',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'depth' => 3,
'walker' => new WP_Bootstrap_Navwalker()
));
?>
</div>
/*!
* Custom Logo
* This function allows a user to upload a custom logo of their own.
* Adjust the width/height to fit your layout.
*
* Below are two functions that modifies the custom-logo classes to work with Bootstrap navbar markup.
*/
function add_custom_logo() {
$defaults = array (
'default-image' => get_template_directory_uri() . '/images/logo.png',
'uploads' => true,
'width' => '227',
'height' => '60',
'flex-width' => true,
'flex-height' => true
);
add_theme_support('custom-logo', $defaults);
}
add_action('init', 'add_custom_logo');
// Change 'custom-logo-link' class to 'navbar-brand'
function change_brand_class($html) {
$html = str_replace('custom-logo-link', 'navbar-brand', $html);
return $html;
}
add_filter('get_custom_logo','change_brand_class');
// Add 'img-responsive'-class to the logo for better responsiveness
function change_logo_class($html) {
$html = str_replace('custom-logo', 'img-responsive', $html);
return $html;
}
add_filter('get_custom_logo','change_logo_class');
To implement it in your navbar, insert this in <navbar-header>
after the hidden button for the mobile navbar.
This contains a fallback to /images/logo.png
as a placeholder if no custom logo has been uploaded.
if(function_exists('the_custom_logo')) :
if(has_custom_logo()) :
the_custom_logo();
else : ?>
<img src="<?php echo get_template_directory_uri(); ?>/images/logo.png" class="img-responsive" alt="">
<?php endif; ?>
<?php endif; ?>
/*!
* Custom header image
* This function allows the user to upload a custom header image.
* Adjust the width/height below to fit your layout.
*/
function add_custom_header_image() {
$defaults = array(
'default-image' => get_template_directory_uri() . '/images/header.jpg',
'uploads' => true,
'width' => '2560',
'height' => '784',
'flex-width' => true,
'flex-height' => true
);
add_theme_support('custom-header', $defaults);
}
add_action('init', 'add_custom_header_image');
To implement this use the following markup.
This has a fallback image placed in /images/header.jpg
.
<header <?php if(has_post_thumbnail()) : ?> style="background-image: url(<?php the_post_thumbnail_url(); ?>);" <?php else: ?> style="background-image: url(<?php echo get_template_directory_uri(); ?>/images/header.jpg);" <?php endif; ?>>
// header content
</header>
/*!
* Enable featured images in posts
* This function allows a user to upload and select an image as a posts featured image.
* This has been modified so it works on both posts and pages.
*/
function add_featured_image() {
add_theme_support('post-thumbnails', array('post', 'page'));
}
add_action('init', 'add_featured_image');
/*!
* Remove query strings from static resources.
* To get a better score on Pingdom and to work past the cache-busting way WordPress works,
* these functions removes all strings that contains '?ver' or '&ver'.
*/
// Remove strings with '?ver'
function remove_query_strings_1($src) {
$rqs = explode('?ver', $src);
return $rqs[0];
}
if (is_admin()) {
// Remove query strings from static resources disabled in admin
} else {
add_filter('script_loader_src', 'remove_query_strings_1', 15, 1);
add_filter('style_loader_src', 'remove_query_strings_1', 15, 1);
}
// Remove strings with '&ver'
function remove_query_strings_2($src) {
$rqs = explode('&ver', $src);
return $rqs[0];
}
if (is_admin()) {
// Remove query strings from static resources disabled in admin
} else {
add_filter('script_loader_src', '_remove_query_strings_2', 15, 1);
add_filter('style_loader_src', '_remove_query_strings_2', 15, 1);
}
/*!
* Custom Widget Area example
* Below are two examples on how to create custom widget areas.
* The first one is a clean one, the second is an example on how to implement
* Bootstrap's Modals, so one could fill in a modals content in a simple widget.
*/
// CUSTOM WIDGET AREAS
function custom_widget_areas() {
register_sidebar(array(
'name' => __('Top Bar', 'theme_name'),
'id' => 'top-bar-widget',
'before_widget' => '',
'after_widget' => '',
'before_title' => '',
'after_title' => '',
));
register_sidebar(array(
'name' => __('Modal Widget', 'theme_name'),
'id' => 'modal-widget',
'before_widget' => '<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="#modal-title"><div class="modal-dialog" role="document"><div class="modal-content">',
'after_widget' => '</div><div class="modal-footer"><button type="button" class="btn btn-primary close_modal" data-dismiss="modal">Close</button></div></div></div></div>',
'before_title' => '<div class="modal-header"><button type="button" class="close close_modal" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button><h4 class="modal-title" id="modal-title">',
'after_title' => '</h4></div><div class="modal-body">',
));
}
add_action('widgets_init', 'custom_widget_areas');
/*!
* Send comment notification e-mails to a specific e-mail address
*/
function modify_comment_recepient($emails, $comment_id) {
// Adding any email
$emails = array('mail@example.com');
return $emails;
}
add_filter('comment_moderation_recipients', 'modify_comment_recepient', 11, 2);
add_filter('comment_notification_recipients', 'modify_comment_recepient', 11, 2);
/*
* Display Image from the_post_thumbnail or the first image of a post else display a default image.
* Chose the size from "thumbnail", "medium", "large", "full" or your own defined size using filters.
*
* Usage: <?php echo show_post_image(); ?>
*/
function show_post_image($size = 'full') {
if (has_post_thumbnail()) {
$image_id = get_post_thumbnail_id();
$image_url = wp_get_attachment_image_src($image_id, $size);
$image_url = $image_url[0];
} else {
global $post, $posts;
$image_url = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
$image_url = $matches [1] [0];
//Defines a default image
if(empty($image_url)){
$image_url = get_bloginfo('template_url') . "/images/default.jpg";
}
}
return $image_url;
}