This website uses cookies to allow us to see how the site is used. If you continue to use this site, we assume that you are okay with this. If you want to use the sites without cookies, please see our privacy policy.

Create multiple WordPress roles and limited capabilities for Schools

Personally I have set up many school websites and out of the box WordPress has a pretty sophisticated user roles and capabilities authoring engine. This can pretty much apply to any multiple user website but by just considering schools we can break it down in to user chunks.

So, schools have; Students, Staff, Teachers, Deputy Heads and probably a Head who will have more capabilities than others. Using the following code in your functions.php file you can firstly add multiple generic roles then at a later stage give them more capabilities like so:


// add multiple roles with basic capabilities for later use
function add_multiple_roles() {
	$roles = array('head' => 'Head','dep_head' => 'Deputy Head','teacher' => 'Teacher','staff' => 'Staff','student'=>'Student');

	$capabilities = array(
	    'read' => true,  // true allows this capability
	);

	foreach ($roles as $k => $v) {
		add_role( $k, __( $v ),  $capabilities );
	}
}
add_action( 'admin_init', 'add_multiple_roles');

function add_staff_caps() {
    // only relates to staff
    $role = get_role( 'staff' );
	// edit their own posts
    $role->add_cap( 'edit_posts' );
}
add_action( 'admin_init', 'add_staff_caps');

function add_teacher_caps() {
    // only relates to teacher
    $role = get_role( 'teacher' );
	// delete their own posts
    $role->add_cap( 'delete_posts' );
	// edit their own posts
    $role->add_cap( 'edit_posts' );
}
add_action( 'admin_init', 'add_teacher_caps');

function add_dep_head_caps() {
    // only relates to dep_head
    $role = get_role( 'dep_head' );
 	// publish their own posts
    $role->add_cap( 'publish_posts' );
 	// delete their own posts
    $role->add_cap( 'delete_published_posts' );
 	// edit their own published posts
    $role->add_cap( 'edit_published_posts' );
	// edit their own posts
    $role->add_cap( 'edit_posts' );
}
add_action( 'admin_init', 'add_dep_head_caps');

function add_head_caps() {
   $role = get_role( 'head' );
   // do whatever you see fit for the Head to do.....
}
add_action( 'admin_init', 'add_head_caps');

At some point you’ll probably want to change these capabilities but without getting yourself lost down a rabbit hole it’s probably worth mentioning that these capabilities are added to the database and if you think by removing them from your functions.php it is going to work as you would expect – think again!

This is not the case so, to chop and change between capabilities and user roles you’ll have to unregister them or remove them per role it they have been added previously. To show this as an example I’ve commented out the line that previously switch the capability on, if it wasn’t removed from the role it would still retain the capability eg:

function add_head_caps() {
   $role = get_role( 'head' );
   // do whatever you see fit for the Head to do...
   // it was switched on previously and commenting it out will not switch it off...
   // $role->add_cap( 'publish_posts' );
   // if it was previously added then you need to remove it....
   $role->remove_cap( 'publish_posts' );
}
add_action( 'admin_init', 'add_head_caps');

if you get in to a quagmire of not knowing where you are with capabilities you can always debug with the following to see what is going on:

print_r($role = get_role( 'head' ));

Integrating responsive-nav.js into WordPress Navigation

Responsive Web Design is all the rage these days. It’s been around since 2009 but it’s really made it way into the main stream this past year. Clients are asking for it, web developers are expected to know it, and most importantly, mobile devices are more popular than ever. One big area of a website were we must be particularly attentive to is website navigation. In my book, Responsive Design with WordPress, I talk all about responsive navigation and how to make it work nicely in WordPress. In this snippet, I’m going to show you my favorite method: responsive-nav.js.

Continue reading “Integrating responsive-nav.js into WordPress Navigation”

Find Pages using given WordPress shortcode

In WordPress it is quite easy to find all Pages or Post using given shortcode, below is a function that will do this, one important thing to keep in mind is that the shortcode you will be looking for needs to be registered (using add_shortcode) before using this function, otherwise the function will return NULL.

What i find cool about the has_shortcode() function is that it will find shortcodes regardless of how they are being used, with or without attributes.


function pages_with_shortcode($shortcode, $args = array()) {
    if(!shortcode_exists($shortcode)) {
        // shortcode was not registered (yet?)
        return null;
    }

    // replace get_pages with get_posts
    // if you want to search in posts
    $pages = get_pages($args);
    $list = array();

    foreach($pages as $page) {
        if(has_shortcode($page->post_content, $shortcode)) {
            $list[] = $page;
        }
    }

    return $list;
}

// quick usage guide
// adding filter with low priority
add_filter("init", "_my_init_test", 0, 1000);
function _my_init_test() {
    foreach(pages_with_shortcode("my_super_shortcode") as $p) {
        echo $p->post_title." <br/>";
    }
}

Playing Nice With WordPress paginate_links function

Let’s say you want to add pagination to your theme but instead of just displaying “next” and “previous” links you’d rather show a list of pages to your users. The paginate_links() function will take care of that for you. However, out of the box it can be a bit tricky to figure out and the examples on the Codex page are not that great in my opinion. Here’s a snippet that we use in all of our themes to display a pagination list on the blog page template.

/*
 * This function displays pagination links based on arguments.
 * @uses paginate_links for output
 */
function my_blog_paginate_links( $return = false ) {
	global $wp_query;

	$pagination_links = paginate_links( array(
		'base' => esc_url( get_pagenum_link() ) . '%_%', // %_% will be replaced with format below
		'format' => ( ( get_option( 'permalink_structure' ) && ! $wp_query->is_search ) || ( is_home() && get_option( 'show_on_front' ) !== 'page' && ! get_option( 'page_on_front' ) ) ) ? '?paged=%#%' : '&paged=%#%', // %#% will be replaced with page number
		'current' => max( 1, get_query_var( 'paged' ) ), // Get whichever is the max out of 1 and the current page count
		'total' => $wp_query->max_num_pages, // Get total number of pages in current query
		'next_text' => 'Next →',
		'prev_text' => '← Previous',
		'type' => ( $return ) ? 'array' : 'list'  // Output this as an array or unordered list
	) );

	if( $return )
		return $pagination_links;
	else
		echo $pagination_links;
}

The above function will output a list of paginated links and works will no permalinks as well as pretty permalinks. We use a few conditional statements in the form of a ternary operator on the ‘format’ argument to determine if permalinks are enabled, we’re on a search page, or if the blog page is the front page. If you pass true as a parameter, an array of values will be returned instead of a list of paginated links. See the comments in the snippet for more information. You can use the function in one of your templates as seen here:

<?php my_blog_paginate_links(); ?>

Prevent loading unnecessary scripts and styles in WordPress

Some plugins, when installed, add about 2 or 3 scripts and stylesheets to every page on your website. This isn’t necessarily a problem but it would be nice to have scripts loaded only on pages that actually need them.

Let’s take the popular Contact Form 7 plugin as an example. Most likely, only pages that contain the [contact-form-7] shortcode will need the extra scripts and styles.

The following snippet will check your post content to see if it contains the contact form 7 shortcode. If it doesn’t, it will dequeue the styles and scripts so they will not be loaded.

function dvk_dequeue_scripts() {
    
    $load_scripts = false;

    if( is_singular() ) {
    	$post = get_post();

    	if( has_shortcode($post->post_content, 'contact-form-7') ) {
        	$load_scripts = true;
    	}

    }

    if( ! $load_scripts ) {
        wp_dequeue_script( 'contact-form-7' );
        wp_dequeue_style( 'contact-form-7' );
    }

}

add_action( 'wp_enqueue_scripts', 'dvk_dequeue_scripts', 99 );

You can, of course, add more logic to the function to detect the necessity of scripts for other plugins as well. You will need to know the handles used to identify the scripts and styles of the plugin and the shortcode.

Be careful when implementing this though. If you’re rendering a contact form using a widget or template function (for example), the snippet above won’t detect it and will still dequeue the scripts and styles.

Extra
If you’re a plugin author, register your scripts as soon as possible but only enqueue them from your main display function (the shortcode callback, rendering function, etc..) with the parameter $in_footer set to true. This way, your scripts will only be loaded when they are actually needed. By registering the script early, users still get a chance to register their own version of it, should they want to.

Make menu highlights work for custom post types

I’ve written on my own blog about how WordPress’s navigation menus are great, but sometimes need some enhancement. One area they fall down in is how they work with custom post types.

Lets say you create a custom post type called ‘resources’ (I’ve done this on a couple of sites recently – see Send My Friend to School and Flesh and Blood). You are going to make use of the built in archive that gets generated at /resources, and you’re going to put this in your menu.

There are two issues in this scenario:

  1. A page displaying an item(s) from a post type seems to highlight any menu item linked to the blog archive page – perhaps your “Home” link, or your “Blog” link. It does this by setting the “current_page_parent” class on that menu item to highlight it. We need to prevent this happening for the post type.
  2. WordPress doesn’t appropriately highlight the menu item you create that links to your post type’s archive. We need to highlight this menu item if viewing post(s) from that post type. We can do this by adding a class like “current_page_parent” to that menu item at the appropriate times.

Before we get the code, we’ll need a way to specify that a certain menu item is to be used for this purpose. To do this you need to know another little trick that you may (or may not) know about.

When editing menus, you can use the “Screen Options” menu in the top right of the edit screen to show some extra fields for each menu item. Importantly here, you can turn on “CSS Classes” from the “Advanced menu properties” section of the Screen Options menu. Once this is enabled you can add a CSS class to your menu item. The code below uses the class “post-type-xxx” where xxx is your post type’s name.

So, in summary, to use the code below you’ll need to:

  • Add a menu item to your menu that links to the index of your post type
  • Add the “post-type-xxx” class to the menu item as described above
  • Add the code below to your functions.php, or other suitable file
  • Sit back and watch the magic!

Here’s the code for the filter:

/*
 * This filter fixes an issue where the blog page is highlighted as a menu item
 * for archives/singles of other post types.
 */
add_filter('nav_menu_css_class', 'mytheme_custom_type_nav_class', 10, 2);

function mytheme_custom_type_nav_class($classes, $item) {
	$post_type = get_post_type();

	// Remove current_page_parent from classes if the current item is the blog page
	// Note: The object_id property seems to be the ID of the menu item's target.
	if ($post_type != 'post' && $item->object_id == get_option('page_for_posts')) {
    	$current_value = "current_page_parent"; 
    	$classes = array_filter($classes, function ($element) use ($current_value) { return ($element != $current_value); } );
	}

	// Now look for post-type-<name> in the classes. A menu item with this class
	// should be given a class that will highlight it.
	$this_type_class = 'post-type-' . $post_type;
	if (in_array( $this_type_class, $classes )) {       
    	array_push($classes, 'current_page_parent');
	};

	return $classes;
}

Add a Custom Post Type Submenu To An Existing Custom Post Type Menu

Custom Post Types are on of the most powerful features of WordPress, especially if you’re in the business of creating custom solutions for clients beyond normal blogging functionality.

Introducing a new menu in the WordPress dashboard is really easy when using the custom post type API; however, what about the case when you have a custom post type and is a child of another custom post type?

Specifically, what about the case when you want to add a custom post type submenu to an existing custom post type menu?

Continue reading “Add a Custom Post Type Submenu To An Existing Custom Post Type Menu”

Get #WordPress page view count from Jetpack

The below code snippet will return the page view count by $post_id if you are running the Jetpack WordPress plugin. The count is also stored in a transient that expires every 30 minutes for performance optimization.

/**
 * Get post pageview count
 */
function wds_post_pageview_count( $post_id ) {
 
  // Check for transient
  if ( ! ( $count = get_transient( 'wds_post_pageview_count' . $post_id ) ) ) {
 
    // Verify we're running Jetpack
    if ( function_exists( 'stats_get_csv' ) ) {
 
      // Do API call
      $response = stats_get_csv( 'postviews', 'post_id='. absint( $post_id ) .'&period=month&limit=1' );
 
      // Set total count
      $count = absint( $response[0]['views'] );
 
    // If not, stop and don't set transient
    } else {
      return 'Jetpack stats not active';
    }
 
      // Set transient to expire every 30 minutes
      set_transient( 'wds_post_pageview_count' . absint( $post_id ), absint( $count ), 30 * MINUTE_IN_SECONDS );
 
  }
 
 return absint( $count );
 
}

Full code gist: https://gist.github.com/williamsba/7824876

Props to Greg Rickaby.

Display OptionTree created Slider using the Flexslider image slider from WooThemes

I was looking for an easy way to integrate the OptionTree plugin’s slider with FlexSlider by WooThemes and I couldn’t find any. So I thought this would be useful to others as well.

Full Code:

<?php
$slides = get_option_tree( 'SLIDE_ID_HERE', $option_tree, false, true, -1 );
if ( ! empty( $slides ) ) { ?>
<div class="flexslider slider" id="slider">
	<ul class="slides">
	<?php
	foreach( $slides as $slide ) { 
		$id = custom_get_attachment_id( $slide['image'] );
		$custom = wp_get_attachment_image_src( $id, 'slider' );
		echo '<li><a href="'.$slide['link'].'"><img src="'.$custom[0].'" alt="'.$slide['title'].'" /></a><p class="flex-caption">'.$slide['title'].'</p></li>';
	}
	?>
	</ul>
</div><!-- END .flexslider.slider #slider -->
<?php } ?>

The above code will take each of the slides you’ve added into the OptionTree plugin and spit them out in the code used by Flexslider to display your slider.

Looking at the code, in the line of php code below, you’ll be changing the “SLIDE_ID_HERE” text to the id you gave your slider in the OptionTree plugin setup.

$slides = get_option_tree( 'SLIDE_ID_HERE', $option_tree, false, true, -1 );

And then a bit further down the code you will see this line of code which is where you’ll call your uploaded image for each slide – I like to create a new image size in the functions.php file so when I upload the photos into the slider, they’re cropped to the “slider” size.

You can change the ‘slider’ id to whatever image size you’d like (ie: thumbnail, medium, large, full).

$custom = wp_get_attachment_image_src( $id, 'slider' );

If you want to create your own slider image size to be cropped in the WordPress admin, you can do so by adding the following code to your functions.php file.

// This theme uses post thumbnails
if ( function_exists( 'add_image_size' ) )
	add_theme_support( 'post-thumbnails' );
	add_image_size( 'slider', 1240, 420, true ); // $id, width, height, crop

Once that’s done, you’re all set and your FlexSlider powered slider will now show the slides you added in the OptionTree plugin.

Enjoy!

Append Items to a Nav Menu

One of the things that is common when working with WordPress clients is they have a tendency to forget their login URL.  Appending an ‘Admin’ link to the end of the footer that the user can’t remove is one way to ensure your client can always find the admin without having to give you a call.

/**
* Add a custom link to the end of a specific menu that uses the wp_nav_menu() function
*/
add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);
function add_admin_link($items, $args){
    if( $args->theme_location == 'footer_menu' ){
        $items = $items . '<li><a title="Admin" href="'. admin_url() .'">' . __( 'Admin' ) . '</a></li>';
    }
    return $items;
}

https://gist.github.com/woodent/1249995

With a few alterations, you can append ( or prepend ) anything to a nav menu.  A few examples would be search fields, dynamically generated ‘Log In’ and ‘Log Out’ links, ‘User Profile’ or ‘User Account’ links, fancy images or icon fonts, and the list goes on…

Properly enqueuing script and styles in WordPress

Often when developing a site, plugin or theme you will want to enqueue your custom script or style, it is worth to learn how to do this right in order to avoid conflicts with third party plugins and decrease number of HTTP requests (for example avoid loading jQuery twice).

Without any further additions below is code that will load custom script and style in the frontend

add_filter("init", "stc_init");
function stc_init() {
    // first step is to register your custom scripts and styles, the scripts will be loaded
    // plugins_url() as used as below will work only when scripts are in the same directory
    // as *this* php file
    wp_register_script("stc-frontend-js", plugins_url("stc-frontend.js", __FILE__), array("jquery"));
    wp_register_style("stc-frontend-css", plugins_url("stc-frontend.css", __FILE__));

    // now we can localize the script (if needed)
    wp_localize_script("stc-frontend-js", "stc_frontend_js_lang", array(
        "hello_world" => __("Hello World!", "my-locale")
    ));
}

add_action("wp_enqueue_scripts", "stc_enqueue_scripts");
function stc_enqueue_scripts() {
    // the two lines below will load in &lt;head&gt; stc-frontend-js, stc-frontend-css
    // and jquery (since stc-frontend-js has dependency on jquery,
    // additionally stc_frontend_js_lang variable will be printend in page
    // html code ... so we are all set to use the scripts
    wp_enqueue_script("stc-frontend-js");
    wp_enqueue_style("stc-frontend-css");
}

Couple of things to consider

  • In order to get this to work you will need two files stc-frontend.js and stc-frontend.css in the same directory as the PHP code will be.
  • The scripts and styles will be loaded in <head> section, so in order to load them wp_enqueue_script and wp_enqueue_style functions have to be executed before head section is printend. Second possibility is to pass fourth (file version) and fifth arguments to wp_register_script, if you set the fifth argument to true then scripts will be loaded in footer instead.
  • This code is for loading resources in the frontend only if you want to do the same in wp-admin, then add following line at the end
    add_action("admin_enqueue_scripts", "stc_enqueue_scripts");
    

The complete source code for this snippet you can get from here.

Show Custom Post Types on the Homepage

Custom post types are commonly used on WordPress sites, but they don’t show on the homepage or in the archive pages unless you write code to do that.  I’ve put together some code that is smart about detecting your public custom post types and automatically adding them to your homepage and archive pages:

/**
 * Show WordPress custom post types on the main blog and archive pages
 *
 * @param WP_Query $query
 **/
function show_custom_post_types( $query ) {

  // Show all custom post types on main blog and archive pages
  if ( $query->is_main_query() && ( is_home() || ( is_archive() && !is_post_type_archive() ) ) ) {

    $custom_post_types = get_post_types( array(
       'public' => true,
       '_builtin' => false,
    ) );
    $post_types = array_merge( array('post'), $custom_post_types );
    $query->set( 'post_type', $post_types );
   }

   return $query;
}

add_filter( 'pre_get_posts', 'show_custom_post_types' );

https://gist.github.com/woodent/2068729

Automatically deactivate plugin when parent plugin is deactivated

There’s a plugin I maintain called Amazon S3 and CloudFront. It checks if the Amazon Web Services plugin is activated and if not, deactivates itself. Here’s the code:

function as3cf_check_required_plugin() {
    if ( class_exists( 'Amazon_Web_Services' ) || !is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
        return;
    }

    require_once ABSPATH . '/wp-admin/includes/plugin.php';
    deactivate_plugins( __FILE__ );

    $msg = sprintf( __( 'Amazon S3 and CloudFront has been deactivated as it requires the <a href="%s">Amazon&nbsp;Web&nbsp;Services</a> plugin.', 'as3cf' ), 'http://wordpress.org/extend/plugins/amazon-web-services/' ) . '<br /><br />';

    if ( file_exists( WP_PLUGIN_DIR . '/amazon-web-services/amazon-web-services.php' ) ) {
        $activate_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=amazon-web-services/amazon-web-services.php', 'activate-plugin_amazon-web-services/amazon-web-services.php' );
        $msg .= sprintf( __( 'It appears to already be installed. <a href="%s">Click here to activate it.</a>', 'as3cf' ), $activate_url );
    }
    else {
        $install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=amazon-web-services' ), 'install-plugin_amazon-web-services' );
        $msg .= sprintf( __( '<a href="%s">Click here to install it automatically.</a> Then activate it. ', 'as3cf' ), $install_url );
    }

    $msg .= '<br /><br />' . __( 'Once it has been activated, you can activate Amazon&nbsp;S3&nbsp;and&nbsp;CloudFront.', 'as3cf' );

    wp_die( $msg );
}

add_action( 'plugins_loaded', 'as3cf_check_required_plugin' );

Get a list of WordPress post types that support a feature

Need to be able to fetch a list of post types that support a specific feature, like thumbnails, excerpts, etc?  This nifty little function will let you do just that:

/**
 * Get a list of post types that support a specific feature.
 * 
 * @param $feature
 * @return array
 */
function get_post_types_that_support( $feature ) {
	global $_wp_post_type_features;
	$post_types = array_keys(
		wp_filter_object_list( $_wp_post_type_features, array( $feature => true ) )
	);
	return $post_types;
}

https://gist.github.com/woodent/6273186

Paginate WordPress posts with a thumbnail image

Its always nice to give your users the ability to paginate through your posts, and there are a couple of simple functions that will allow you to do so from with in the individual posts, by that I mean these functions should be used on the single.php template.

By using get_previous_post() and get_next_post() you can retrieve all the information you need from the previous or the next post adjacent to the currently viewed post. If you want to find out more go checkout the codex in the links provided for both functions.

Using the following you can output the link to the previous post of the currently viewed post:

<?php
   $previous = get_previous_post();
   echo get_permalink($previous->ID);
?>

using the get_next_post() you can do the same to get the opposite or get the adjacent post of the currently viewed post like so:

<?php
   $next = get_next_post();
   echo get_permalink($next->ID);
?>

Now that you can access the ID of the previous and next post we can use another function to get the thumbnail of those posts using the get_the_post_thumbnail() function like this:

<?php
    echo get_the_post_thumbnail($previous->ID, 'thumbnail');
?>
<!-- or -->
<?php
    echo get_the_post_thumbnail($next->ID, 'thumbnail');
?>

All you need to do now is to wrap the code up in your mark up to make it your own, putting it all together it might look something like this:

<?php $previous = get_previous_post(); $next = get_next_post(); ?>
<div class="wrapperdiv">
    <div class="float--left">
        <a title="<?php echo esc_attr($previous->post_title); ?>" href="<?php echo get_permalink($previous->ID); ?>">
            <?php echo get_the_post_thumbnail($previous->ID, 'thumbnail'); ?>
        </a>
    </div>
    <div class="float--right">
        <a title="<?php echo esc_attr($next->post_title); ?>" href="<?php echo get_permalink($next->ID); ?>">
            <?php echo get_the_post_thumbnail($next->ID, 'thumbnail'); ?>
        </a>
    </div>
</div>

Your html markup and css should be adapted for your own designs but as long as you are on the single.php template then your users will now be able to paginate WordPress posts with a thumbnail image of the previous and next posts.

A WordPress function to stop non logged in users accessing a page or pages

If you’ve ever tried to build a mini application with WordPress you’ll probably know that you need to use multiple page templates that only registered users can access, so the easiest thing to do is create a WordPress function to stop non logged in users accessing a page or pages, if they can’t then they should get kicked away, gently of course!

Here is one really simple way I’ve used many times to do this.

First of all create this function in your functions.php file

// check users or die
function check_logged_in_users() {
	global $current_user;
	if ( !is_user_logged_in()) {
		wp_die("<p>To access this page you need to login first! Why don't you go back and try again.</p>", "Oh dear, something went wrong!", array( 'response' => 500, 'back_link' => true ));
	} 
}

So next you need to add the function at the top of each page you’d like to hide from non logged in users, somewhere before the get_header() function should do it, looks something like this:

<?php 
/*
	Template Name: This page is for logged in users only
*/
check_logged_in_users();
get_header(); 
?>

Now all page templates with this function will only allow logged in users to access the page.

Enable Automatic Updates for WordPress Plugins and Themes

With version 3.7 WordPress introduced automatic updates. By default, these are on for maintenance and security releases only, but the underlying code is smart enough to support updates for plugins and themes. Here’s a simple plugin that will enable automatic updates for themes:

/**
 * Plugin Name: Enable Automatic Updates for Themes
 */
add_filter( 'auto_update_theme', '__return_true' );

And here’s one for plugins:

/**
 * Plugin Name: Enable Automatic Updates for Plugins
 */
add_filter( 'auto_update_plugin', '__return_true' );

Please note that these will work only if your host is configured to support automatic WordPress updates. You can learn more about configuring and debugging automatic background updates in the codex.

Create your own registration form in WordPress

From time to time you might need to create your own registration form in WordPress to maintain a brand identity for your client. Although personally I’d be proud to show off the fact that I’m using WordPress, some clients just don’t and they would like their website to reflect their own branding so here’s how we do it.

You can start by putting this form anywhere in one of your theme files but, just to keep things clean I’m going to put this in a new template based on the page.php file so, first of all lets create a new template by duplicating the page.php file and call it something obvious, I’m going to call mine customer-registration.php. Then at the top add the standard template naming comment so you can select the template in the backend of your WordPress installation.

The code at the top of my new page customer-registration.php should look like this:


<?php
/*
   Template Name: Registration Page
*/
get_header();
?>

Next we’ll create the form but, first we need to add an action to hook on too for processing the form as we will be posting it to itself for demonstration purposes, somewhere above the form should be fine.

Then create a simple form with a method of “POST”, an id “adduser”, an empty action so we can post the form to itself and finally some inputs for a Username and Email address. I’ve also included php $error variables for some error checking and you’ll also notice the wp_nonce_field() for extra security after the submit input.

The form code should look something like this:

<?php do_action ('process_customer_registration_form'); ?><!-- the hook to use to process the form -->

<form method="POST" id="adduser" class="user-forms" action="">
	<strong>Name</strong>
	<p class="form-username">
		<label for="user_name"><?php echo 'Username (required)'; ?></label>
		<input class="text-input" name="user_name" type="text" id="user_name" value="" />
	</p>
	
	<p class="form-email">
		<label for="email"><?php echo 'E-mail (required)'; ?></label>
		<input class="text-input" name="email" type="text" id="email" value="" />
	</p>
	
	<p class="form-submit">
		<input name="adduser" type="submit" id="addusersub" class="submit button" value="Register" />
		<?php wp_nonce_field( 'add-user', 'add-nonce' ) ?><!-- a little security to process on submission -->
		<input name="action" type="hidden" id="action" value="adduser" />
	</p>
</form>

Next we’ll need the action function to hook the do_action(‘process_customer_registration_form’) we created at the top of our registration form.

So in your functions.php file add the following code:


function registration_process_hook() {
	if (isset($_POST['adduser']) && isset($_POST['add-nonce']) && wp_verify_nonce($_POST['add-nonce'], 'add-user')) {
	
		// die if the nonce fails
		if ( !wp_verify_nonce($_POST['add-nonce'],'add-user') ) {
			wp_die('Sorry! That was secure, guess you\'re cheatin huh!');
		} else {
			// auto generate a password
			$user_pass = wp_generate_password();
			// setup new user
			$userdata = array(
				'user_pass' => $user_pass,
				'user_login' => esc_attr( $_POST['user_name'] ),
				'user_email' => esc_attr( $_POST['email'] ),
				'role' => get_option( 'default_role' ),
			);
			// setup some error checks
			if ( !$userdata['user_login'] )
				$error = 'A username is required for registration.';
			elseif ( username_exists($userdata['user_login']) )
				$error = 'Sorry, that username already exists!';
			elseif ( !is_email($userdata['user_email'], true) )
				$error = 'You must enter a valid email address.';
			elseif ( email_exists($userdata['user_email']) )
				$error = 'Sorry, that email address is already used!';
			// setup new users and send notification
			else{
				$new_user = wp_insert_user( $userdata );
				wp_new_user_notification($new_user, $user_pass);
			}
		}
	}
	if ( $new_user ) : ?>

	<p class="alert"><!-- create and alert message to show successful registration -->
	<?php
		$user = get_user_by('id',$new_user);
		echo 'Thank you for registering ' . $user->user_login;
		echo '<br/>Please check your email address. That\'s where you\'ll recieve your login password.<br/> (Be sure to check your spam folder)';
	?>
	</p>
	
	<?php else : ?>
	
		<?php if ( $error ) : ?>
			<p class="error"><!-- echo errors if users fails -->
				<?php echo $error; ?>
			</p>
		<?php endif; ?>
	
	<?php endif;

}
add_action('process_customer_registration_form', 'registration_process_hook');

In the function above all we are basically doing is taking the form information and creating a new user from the information given by the user with an auto generated password and sending an email to that user with their login details, we are also making some error checks to make sure the user is created correctly, if there are no errors the user is created with a message telling the new user what to do next, if there are errors we tell the user what has happened so they can try again.

Now you should have a viable registration form that can be placed anywhere on your WordPress installation.

Getting static images for YouTube videos ready for your WordPress posts

This one’s a little complicated, but it’s a neat trick to getting static images for YouTube videos ready for your WordPress posts.

Lets say you want a site that uses lots of embedded YouTube videos. You want to show an index of these videos on your front page, or as an archive, but you don’t want to fetch an embed from YouTube for every video – you’d rather use something like featured images, but without having to do a screen grab, crop it, resize it, and upload.

Well, here’s a snippet that creates an automatic thumbnail from a YouTube URL when you save a post. To make this work you will need a piece of meta-data (the snippet uses ’_mytheme_embed_url’). When a post with this meta data item is saved, the snippet creates a new meta-data item called ’_mytheme_video_img_url’ with the URL of the thumbnail in.

You can use the thumbnail in your theme by doing something like:

  $preview_img = get_post_meta( get_the_ID(), ’_mytheme_video_img_url', true );
  if ($preview_img) {
    printf( '&lt;img src=&quot;%s&quot; /&gt;', $preview_img );
  }

Here’s the snippet:

// This action attempts to generate a YouTube thumbnail URL from the provided YouTube URL.
add_action( 'updated_post_meta', 'mytheme_generate_youtube_url', 10, 4);
add_action( 'added_post_meta', 'mytheme_generate_youtube_url', 10, 4);
function mytheme_generate_youtube_url( $meta_id, $object_id, $meta_key, $meta_value ) {
    if ($meta_key == '_mytheme_embed_url') {
        if (strlen($meta_value) &gt; 7 ) { // Eliminates default 'http://'
            if (preg_match( '/youtube.com/', $meta_value )) {
                if (preg_match ('/\/embed\/(.*)/', $meta_value, $vid_matches )) {
                    $vid_tmp = $vid_matches[1];
                    $vid_tmp = explode('?', $vid_tmp);
                    $vid = $vid_tmp[0];
                } else {
                    $url_query = parse_url( $meta_value, PHP_URL_QUERY );
                    parse_str( $url_query, $params );
                    $vid = $params['v'];
                }
            } elseif (preg_match( '/youtu.be/', $meta_value )) {
                $vid = ltrim( parse_url( $meta_value, PHP_URL_PATH ), '/');
            }
            if ($vid) {
                $img_url = sprintf('http://i.ytimg.com/vi/%s/hqdefault.jpg', $vid);
                update_post_meta( $object_id, '_mytheme_video_img_url', $img_url );
            }
        }
    }
}

There’s a full write up of this on my own blog.

Credits:

This is mostly my own collation of things I found elsewhere so here are my sources – with thanks!

How to create your own custom WordPress login page

Some times you might like to roll your own login page just for that little added bespoke or custom website touch, this is probably easier than you realise! All you need to do is create a custom template and use one of the built in WordPress functions wp_login_form simples! Here’s how to create your own custom WordPress login page.

First of all you need to create a simple custom page template in your theme folder eg: custom-login.php with the following code at the top of your custom page template:

/*
Template Name: Custom Login
*/

Now when you create a new page in the backend you will get the option to use this template as the framework for the page you are creating. So, in this template you will also need the following snippet:


if ( ! is_user_logged_in() ) { // Display WordPress login form for non logged in users:
    $args = array(
        'redirect' =&gt; admin_url(),
        'form_id' =&gt; 'loginform-custom', // give the login form an id for styling the css
        'label_username' =&gt; __( 'Your Username' ),
        'label_password' =&gt; __( 'Your Password' ),
        'label_remember' =&gt; __( 'Remember me on this device' ),
        'label_log_in' =&gt; __( 'Log In' ),
        'remember' =&gt; true
    );
    wp_login_form( $args );
} else { // Otherwise if the users is logged in:
    wp_loginout( home_url() ); // Display &quot;Log Out&quot; link.
    echo &quot; | &quot;;
    wp_register('', ''); // Display &quot;Site Admin&quot; link.
}

Now all you need to do is login to the backend, create a page, select ‘Custom Login’ from the Template dialogue options, preview it and bingo! You’ve just created your own custom and bespoke WordPress login page. You might need to tweak the css styling a little but it will function just like the standard WordPress login page.

Resource: Codex

Track the number of times a WordPress post has been viewed

This is a neat little snippet to track the number of times a WordPress post has been viewed, used wisely it can be used to show a trending post or popular content. In the backend you’ll discover gold gems of content and it can be used to display trending content in the frontend, it could be a blog post, a product, a review or just a popular page that gets a lot of attention! Very useful for your visitors. So, there are a couple of elements to this snippet; a couple of functions and a means to register the data in a post, lets begin…

For the function:

//Track post views without a plugin using post meta
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 &quot;0 View&quot;;
    }
    return $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);
    }
}

The function above will create a custom field called ‘post_views_count’ attached to the ID of a post that will record the data but, if we have no data a little bit of organic funky creation will happen to create it as zero (0), if it does exist (even if it is 0) we add 1 more view to the data and save it and this is how we clock the views. Sweet eh!

To take advantage of the function we need to register the view in a template or custom post type, this is done by adding the function within the WordPress standard loop so the ID of the post is registered:

    setPostViews(get_the_ID());

To query the content based on views:

$get_trending = array(
    'meta_key' => 'post_views_count',
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'posts_per_page' => 5
);
$trendy = new WP_Query($get_trending);
while ($trendy->have_posts()) : $trendy->the_post();

echo '<ul><li><a href="';
echo the_permalink();
echo '">';
echo the_title();
echo '</a></li></ul>';

endwhile;
// Reset Post Data
wp_reset_postdata();

hopefully this gives you the gist of this awesome function resource

Get a twitter count of your shared WordPress content without a plugin

If you run a blog that has an audience who regularly share your pages, why not show them the count of how many times your pages have been shared. Here’s how to get a twitter count of your shared WordPress content without a plugin.

function getTweetCount($url)
{
    $url = urlencode($url);
    $twitterEndpoint = &quot;http://urls.api.twitter.com/1/urls/count.json?url=%s&quot;;
    $fileData = file_get_contents(sprintf($twitterEndpoint, $url));
    $json = json_decode($fileData, true);
    unset($fileData); // free memory
    //print_r($json);
    return $json['count'];
}

Add class to search terms for highlighting in WordPress search results

When a user searches your WordPress site it’s nice to give them some feedback on the term they’ve just search, this function will add a class to the search terms you can then use css to highlight the search results.

function wptx_highlight_results($text){
     if(is_search()){
     $sr = get_query_var('s');
     $keys = explode(&quot; &quot;,$sr);
     $text = preg_replace('/('.implode('|', $keys) .')/iu', '&lt;strong class=&quot;search-excerpt&quot;&gt;'.$sr.'&lt;/strong&gt;', $text);
     }
     return $text;
}
add_filter('the_excerpt', 'wptx_highlight_results');
add_filter('the_content', 'wptx_highlight_results');
add_filter('the_title', 'wptx_highlight_results');

Source: wpsnipp.com

Have all WordPress user data emailed to site owner on registration

Some sites will have additional user data in the registration form, when users register the site owner is notified by email. Now rather than just getting notified by WordPress that a new user has registered why not have all WordPress user data emailed to site owner on registration, here’s a function that does just that.

function new_user_registered($user_id) {
    global $wpdb;
    $admin_email = get_bloginfo('admin_email');

    if (!current_user_can( 'administrator' )){// avoid sending emails when admin is updating user profiles
        $to = $admin_email;
        $subject = 'Yay! You have a new registered user.';
        $message = &quot;The user has registered with the following user meta data:\n&quot;;
        foreach($_POST as $key => $value){
            $message .= $key . ': '. $value . '\n';
        }
        wp_mail( $to, $subject, $message);
    }
}
add_action( 'user_register', 'new_user_registered');

function yoursite_wp_mail_from($content_type) {
  return 'changethis@mydomain.com';
}
add_filter('wp_mail_from','yoursite_wp_mail_from');

function yoursite_wp_mail_from_name($name) {
  return 'From a Nice Name';
}
add_filter('wp_mail_from_name','yoursite_wp_mail_from_name');

Create a WordPress members role and redirect them to a members area

To create a WordPress members role and redirect them to a members area after login is a simple requirement for many client websites, here are two simple functions to create a new user role, give them some capabilities and redirect them to a members area after they login.

// create a users role with capabilities
$new_member_role = add_role('members', 'Member', array(
    'read' =&gt; true, // True allows that capability
    'edit_posts' =&gt; true,
    'delete_posts' =&gt; false, // Use false to explicitly deny
));

// redirect the users after they login, be sure to create a page with a slug of members-welcome
function wptx_login_redirect_contributors() {
  if ( current_user_can('members') ){
      return '/members-welcome/';
  }
}
add_filter('login_redirect', 'wptx_login_redirect_contributors');

if you need to protect this page from non-logged in users see how to hide a page if a user is not logged in

 

Remove or add additional information to WordPress user profiles

Sometimes the default WordPress user contact details on user profiles are not needed, this sweet little snippet will remove or add additional information to WordPress user profiles; ideal for memberships sites.

function my_user_contactmethods($user_contactmethods){
   // remove contact items
   unset($user_contactmethods['yim']);
   unset($user_contactmethods['aim']);
   unset($user_contactmethods['jabber']);
   // additional contact items
   $user_contactmethods['twitter'] = 'Twitter Username';
   $user_contactmethods['facebook'] = 'Facebook Username';
   return $user_contactmethods;
}

Once saved the user information can be output using the get_user_meta function, the example below is for logged in users…

if ( is_user_logged_in() ) {
// gets all user data
global $current_user;
// gets user meta by id
$user_info = get_user_meta($current_user->ID);
// outputs specific user meta
echo 'Twitter: ' . $user_info['twitter'][0];
echo 'Facebook: ' . $user_info['facebook'][0];
}

source: wp.tuts

Neatly Wrapping Custom Post Type Queries in a Custom Class that Extends WP_Query

Let’s say you have a custom post type book that you almost always want to order by title. In other words, when querying for books, the default should be to order them by title. Also, you would almost never use paging. Instead of repeating these query arguments over and over, you can wrap them in a class that extends WP_Query.

class My_Book_Query extends WP_Query {

	function __construct( $args = array() ) {

		$args = wp_parse_args( $args, array(
			'post_type' => 'book',
			'orderby' => 'title',
			'order' => 'ASC',
			// Turn off paging
			'posts_per_page' => -1,
			// Since, we won't be paging,
			// no need to count rows
			'no_found_rows' => true
		) );

		parent::__construct( $args );

	}
}

Then when querying for books, simply call this new class instead of WP_Query. And feel free to use any query arguments you normally would.

$r = new My_Book_Query( array(
	'order' => 'DESC'
) );

while ( $r->have_posts() ) {
	$r->the_post();
	the_title();
	echo '<br />';
}

wp_reset_postdata();

You could also add methods to the class and hook them up to WP_Query filters like posts_where, posts_join, etc. All nicely wrapped up in a class.

Update: I’ve expanded on this and posted a longer, more involved example on my blog. Check it out ».

Unified text size in the WordPress tag cloud

A simple function to unify the text size of the tag cloud, simply because a non client was getting frustrated with their existing web providers with a “it simply can’t be done.” Well to achieve a unified text size in the WordPress tag cloud here’s how.

add_filter('widget_tag_cloud_args','style_tags');
function style_tags($args) {
$args = array(
     'largest'    => '10',
     'smallest'   => '10',
     'format'     => 'list',
     );
return $args;
}

Disable the WordPress Public Search

Sometimes you just might not need the search functionality for your website but, just by not enabling it doesn’t mean the content is not searchable, If for any reason you need to disable the WordPress public search use this function.

function my_disable_public_search( $q ) {
	if ( $q->is_admin ) {
		return $q;
	}

	if ( $q->is_search ) {
		unset( $_GET['s'] );
		unset( $_POST['s'] );
		unset( $_REQUEST['s'] );
		$q->set( 's', '' );
		$q->is_search = false;
		$q->set_404();
	}
}

add_action( 'parse_query', 'my_disable_public_search', 5 );