WordPress can be customized easily and that is the beauty of it, that you can adapt it to whatever purpose you would want your site to have. If you don’t like something about it you will always have the option to change it. The easiest way to do that is by using a plugin, but if you would be using a plugin for every little thing that you need you would end up with a lot of plugins and that is never recommended.
Try to use plugins just for the complicated actions that you can’t customize yourself. If there some small modification that you want to make to the theme, just do it yourself in the code, don’t use a plugin for it, instead use a snippet. WordPress snippets are some of the best things that you can find online related to WordPress customization. There’s a little modification that can be made for almost every customization that you can think of.
In this article you will see WordPress code snippets for a few interesting problems, not the regular ones that you see almost everywhere posted. I hope these will help you as much as they helped me.
These all go into the functions.php file. I know it might look silly to some of you that I mentioned this, but there are also WordPress beginners and might not know it.
Pagination for Twitter Bootstrap
<?php
// Numeric 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.'<div class="pagination"><ul class="clearfix">'."";
if ($paged > 1) {
$first_page_text = "«";
echo '<li class="prev"><a href="'.get_pagenum_link().'" title="First">'.$first_page_text.'</a></li>';
}
$prevposts = get_previous_posts_link('← Previous');
if($prevposts) { echo '<li>' . $prevposts . '</li>'; }
else { echo '<li class="disabled"><a href="#">← Previous</a></li>'; }
for($i = $start_page; $i <= $end_page; $i++) {
if($i == $paged) {
echo '<li class="active"><a href="#">'.$i.'</a></li>';
} else {
echo '<li><a href="'.get_pagenum_link($i).'">'.$i.'</a></li>';
}
}
echo '<li class="">';
next_posts_link('Next →');
echo '</li>';
if ($end_page < $max_page) {
$last_page_text = "»";
echo '<li class="next"><a href="'.get_pagenum_link($max_page).'" title="Last">'.$last_page_text.'</a></li>';
}
echo '</ul></div>'.$after."";
}
?>
Insert this snippet in your functions.php. It creates a numbered page navigation menu using Twitter Boostrap native CSS classes. Use in your template files by calling the function
page_navi();
Github Gist shortcode
This code snippet will detect links to Github Gist in posts and replace them with shortcodes and then shortcodes will be replaced with embedded gist. Just add the code to your functions.php
<?php
// [gist id="ID" file="FILE"]
function gist_shortcode($atts) {
return sprintf(
'<script src="https://gist.github.com/%s.js%s"></script>',
$atts['id'],
$atts['file'] ? '?file=' . $atts['file'] : ''
);
} add_shortcode('gist','gist_shortcode');
// Remove this function if you don't want autoreplace gist links to shortcodes
function gist_shortcode_filter($content) {
return preg_replace('/https:\/\/gist.github.com\/([\d]+)[\.js\?]*[\#]*file[=|_]+([\w\.]+)(?![^<]*<\/a>)/i', '[gist id="${1}" file="${2}"]', $content );
} add_filter( 'the_content', 'gist_shortcode_filter', 9);
?>
Formats:
https://gist.github.com/1147076
https://gist.github.com/1147076#file_annotated.js
https://gist.github.com/1147076.js?file=annotated.js
[gist id=1147076]
[gist id=1147076 file=annotated.js]
This works perfectly in most cases but there is one(or more?) case when it doesn’t work as it should:
https://gist.github.com/1147076#file_license.txt
If we add this url to our post it will display all files from this gist. It’s because file name in gist is uppercased. But this one will work corectly:
https://gist.github.com/1147076.js?file=LICENSE.txt
Automatically set the featured image
If you set a featured image, then that will be the featured image, otherwise, the first one of the article will be set as featured image.
<?php
function autoset_featured() {
global $post;
$already_has_thumb = has_post_thumbnail($post->ID);
if (!$already_has_thumb) {
$attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
if ($attached_image) {
foreach ($attached_image as $attachment_id => $attachment) {
set_post_thumbnail($post->ID, $attachment_id);
}
}
}
} //end function
add_action('the_post', 'autoset_featured');
add_action('save_post', 'autoset_featured');
add_action('draft_to_publish', 'autoset_featured');
add_action('new_to_publish', 'autoset_featured');
add_action('pending_to_publish', 'autoset_featured');
add_action('future_to_publish', 'autoset_featured');
?>
Source
Breadcrumbs without plugin
<?php
function the_breadcrumb() {
echo '<ul id="crumbs">';
if (!is_home()) {
echo '<li><a href="';
echo get_option('home');
echo '">';
echo 'Home';
echo "</a></li>";
if (is_category() || is_single()) {
echo '<li>';
the_category(' </li><li> ');
if (is_single()) {
echo "</li><li>";
the_title();
echo '</li>';
}
} elseif (is_page()) {
echo '<li>';
echo the_title();
echo '</li>';
}
}
elseif (is_tag()) {single_tag_title();}
elseif (is_day()) {echo"<li>Archive for "; the_time('F jS, Y'); echo'</li>';}
elseif (is_month()) {echo"<li>Archive for "; the_time('F, Y'); echo'</li>';}
elseif (is_year()) {echo"<li>Archive for "; the_time('Y'); echo'</li>';}
elseif (is_author()) {echo"<li>Author Archive"; echo'</li>';}
elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {echo "<li>Blog Archives"; echo'</li>';}
elseif (is_search()) {echo"<li>Search Results"; echo'</li>';}
echo '</ul>';
}
?>
And for the function to be called, use the following code in the page that you want.
<?php the_breadcrumb(); ?>
Keep WordPress from compressing JPGs
<?php
add_filter('jpeg_quality', function($arg){return 100;});
?>
Source
Extend search to include custom post meta
<?php
/*
* Extend wp search to include custom post meta
*/
function custom_search_query( $query ) {
if ( !is_admin() && $query->is_search ) {
$query->set('meta_query', array(
array(
'key' => '__meta_key__',
'value' => $query->query_vars['s'],
'compare' => 'LIKE'
)
));
$query->set('post_type', '__your_post_type__'); // optional
};
}
add_filter( 'pre_get_posts', 'dc_custom_search_query');
?>
Add links to WordPress 3.3 New Toolbar
<?php
add_action('admin_bar_menu', 'add_toolbar_items', 100);
function add_toolbar_items($admin_bar){
$admin_bar->add_menu( array(
'id' => 'my-item',
'title' => 'My Item',
'href' => '#',
'meta' => array(
'title' => __('My Item'),
),
));
$admin_bar->add_menu( array(
'id' => 'my-sub-item',
'parent' => 'my-item',
'title' => 'My Sub Menu Item',
'href' => '#',
'meta' => array(
'title' => __('My Sub Menu Item'),
'target' => '_blank',
'class' => 'my_menu_item_class'
),
));
$admin_bar->add_menu( array(
'id' => 'my-second-sub-item',
'parent' => 'my-item',
'title' => 'My Second Sub Menu Item',
'href' => '#',
'meta' => array(
'title' => __('My Second Sub Menu Item'),
'target' => '_blank',
'class' => 'my_menu_item_class'
),
));
}
?>
Add custom image sizes to media insert dialog
<?php
if ( function_exists( 'add_image_size' ) ) {
add_image_size( 'new-size', 300, 100, true ); //(cropped)
}
add_filter('image_size_names_choose', 'my_image_sizes');
function my_image_sizes($sizes) {
$addsizes = array(
"new-size" => __( "New Size")
);
$newsizes = array_merge($sizes, $addsizes);
return $newsizes;
}
?>
Source
Different admin and theme languages
Don’t define WPLANG in wp-config. That’s really silly. Try this instead.
<?php
// setup one language for admin and the other for theme
// must be called before load_theme_textdomain()
function set_my_locale($locale) {
$locale = ( is_admin() ) ? "en_US" : "it_IT";
setlocale(LC_ALL, $local );
return $locale;
}
add_filter( 'locale', 'set_my_locale' );
?>
Change default from address
<?php
add_filter('wp_mail_from', 'new_mail_from');
add_filter('wp_mail_from_name', 'new_mail_from_name');
function new_mail_from($old) {
return 'no-reply@example.com';
}
function new_mail_from_name($old) {
return 'Dave Thomas';
}
?>
Truncate post title
<?php
function customTitle($limit) {
$title = get_the_title($post->ID);
if(strlen($title) > $limit) {
$title = substr($title, 0, $limit) . '...';
}
echo $title;
}
?>
When you’re in need of truncating a title, call:
customTitle(50)
Where (50) is the number of Characters it allows before truncating.
Simple HTML in widget title
The snippet makes it possible to use (type [s] and [/s] in widget title) and (type [e] and [/e] in widget title) tags only but other HTML tags can be added easily if you want to.
<?php
function html_widget_title( $title ) {
//HTML tag opening/closing brackets
$title = str_replace( '[', '<', $title );
$title = str_replace( '[/', '</', $title );
//<strong></strong>
$title = str_replace( 's]', 'strong>', $title );
//<em></em>
$title = str_replace( 'e]', 'em>', $title );
return $title;
}
add_filter( 'widget_title', 'html_widget_title' );
?>
Post views without plugin
<?php
// function to display number of posts.
function getPostViews($postID){
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
return "0 View";
}
return $count.' Views';
}
// function to count views.
function setPostViews($postID) {
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}
// Add it to a column in WP-Admin
add_filter('manage_posts_columns', 'posts_column_views');
add_action('manage_posts_custom_column', 'posts_custom_column_views',5,2);
function posts_column_views($defaults){
$defaults['post_views'] = __('Views');
return $defaults;
}
function posts_custom_column_views($column_name, $id){
if($column_name === 'post_views'){
echo getPostViews(get_the_ID());
}
}
?>
After that add this to single.php
<?php setPostViews(get_the_ID()); ?>
And to display the number of views a post has, add this where you want it to be displayed:
<?php echo getPostViews(get_the_ID()); ?>
Source
Exclude category from homepage
<?php
function excludeCat($query) {
if ( $query->is_home ) {
$query->set('cat', '-3,-5,-23');
}
return $query;
}
add_filter('pre_get_posts', 'excludeCat');
?>
Load jQuery in footer
<?php
/**
* Prints jQuery in footer on front-end.
*/
function ds_print_jquery_in_footer( &$scripts) {
if ( ! is_admin() )
$scripts->add_data( 'jquery', 'group', 1 );
}
add_action( 'wp_default_scripts', 'ds_print_jquery_in_footer' );
?>
Source
Include future posts in RSS feed
Correct scheduled posts do not appear in the rss feed. With this function it will include your scheduled posts in the rss feed. However, it will not be found if clicked.
<?php
/* Include published and future posts in rss feed. */
function FuturePostsFeed($query) {
if ($query->is_feed) {
$query->set('post_status','publish,future');
}
return $query;
}
add_filter('pre_get_posts','FuturePostsFeed');
?>
Restrict user access
With this snippet you can create a page template restricted only to those users with the right role to access to it.
<?php
/* Template Name: Restricted to Authors only */
if ( !current_user_can('author')) {
include('error.php');
exit(0);
}
?>
.htaccess Gzip compression
Compression reduces response times by reducing the size of the HTTP response. Gzip is the most popular and effective compression method currently available and generally reduces the response size by about 70%. Approximately 90% of today’s Internet traffic travels through browsers that claim to support gzip.
You’ll have to add this code to the .htaccess file:
<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>
or
# BEGIN GZIP
<ifmodule mod_deflate.c>
AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript
</ifmodule>
# END GZIP
Source
Schedule cron jobs with WordPress
<?php
add_action('my_hourly_event', 'do_this_hourly');
function my_activation() {
if ( !wp_next_scheduled( 'my_hourly_event' ) ) {
wp_schedule_event(time(), 'hourly', 'my_hourly_event');
}
}
add_action('wp', 'my_activation');
function do_this_hourly() {
// do something every hour
}
?>
More info in cron jobs here
Custom admin CSS
You can change the default style of WordPress admin area by overriding the old stylesheet. To do this, you have to create a new css file in your theme folder, and then include it in WP-Admin using the admin_head hook.
<?php
function customAdmin() {
$url = get_settings('siteurl');
$url = $url . '/wp-content/themes/my-theme/styles/wp-admin.css';
echo '<!-- custom admin css -->
<link rel="stylesheet" type="text/css" href="' . $url . '" />
<!-- /end custom adming css -->';
}
add_action('admin_head', 'customAdmin');
?>
Enable threaded comments
WordPress has support for threaded comments, but you have to enable it yourself by adding a script to your head. You can use WordPress built in function wp_enqueue_script () to load the script, by adding this snippet to your functions.php.
When the script is loaded, you have to activate the threaded comments in the settings tab in WordPress admin, under Settings > Discussion. Click Enable threaded (nested) comments and choose the level of nested comments you want.
<?php
function enable_threaded_comments(){
if (is_singular() AND comments_open() AND (get_option('thread_comments') == 1)) {
wp_enqueue_script('comment-reply');
}
}
add_action('get_header', 'enable_threaded_comments');
?>
Remove update notification for regular users
This hides the update message that is displayed when there is a new version of WordPress available.
<?php
if ( !current_user_can('administrator') ) {
add_action( 'init', create_function( '$a', "remove_action( 'init', 'wp_version_check' );" ), 2 );
add_filter( 'pre_option_update_core', create_function( '$a', "return null;" ) );
}
?>
Limit amount of post revisions
Why? Because post revisions can inflate your database at an annoying pace so you have to stop this. Paste this code in wp-config
# Maximum 5 revisions #
define('WP_POST_REVISIONS', 5);
# Disable revisions #
define('WP_POST_REVISIONS', false);
Code in posts without a plugin
To use this little hack, simply put the code between [ code ] and [ /code ] (without spaces).
<?php
function bbcode( $attr, $content = null ) {
$content = clean_pre($content); // Clean pre-tags
return '<pre"><code>' .
str_replace('<', '<', $content) . // Escape < chars
'</code></pre>';
}
add_shortcode('code', 'bbcode');
?>
Disable Google Analytics for logged in users
This snippet automatically adds the Google Analytics code to your footer area (in case wp_footer () is called), so you don’t have to manually insert the Analytics code to all your files.
<?php
// function for inserting Google Analytics into the wp_head
add_action('wp_footer', 'ga');
function ga() {
if ( !is_user_logged_in() ) { // not for logged in users
?>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX']); // insert your Google Analytics id here
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<?php
}
}
?>
Custom feed footer without a plugin
<?php
if ( !function_exists('custom_feed_footer') )
{
function custom_feed_footer($content)
{
if(is_feed())
$content .= 'Your text';
return $content;
}
add_filter('the_excerpt_rss', 'custom_feed_footer');
add_filter('the_content', 'custom_feed_footer');
}
?>