Post

WordPress Code Snippets

Hide ACF Fields on Production

Prevents ACF fields being overwritten on deploy and stops clients deleting fields in production.

Add to functions.php, update the protected URLs:

1
2
3
4
5
6
7
8
9
10
11
add_filter(
	'acf/settings/show_admin',
	function () {
		$site_url = get_bloginfo( 'url' );
		$protected_urls = array(
			'https://staging.cloud',
			'https://live.com.au',
		);
		return ! in_array( $site_url, $protected_urls );
	}
);

ACF local json

Custom Excerpt Length

1
2
3
4
function custom_excerpt_length( $length ) {
	return 20;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );

Custom Excerpt More

Change the excerpt link based on post type:

1
2
3
4
5
6
7
8
function new_excerpt_more( $more ) {
    if ('testimonials' == get_post_type()) {
          return ' <br /><a class = "more" href="'. get_permalink(isset($post->ID)) . '"> View</a>';
    } else {
          return ' <br /><a class = "more" href="'. get_permalink(isset($post->ID)) . '"> Read More</a>';
    }
}
add_filter('excerpt_more', 'new_excerpt_more');

Put WordPress into Maintenance Mode

Add to functions.php:

1
2
3
4
5
6
function wp_maintenance_mode() {
   if (!current_user_can('edit_themes') || !is_user_logged_in()) {
     wp_die('<h1>Under Maintenance</h1><br />Website under planned maintenance. Please check back later.');
   }
}
add_action('get_header', 'wp_maintenance_mode');

WordPress Query Post Loops

Basic loop

Uses the default query WordPress already ran for the current page. No custom arguments — outputs whatever posts the current URL context returns (archive, category, search etc.).

1
2
3
4
5
6
7
8
9
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

	<h2><?php the_title() ;?></h2>
	<?php the_post_thumbnail(); ?>
	<?php the_excerpt(); ?>

<?php endwhile; else: ?>
	<p>Sorry, no posts to list</p>
<?php endif; ?>

Advanced loop

Still uses the default query but outputs more post data — post ID, date, category, full content, comment form, and prev/next navigation. Adds a featured-post class if the post is in the featured category.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

<article id="post-<?php the_ID(); ?>" <?php if(is_category('featured')): ?>class="featured-post"<?php endif; ?>>
	<h1><?php the_title() ;?></h1>		
	<p>
		Published on <?php the_time('M j, Y'); ?> 
		by <?php the_category(', '); ?>
		in <?php the_category(', '); ?>
	</p>
	<?php the_content(); ?>
	<?php comment_form(); ?>
	<div class="prev-next-links">
		<ul>
			<li><?php next_post_link(); ?></li>
			<li><?php previous_post_link(); ?></li>
		</ul>
	</div>
</article>

<?php endwhile; else: ?>
	<p>Sorry, this post does not exist</p>
<?php endif; ?>

Loop using query_posts

Modifies the main query directly. Simple but not recommended for production — it overwrites the global query and can break pagination. Use WP_Query instead for secondary queries.

1
2
3
4
5
6
7
8
9
<?php query_posts('showposts=1&post_type=post'); ?>

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
	<h1><?php the_title() ;?></h1>		
	<?php the_post_thumbnail(); ?>
	<?php the_excerpt(); ?>
<?php endwhile; else: ?>
	<p>Sorry, there are no posts to display</p>
<?php endif; ?>

Loop using WP_Query

Creates a separate query object independent of the main query. The recommended approach for fetching a specific post, page, or set of posts anywhere on the page.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
$args = array( 
	'pagename' => 'about-us'
);
$the_query = new WP_Query( $args );
?>

<?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
	<h1><?php the_title() ;?></h1>			
	<?php the_excerpt(); ?>
<?php endwhile; else: ?>
	<p>Sorry, there are no posts to display</p>
<?php endif; ?>

WP_Query with multiple args

Same as above but demonstrates filtering by author, post type, order, and year simultaneously.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
$args = array( 
	'author_name' => 'zgordon',
	'orderby' => 'title',
	'post_type' => 'workshops',
	'year' => 2012
);
$the_query = new WP_Query( $args );
?>

<?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
	<h1><?php the_title() ;?></h1>			
	<?php the_excerpt(); ?>
<?php endwhile; else: ?>
	<p>Sorry, there are no posts to display</p>
<?php endif; ?>
1
2
3
4
5
6
7
8
9
10
11
12
function my_deregister_styles() {
	wp_deregister_style('parent');
	wp_deregister_style( 'divi-style' );
}
add_action('wp_enqueue_scripts', 'my_deregister_styles', 100);

function pxs_add_footer_styles() {
	$parent_style = 'parent-style';
	wp_enqueue_style( $parent_style, get_template_directory_uri() . '/style.css' );
	wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style') );
};
add_action( 'get_footer', 'pxs_add_footer_styles' );

Create Child Theme

functions.php:

1
2
3
4
5
6
<?php
function child_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array( 'parent-style' ) );
}
add_action( 'wp_enqueue_scripts', 'child_enqueue_styles' );

style.cssTheme Name is the child theme name, Template must match the parent theme’s folder name exactly:

1
2
3
4
5
6
7
8
9
/*
Theme Name:   Parent Theme Name Child
Theme URI:    https://example.com
Description:  Child theme for Parent Theme Name
Author:       Your Name
Author URI:   https://yourwebsite.com
Template:     parent-theme-folder-name
Version:      1.0.0
*/

Move Yoast to Bottom

1
2
3
4
function yoasttobottom() {
	return 'low';
}
add_filter( 'wpseo_metabox_prio', 'yoasttobottom');

Redirect User on Failed Login

1
2
3
4
5
6
7
8
9
10
add_action( 'wp_login_failed', 'my_callback' );
function my_callback() {
	if (! is_user_logged_in()) {
		wp_redirect( 'https://example.com', 301 );
		exit();
	} else {
		wp_redirect( 'https://example.com/login/', 301 );
		exit();
	}
}

Secure Area

Restrict page content to logged-in users:

1
2
3
4
5
6
7
8
9
10
<?php if (is_user_logged_in()) { ?>
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<?php the_content(); ?>
	<?php endwhile; else: ?>
		<?php get_template_part('notfound'); endif; ?>
<?php } else { ?>
	<div class="notification">
		<p>You need to <a href="/wp-login.php?action=register">Register</a> or <a href="/login">Login</a> to view this page.</p>
	</div>
<?php } ?>

Date Counter

Shortcode that calculates the difference between two dates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function DateCounter($atts){
	$startDate = $atts["startdate"];
	$endDate   = strtolower($atts["enddate"]);
	
	switch (strtolower($atts["format"])) {
		case "year":
		case "years":
			$difference = (new DateTime($endDate))->diff(new DateTime($startDate));
			$result = $difference->y;
			break;
		case "month":
		case "months":
			$min_date = min(strtotime($startDate), strtotime($endDate));
			$max_date = max(strtotime($startDate), strtotime($endDate));
			$i = 0;
			while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) { $i++; }
			$result = $i;
			break;
		case "day":
		case "days":
			$result = floor((strtotime($endDate) - strtotime($startDate)) / (60*60*24));
			break;
		case "currentyear":  $result = date("Y"); break;
		case "currentmonth": $result = date("m"); break;
		case "currentday":   $result = date("d"); break;
	}
	return $result;
}
add_shortcode( 'DateCounter', 'DateCounter' );
1
2
3
4
<?php if ( has_post_thumbnail()) { 
	$image_src = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
	echo '<img src="' . $image_src[0] . '" width="100%" />';
} ?>

Enable Gutenberg for Custom Post Type

Key args are 'show_in_rest' => true and including 'editor' in supports:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function register_events_cpt() {
    $args = array(
        'labels'             => array(
            'name'          => 'Events',
            'singular_name' => 'Event',
        ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'show_in_rest'       => true,
        'has_archive'        => true,
        'rewrite'            => array( 'slug' => 'events' ),
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
    );
    register_post_type( 'events', $args );
}
add_action( 'init', 'register_events_cpt' );
This post is licensed under CC BY 4.0 by the author.