• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

nSiteful Web Builders

Building a Better Web - One Site at a Time.

  • Home
  • About
    • Testimonials
    • Resources
    • Partner With Me
    • Frequently Asked Questions
  • Web Sites
  • Online Marketing
  • WordPress Support
    • Customized WordPress Training
    • 60-for-60 Sessions
  • Web Applications
  • Blog
    • At-A-Glance
    • Blog Articles Grouped by Category
    • Case Studies
    • General
    • Portfolio
    • Reviews
    • Snippets
    • Techniques
    • Projects
  • Contact
    • Purchase Retainer Consulting Hours
    • About Retainer Consulting Hours
    • Book a Meeting with Jeff
    • Tell Me About Your Web Project
    • nSiteful Newsletter Archives
    • nSiteful Rewards

By Jeff - 7/26/2013
Cats: Case Studies · Tags: MySQL, php, WordPress

case-studies

Case Study: Emergency Notice Banner for Hybrid Web site

Last updated August 7th, 2015 at 10:17 am

Eaton Academy’s Web site (EatonAcademy.org) is just one of many hybrid projects I’ve built over the years. Namely, the main section of site is custom-built using generous doses of PHP and MySQL for templating while the blog section is built on WordPress. The two sections are visually integrated but fundamentally independent from a functional standpoint.

When Eaton co-founder Brian Uitvlugt wanted me to implement an emergency announcement banner that would appear at the top of all pages of the site (for school closing information and such), he was issuing an interesting and fun challenge.

One option would have been to extend the functionality of the already-existing custom (non-WordPress) Intranet system. I could have added a form through which Brian and other authorized users could add, edit, and delete the notices (along with associated database modifications to store and serve the information). Then I could customize both the main site’s templates and the blog’s templates to display the notices to the public.

Instead, I suggested (and Brian agreed) that we leverage WordPress for the job.

The end result

We launched the banner feature in December of 2012, in anticipation of school closings, late openings, or early dismissals due to extreme weather.

I had almost forgotten about the little-used feature (as had Brian) until today — when the school’s email system went down. Here’s what the Web site looks like at the time of this writing.

Banner on Main Site

Eaton Banner Main Site
Banner as it appears on main section of Web site

Banner Announcement on index page of blog

Here's how the announcement appears on the blog's home page
Here’s how the announcement appears on the blog’s home page

Banner Announcement on single page of blog

Here's how the banner announcement looks on the single page for the article
Here’s how the banner announcement looks on the single page for the article

Functional Specs

Here’s the general approach we took.

  1. We agreed to create a special new WordPress post category called “Banner”. A blog post MUST be assigned to the “Banner” category to be used in the site’s banner.
  2. Only the MOST RECENT blog post assigned to the “Banner” category will be used in the banner.
  3. Optionally, the post should be marked as a STICKY post. This will ensure that it appears as the first post in the blog’s main index page, even if another post has a more recent publication date.
  4. To remove a banner from the public-facing Web site, an authorized user would perform one of the following actions in the WordPress dashboard:
    1. delete the post
    2. change the post’s STATUS to ‘Draft’ or ‘Pending Review’
    3. change the post’s VISIBILITY to ‘Password Protected’ or ‘Private’

Technical Specs

For the techies in the audience, here are some details of how I put the nuts and bolts together. I’m not going to get heavy into explaining the code because (a) you might not care or (b) you might be able to figure it out yourselves. If you do wonder why I’m doing what I’m doing (or if you have a better way), please feel free to post in the comments, and I’ll be happy to respond.

Function to get post data array

Since I’m working outside of WordPress, I couldn’t use WordPress’ internal query methods to grab the post data. Hence the multi-table SQL query code with a fairly involved “where” clause involving the wp_terms, wp_term_taxonomy, and wp_term_relationships tables.

This function (get_blog_posts_recent()) gets and returns a nested array of posts that meet the selection criteria passed in a single line of code in the header template of the main site (keep reading for that).

function get_blog_posts_recent($args=array()) {
	$defaults = array(
		'table' => 'wp_posts',
		'fields' => array('ID', 'post_title', 'post_date', 'guid'),
		'category' => '',
		'limit' => '1'
	);
	$r = array_merge($defaults, $args); 
	extract($r);
	
	// When category is specified:
	if ( !empty($category) ) {
		$new_fields = array();
		for ( $i=0, $n=count($fields); $i<$n; $i++ ) {
			$new_fields[] = 't1.' . $fields[$i];
		}
		$field_list = implode(', ', $new_fields);
		
		$sql = "select " . $field_list . 
		", t3.name 
		from " . $table . " as t1, 
		wp_term_relationships as t2,
		wp_terms as t3,
		wp_term_taxonomy as t4
		
		where t1.post_status = 'publish' 
		and t1.post_type = 'post' 
		and t1.ID = t2.object_id 
		and t2.term_taxonomy_id = t4.term_taxonomy_id 
		and t4.term_id = '$category' 
		and t3.term_id = '$category'
		order by t1.post_date desc limit $limit";
	} else {
		// ANY category:
		$field_list = implode(', ', $fields);
		$sql = "SELECT " . $field_list . " FROM " . $table . " 
		where post_status = 'publish' and post_type = 'post' 
		order by post_date desc limit $limit";
	}
	$result = mysql_query($sql);
	if ( !mysql_num_rows($result) ) return false;
	// Else...
	$data = array();
	while ( $record = mysql_fetch_assoc($result) ) {
		$data[] = $record;
	}
	return $data;
}

[PS/Update for fellow geeks: I just finished reading Andrew Nacin’s recent post at Make WordPress Core entitled Potential roadmap for taxonomy meta and post relationships. If the ideas in that post are implemented (especially the elimination of the wp_terms table), that multi-table join in the code above could be simplfied considerably. We can hope…]

Is there a post that matches the selection criteria?

This function (eaton_banner_exists()) calls the one above. If there’s no post whose category id is associated with the passed category id, then we can just quit (the good old return false (line 10). Otherwise, go get it or them.

function eaton_banner_exists($category, $limit, $fields) {
	$conn_link = banner_conn();
	if ( $data = get_blog_posts_recent( array ('category' => $category, 'limit' => $limit, 'fields' => $fields ) ) ) {
		mysql_close($conn_link);
		include(SITE_INCLUDES_PATH . 'dbconn.php');
		return $data;
	} else {
		mysql_close($conn_link);
		include(SITE_INCLUDES_PATH . 'dbconn.php');
		return false;
	}
}

Function that looks for the most recent banner post

This function (eaton_banner()) uses the hard-coded category id that corresponds to “Banner” (’56’) and specifies a limit of 1 post to grab. It also passes an array of field names to be selected in the eaton_banner_exists() function.

function eaton_banner( $category_id = '56', $limit = '1' ) {
	$fields = array('ID', 'post_title', 'post_date', 'guid', 'post_content');
	if ( $data = eaton_banner_exists( $category_id, $limit, $fields ) ) {
		//echo_r($data, 'Banner test');
		return $data;
	} else {
		return false;
	}
}

The one-line call in the main site’s header template

I added this one-line script to the header template. If the eaton_banner() function finds and returns a post in the “Banner” category, then we’ll include a simple file at the top of the page. Otherwise, we’ll do nothing.

<?php if ( $banner_content = eaton_banner() ) include(SITE_INCLUDES_PATH . 'inc_banner.php'); ?>

Finally, the include file for the main section of the site

This is the simple HTML (with a little bit of interspersed PHP) that makes the banner display, if it indeed exists. Some CSS markup makes the banner appear inside a centered, bordered box at the very top of each page of the main site.

<?php 
	extract($banner_content[0]);
?>
<div class="eaton-banner">
	<div class="inner">
		<h1><?php echo $post_title;?></h1>
		<div class="text">
			<?php echo nl2br($post_content);?>
		</div>
	</div><!-- .inner -->
</div><!-- .eaton-banner -->

Conclusion

If the Eaton Web site were completely built on WordPress, adding an announcement banner to all pages of the site would have been extremely simple. I probably would have used a plugin like iTheme’s Boom Bar.

But a hybrid Web site needn’t pose insurmountable obstacles. With a little bit of mental elbow grease — and just the right amount of knowledge of PHP, MySQL, and the WordPress database structure, one can accomplish all kinds of nifty things.

Like what you see? Share with others and join my mailing list. No long-term commitment, unsubscribe any time.

Related Posts

  1. PHP, MySQL: Get From Foreigner (utility function)
  2. Use Custom Fields to Hide Stale Posts
  3. How to add an About Us blurb to every WordPress blog post
  4. PHP OOP Virtual Study Group?
  5. Automatic “Visit Web Site” Links on WordPress Portfolio Posts

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

mailchimp signup

Subscribe to get notified when new articles are published. Unsubscribe any time. No spam. I promise. Check out my newsletter archives.

social

Twitter Facebook LinkedIn

Recent Articles

  • Post-Specific CSS for WordPress October 5, 2026
  • You built an online course, but they haven’t come. September 16, 2026
  • Custom MemberPress Pricing Pages December 19, 2025
  • CSS Data Attribute Override December 11, 2025
  • MemberPress Rules Using Custom Taxonomies and Custom Roles December 10, 2025

Filter By Category/Tag

Categories

  • Case Studies (8)
  • For Staff (1)
  • General (73)
  • Portfolio (7)
  • Reviews (14)
  • Snippets (24)
  • Techniques (52)

Popular Tags

Advanced Custom Fields Blogging Child Themes Content Marketing CSS Customer Service Custom Fields Custom Post Types Diagnostics Domain Names Facebook FooGallery Genesis Hosting HTML Images iPhone Libra Live Chat Marketing Media MemberPress MemberPress Courses Membership Sites Mobile-Friendly MySQL Photo Gallery php Pinterest Plugins Post Formats Pricing Project Management SEBA SEO Seth Godin Shortcodes Social Networking Surveys Taxonomies Twitter Video Web design Web forms WordPress

Footer

Background

Web Sites | WordPress Support | Web Applications.

Formally trained in liberal arts and education (I have a B.A. in Government from Harvard and studied Secondary Education at Rutgers Graduate School), I have honed my skills in the communication arts and sciences as a teacher, trainer, instructional designer, writer, photographer, calligrapher, helpdesk manager, database programmer, and multimedia developer.

(I've also been a group counselor, waiter, bartender, bicycle messenger boy, computer salesman, carpenter's helper, financial analyst, and school board president.)

Tech

Systems since 1983.
Web sites since 1994.
PHP since 2001.
WordPress since 2007.

Contact

Book Meeting
770-772-5134
Email Jeff
Send Money
All Ways

Copyright 2026, nSiteful Web Builders, Inc.

Cookies Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
View preferences
  • {title}
  • {title}
  • {title}
https://iframe.mediadelivery.net/embed/392008/42d18bc1-2adc-4741-b733-053d08d09c32
https://vz-000c5976-3ab.b-cdn.net/42d18bc1-2adc-4741-b733-053d08d09c32/play_720p.mp4

Receive occasional emails from Jeff