WordPress

NETBibleTagger For WordPress

By michael  |  December 1st, 2010  |  Published in WordPress, WordPress Plugins  |  Comments Off

I came across this nice little piece of JS today by Bible.org called NETBible Tagger when an elder at the church I attend requested that I add it to our web site. In short, it “Automatically Tag and Quote Scripture References on Your Site”.

The developer has done a great job, adding several options to allow you to configure it as desired. While there are some widgets and modules for other CMS platforms out there, I didn’t see one for WordPress so I thought I’d draft one up real quick.

As always, this was created for a client and I don’t have a ton of time to keep up with most of my plugins right now. If you find a bug, let me know though.

== Changelog ==
* 1.1 – Minor tweak to make work in all webkit browsers
* 1.0 – Initial Release

== Installation ==
1. Upload the entire `ft-netbible-tagger` folder to your `/wp-content/plugins/` folder.
2. Go to the ‘Plugins’ page in the menu and activate the plugin.
3. Navigate to Settings -> NETBible Tagger in your WordPress dashboard to customize the settings.

== Download ==
You can download it here until its accepted at the WordPress plugin repo

== Screenshot ==

Quickly Add a Single 301 Permanent Redirect to WordPress

By michael  |  June 22nd, 2010  |  Published in WordPress  |  1 Comment

Alan Knox, the developer of our FacePress plugin that automatically publishes WordPress posts to Facebook recently left FullThrottle to start his own Web Design company. We’re really excited about where he is going and about the sites that he already has in development.

When he left, we mutually agreed to send his FacePress plugin with him (its his baby and he’s best qualified to support and enhance it). In doing so, we needed to create a permanent 301 redirect for the support page but we didn’t want to install a plugin that included an admin panel, etc. Instead, we elected to put this short code in our theme’s functions.php file.

Please feel free to take and modify as needed. Only one condition: if you have a way to improve this, please share in the comments!

// Permanantly Redirect FacePress Plugin
function permanent_301_redirect_facepress() {
	if ( isset( $_SERVER['REQUEST_URI'] ) && '/facepress-ii' == $_SERVER['REQUEST_URI'] || '/facepress' == $_SERVER['REQUEST_URI'] ) {
		header( 'HTTP/1.1 301 Moved Permanently' );
		wp_redirect( 'http://knoxwebdev.com/facepress-ii' );
		exit();
	}
}
add_action( 'template_redirect', 'permanent_301_redirect_facepress' );

Test it by going to http://fullthrottledevelopment.com/facepress-ii!

Global 404 for WPMU or WP Multi Sites

By michael  |  June 22nd, 2010  |  Published in WordPress  |  Comments Off

I quickly drafted the following code in response to this tweet:

I really really really really want a MU universal 404 file.less than a minute ago via TweetDeck

function global_404() {
	if ( is_404() ){
		wp_redirect( 'http://site.com/global404' );
		die();
	}
}
add_action( 'template_redirect', 'global_404' );

If placed inside a plugin that is activated on every site in your network, the above code will do the following:

  1. Determine that the user looked for a page that didn’t exist.
  2. Redirect to a URL of your choice, regardless of the site that they are currently viewing.

Remove Tool Tips (Titles) from Category and Page lists

By michael  |  June 15th, 2010  |  Published in WordPress  |  5 Comments

The following code, placed in your WordPress theme’s functions.php file will strip the title attribute from wp_list_categories, wp_list_pages. The custom menu widgets and code don’t seem to output titles.

This request was made by a client. I have no idea how many people are interested in it, but here it is:

function ft_rtt_remove_title_attribute( $output ){
$output = preg_replace('/title=\"(.*?)\"/','',$output);
return $output;
}
add_filter('wp_list_categories','ft_rtt_remove_title_attribute');
add_filter('wp_list_pages','ft_rtt_remove_title_attribute');

Contributing to WordPress Makes You a Better Developer

By michael  |  May 24th, 2010  |  Published in WordPress  |  10 Comments

trac-logo I have been a passive member of the WordPress developer community for about two years now. Understandably, my familiarity with WordPress and my efficiently in developing for that platform have both increased with time.

My first real tipping point in efficient development came with a better understanding of how the wp-content folder interacts with the rest of the core files. This was ground breaking for me and it almost immediately ‘powered up’ my WordPress related development.

Over the past several months I have been experiencing a second surge in both my level of understanding and my efficiency in WordPress development. This is directly related to my involvement in the WordPress 3.0 development cycle. I wanted to quickly share four aspects of this process that have helped me increase efficiency in my overall WordPress development. It’s my hope that this encourages you to jump in and contribute as well.

Familiarity with new tools and technologies
WordPress.org manages their code base in a web application named Trac. Trac is an opensource software that integrates SVN and ticket based bug reporting. You can view the WordPress installation for the core files here: http://core.trac.wordpress.org. Although I had a basic understanding of what Trac was and knew where it existed online, my interactions with it were in the single digit range (and less than 1).

Trac
It is impossible to seriously contribute to WordPress core as a developer without diving into Trac. It was intimidating for me to do so at first, but has proven well worth the learning curve it took to become comfortable with the process of creating tickets, creating patches, and submitting them for review and possible inclusion into WordPress.

  • Taking the time to understand how the WordPress community uses Trac in our development process has increased my efficiency in the following ways:
  • Comments in the individual tickets help me understand why specific changes were made in the code.
  • Milestones help me to better judge what features and bug fixes will be included in future releases.
  • The ability to browse existing tickets and submitted patches help me to determine legitimate bugs and discover possible solutions.
  • The ability to navigate revisions in an intelligent GUI using the power of Annotate helps me track down unresolved bugs more quickly.

SVN
Although I was already familiar with SVN due to the plugin repository and other non-WordPress related projects, contributing to WP core has substationaly increased the frequency at which I find myself using it. Increased use inevitably leads to increased knowledge and efficiency with any tool.

A better awareness of WordPress community
Possibly the greatest benefit I have gleaned from my involvement in contributing to WordPress is a greater awareness of who the WordPress community includes. Prior to contributing to comments and patches on Trac and finding a suitable IRC client, I didn’t know who Andrew Nacin, Ptah Dunbar, Austin Matzko even existed… let alone understand their contributions to WordPress. These are only a few names that immediately come to my mind… several more exist.

Its funny how you think you know ‘who’ a community is because you’re following a couple mailing lists or a couple of opinionated talkers on Twitter. Getting plugged into the development process has opened me up to a whole new world of very intelligent individuals that I continue to learn from by listening in on their conversations. My coding has become more efficient due to the little tidbits of information I skim off of their public discussions every day.

Familiarity with More of the Core Functionality
Troubleshooting your own code inevitably leads you to a greater understanding of the code surrounding it and supporting it… troubleshooting somebody else’s code multiplies this effect several times over. I’m pretty familiar with the WordPress core files, but diving into Trac and hunting down bugs that can only be reproduced by a remote set of users have taken me to places in the codebase that I never would have found otherwise. I can’t tell you the number of times I’ve been hunting down a specific bug and ran across an amazing function that I was previously unaware existed. Finding all these hidden jewels and obtaining a better understanding of how different functions work within WordPress has largely increased my development on a day to day basis.

Coding Standards
I’m pretty anal about the way my code looks. I try to document as much as possible while I develop it. Additionally, all my code is formatted the same way to increase comprehension if I have to dive back into a file months or years after initially creating it. With this being said, I still have several habits that are less than productive in the long run… my guess is that you’re just as lazy.

WordPress has a guide sheet dictating what coding standards should be followed when contributing to the core software. Many of these standards are nothing more than the lead developers collaborative opinions. The standards are not ‘right’ or ‘wrong’ in any global or authoritative manner… rather, they’re simply the way that WordPress has determined to standardize its code base.

This has been helpful to me because it has encouraged me to clean up some less than standard areas in my own code. Once you work on a couple large patches it becomes natural to start applying those standards to your own work. Again, I’m not suggesting that you have to accept these standards as rule in your personal development… but I am reporting that once I got past the basic control issues I had with not doing things the way I previously did them, adopting many of the WordPress coding standards has actually increased my overall efficiency… a result that I am always happy to discover.

Conclusion and Resources
When I first ventured into the world of WordPress Trac it was with a very utilitarian purpose… I had a problem and I needed it fixed. Two months later, I’m still there and its extremely addictive. Contributing to WordPress core has introduced me to new technologies, new friends, and it continues to increase my efficiency in day to day development. If you’re a WordPress developer and you’ve yet to jump into core contribution, I would highly encourage you to start today. Here are some resources to get you started:

Remove Username Character Limit from WordPress Multi-Site / Multi-User

By michael  |  May 13th, 2010  |  Published in WordPress, WordPress Plugins  |  15 Comments

I’ve been working on a pretty complex project with WordPress MultiUser (soon to be MultiSite). This client needs several sites with hundreds of users divided into each site. I will be integrating the backend authentication with LDAP and discovered that a small percentage of their users have usernames with fewer than four characters.

WordPress MU currently has a minimum limit of four characters set in its core. Unfortunately, this limit is still imposed in WordPress MS 3.0. The limit is probably there because usernames were used for the domain too and WP-Devs didn’t want to conflict with country codes. But that is not an issue for my client, so I wanted to kill the limit (without touching core).

Basically, I wrote a quick mu-plugin that unset the error message when someone tries to add a user with fewer than four characters. Doing this removes any halts that would stop processing the new user. Here is my code:

function remove_username_char_limit($result) {	
  if ( is_wp_error( $result[ 'errors' ] ) && !empty( $result[ 'errors' ]->errors ) ) {

    // Get all the error messages from $result
    $messages = $result['errors']->get_error_messages();
    $i = 0;
    foreach ( $messages as $message ) {

      // Check if any message is the char limit message
      if ( 0 == strcasecmp("Username must be at least 4 characters", $message)) {
        // Unset whole 'user_name' error array if only 1 message exists
        // and that message is the char limit error
        if ( 1 == count($messages) ) {
          unset( $result['errors']->errors['user_name'] );
        } else {
          // Otherwise just unset the char limit message
          unset( $result['errors']->errors['user_name'][$i] );
        }
      }	

      $i++;
    }
  }

  return $result;	
}
add_action('wpmu_validate_user_signup', 'remove_username_char_limit');

Embed an RSS/ATOM Feed into your WordPress Website

By michael  |  April 26th, 2010  |  Published in Development, WordPress  |  Comments Off

One of our clients needs to pull an RSS feed from a real estate virtual tour provider and display it on one of their pages. I looked into a few plugins and could not find one that was easily customizable. After a quick google search I discovered that WordPress has some built-in functions based off of SimplePie‘s easy to use RSS API.

We also needed to customize the output a little bit, which required me to rely on PHP’s preg_match and preg_replace functions. Here is some simple example for embedding a feed into your WordPess website:

<?php
include_once(ABSPATH.WPINC.'/rss.php'); // path to include script
$feed = fetch_feed('http://url.to.feed/'); // specify feed url
?>

<?php
if (!is_wp_error($feed)) : 
	$rss_items = $feed->get_items(); 
?>

    // Loop through each feed item and display each item as a hyperlink. <?php foreach ( $rss_items as $item ) : ?>
  • <?php echo $item->get_title(); ?>
  • <?php endforeach; ?>

Check out the codex for more information about WordPress’ function feed_fetch()… and with a little extra coding you can format the feed any way you like, see our example at NC Capital Homes.

Easily Extended Contact Info in WordPress

By michael  |  April 22nd, 2010  |  Published in Development, WordPress, WordPress Plugins  |  Comments Off

I’m working on a project where I need the ability to add “Phone”, “Building”, and “Room” as information a user could add in their profile. I also wanted to remove “AIM”, “Yahoo”, and “Jabber” — none of the users are going to need to fill in that info.

You can easily add this code into your functions.php. I was writing it for a WordPress MU site with multiple themes and needed to make sure it was enforced, so I stuck it in the mu-plugins directory, in a file named “extended-contact-info.php”.

This is the simple code block you need:

function extended_contact_info($user_contactmethods) {
	//Use this if you want to append to the default 
	//contact methods (AIM, Yahoo, Jabber)
	//$user_contactmethods += array(
	//	'building' => __('Building'),
	//	'room' => __('Room'),
	//	'phone' => __('Phone')
	//);

	//Use this if you want to ignore the default 
	//contact methods (AIM, Yahoo, Jabber)
	$user_contactmethods = array(
		'building' => __('Building'),
		'room' => __('Room'),
		'phone' => __('Phone')
	);
	
	return $user_contactmethods;
}

add_filter('user_contactmethods', 'extended_contact_info');

WordPress Ultimate CMS Plugin

By michael  |  March 8th, 2010  |  Published in News, WordPress, WordPress Plugins  |  Comments Off

Description

FullThrottle Development is thrilled to announce our latest and greatest WordPress plugin! This ground breaking piece of craftsmanship will instantly turn your WordPress blogging software into a full fledged CMS. Just install, activate, and partake. Sreenshots below.

Download:

Features include but are not limited to the following:

  • Full standards compliance — We have gone to great lengths to make sure every bit of WordPress generated code is in full compliance with the standards of the W3C. This is important not only for interoperability with today’s browser but also for forward compatibility with the tools of the next generation. Your web site is a beautiful thing, and you should demand nothing less.
  • No rebuilding — Changes you make to your templates or entries are reflected immediately on your site, with no need for regenerating static pages.
  • WordPress Pages — Pages allow you to manage non-blog content easily, so for example you could have a static “About” page that you manage through WordPress. For an idea of how powerful this is, the entire WordPress.org site could be run off WordPress alone. (We don’t for technical mirroring reasons.)
  • WordPress Links — Links allows you to create, maintain, and update any number of blogrolls through your administration interface. This is much faster than calling an external blogroll manager.
  • WordPress Themes — WordPress comes with a full theme system which makes designing everything from the simplest blog to the most complicated webzine a piece of cake, and you can even have multiple themes with totally different looks that you switch with a single click. Have a new design every day.
  • Cross-blog communication tools— WordPress fully supports both the Trackback and Pingback standards, and we are committed to supporting future standards as they develop.
  • Comments — Visitors to your site can leave comments on individual entries, and through Trackback or Pingback can comment on their own site. You can enable or disable comments on a per-post basis.
  • Spam protection — Out of the box WordPress comes with very robust tools such as an integrated blacklist and open proxy checker to manage and eliminate comment spam on your blog, and there is also a rich array of plugins that can take this functionality a step further.
  • Full user registration — WordPress has a built-in user registration system that (if you choose) can allow people to register and maintain profiles and leave authenticated comments on your blog. You can optionally close comments for non-registered users. There are also plugins that hide posts from lower level users.

Screenshot

Screen shot 2010-03-08 at 11.25.19 AM

Colophon

Saving ‘meta data’ for WordPress categories

By michael  |  February 7th, 2010  |  Published in Development, WordPress  |  15 Comments

[updated 2010-06-08]

WordPress has some great hooks for adding extra fields to the Add Category page (as well as the edit category and the table listing the categories). Where / how do you save that data though. I ran accross a couple other devs on Twitter this evening that were asking this question. This post is primarily for them and it doesn’t provide all the code you need to get finish, but it should get most dev on their way. For instance, you will need another action for adding to the edit page, another action for adding to the table, and another action for editing the data. You will need to replace the type of fields. The below code assumes a custom taxonomy called ‘manufacturers’.

Additionally, the code below saves every field for every category or taxonomy in a different line in the options table. If I were going to put this into production I’d serialize the data so that all fields for a single category were stored in a single row of the options table.

Finally, as this is not in production yet (though it has been tested) there may be some errors or bugs. Please let me know if you find any and I will update (code would be nice too).

This following code, placed in your theme’s functions.php file:

<?php
### CUSTOM FIELDS FOR MANUFACTURERS

	// Manufacturer fields
	function ft_add_manufacturer_fields(){
		?>
		<!-- Web Site -->
		<div class="form-field">
			<label for="man_web_site"><?php _e('Manufacturer Web Site') ?></label>
			<input type='text' name="man_web_site" id="man_web_site" />
			<p><?php _e('The manufacturer\'s web site.'); ?></p>
		</div>

		<!-- Logo -->
		<div class="form-field">
			<label for="man_logo_url"><?php _e('Manufacturer Logo URL') ?></label>
			<input type='text' name="man_logo_url" id="man_logo_url" />
			<p><?php _e('The web address of the manufacturer\'s logo.'); ?></p>
		</div>

		<!-- Status -->
		<div class="form-field">
			<label for="man_status"><?php _e('Manufacturer Status') ?></label>
			<select name="man_status" id="man_status"><option value='standard' selected="selected">Standard</option><option value='premium'>Premium</option></select>
			<p><?php _e('Only manufacturer\'s with a premium status will have their logos linked to their web site.'); ?></p>
		</div>

		<?php
	}
	add_action('manufacturers_add_form_fields','ft_add_manufacturer_fields');

	// Add field to edit category screen
	function ft_edit_manufacturers_form(){	

		// clear values.
		$man_web_site = $man_logo_url = $man_status = '';

		// Clean tag id
		$id = sanitize_text_field($_GET['tag_ID']);

		if ( $opt_array = get_option('man_'.$id.'_meta') ){
			$man_web_site 	= sanitize_text_field($opt_array['man_web_site']);
			$man_logo_url 	= sanitize_text_field($opt_array['man_logo_url']);
			$man_status 	= sanitize_text_field($opt_array['man_status']);
		}
		?>
		<!-- Web Site -->
		<tr class="form-field">
			<th scope="row" valign="top"><label for="man_web_site"><?php _e('Manufacturer Web Site') ?></label></th>
			<td><input type='text' name="man_web_site" id="man_web_site" value="<?php echo $man_web_site; ?>" /><br />
			<span class="man_web_site"><?php _e('The manufacturer\'s web site.'); ?></span></td>
		</tr>

		<!-- Logo -->
		<tr class="form-field">
			<th scope="row" valign="top"><label for="man_logo_url"><?php _e('Manufacturer Logo URL') ?></label></th>
			<td><input type='text' name="man_logo_url" id="man_logo_url" value="<?php echo $man_logo_url; ?>" /><br />
			<span class="man_logo_url"><?php _e('The URL for the manufacturer\'s logo.'); ?></span></td>
		</tr>

		<!-- Status -->
		<tr class="form-field">
			<th scope="row" valign="top"><label for="man_status"><?php _e('Manufacturer Status') ?></label></th>
			<td><select name="man_status" id="man_status"><option value='standard' selected="selected">Standard</option><option value='premium' <?php if ( $man_status == 'premium' ){ echo 'selected="selected" '; } ?>>Premium</option></select>
			<br /><span class="man_status"><?php _e('Only manufacturer\'s with a premium status will have their logos linked to their web site.'); ?></span></td>
		</tr>

		<?php
	}
	add_action('manufacturers_edit_form_fields','ft_edit_manufacturers_form');

	// Add Manufacturer fields to table head
	function ft_manage_manufacturers_columns($columns){
		if ( !isset($_GET['taxonomy']) || $_GET['taxonomy'] != 'manufacturers' )
			return $columns;

		if ( $posts = $columns['posts'] ){ unset($columns['posts']); }
		$columns['man_status'] = 'Status';
		if ( isset($posts) ){ $columns['posts'] = 'Machines'; }
		return $columns;
	}
	add_filter('manage_edit-tags_columns','ft_manage_manufacturers_columns');

	// Add fields to table for each manufacturer
	function ft_manage_manufacturers_custom_fields($deprecated,$column_name,$term_id){
		if ( $opt_array = get_option('man_'.$term_id.'_meta') ){
			return esc_html($opt_array[$column_name]);
		}
	}
	add_filter('manage_manufacturers_custom_column','ft_manage_manufacturers_custom_fields',10,3);

	// Insert or Update the Manufacturer
	function ft_create_update_manufacturer($term_id,$tt_id){
		// Grab your field names in $_POST, sanatize and put wherever you want
		if ( isset($_POST['man_web_site']) )
			$update['man_web_site'] = sanitize_text_field($_POST['man_web_site']);
		if ( isset($_POST['man_logo_url']) )
			$update['man_logo_url'] = sanitize_text_field($_POST['man_logo_url']);
		if ( isset($_POST['man_status']) )
			$update['man_status'] = sanitize_text_field($_POST['man_status']);

		if ( isset($update) )
			update_option( 'man_'.$term_id.'_meta' , $update );

	}
	add_action('created_manufacturers','ft_create_update_manufacturer',10,2);
	add_action('edit_manufacturers','ft_create_update_manufacturer',10,2);

	// On Delete Manufacturer
	function ft_delete_manufacturer($term_id,$tt_id){
		delete_option('man_'.$term_id.'_meta');
	}
	add_action('delete_manufacturers','ft_delete_manufacturer',10,2);
>

Download a text file with the above code: here