WordPress – redirect traffic to your primary domain

This is a snippet that allows you to redirect all your incoming traffic to a single primary domain.

You may end up with web sites that have multiple domains. Most commonly, site owners will want both their www and non-www domain names to end up in the same place. Later version of WordPress handle this automatically. However, web sites can change domain name for many reasons (e.g company name change, development work on a sub-domain, site restructure and so on).

It generally, and usually, best to control your traffic by configuring your web server to handle any such change. There are times though when this is not possible, or simple that you want (as a WordPress developer) the speed and control that goes with managing it from with WordPress itself.

function tcb_redirect_to_primary_domain() {
  $schema           = is_ssl() ? 'https://' : 'http://';
  $requested_domain = strtolower($schema . $_SERVER['HTTP_HOST']);

  $primary_domain = get_bloginfo('siteurl');
  if( defined('WP_SITEURL') && '' != WP_SITEURL )
    $primary_domain = WP_SITEURL;

  if( empty($primary_domain) ) return; // Something is really wrong.

  $primary_domain = strtolower($primary_domain);

  // strip subdirectories.
  if( preg_match('|^(https?://)([^/]+)/.+|', $primary_domain, $matches) )
    $primary_domain = $matches[1] . $matches[2];

  $primary_domain    = rtrim($primary_domain, '/');
  $requested_domain  = rtrim($requested_domain, '/');

  if( $primary_domain !== $requested_domain ){
    $redirect = $primary_domain . $_SERVER['REQUEST_URI'];
    wp_redirect( $redirect, 302 );
    exit;
  }
}
add_action('template_redirect', 'tcb_redirect_to_primary_domain');

This is pretty much a follow up to Divy Dovy’s post on WordPress domain redirection.

After Dave asked me about it, I realised that what I use at work is at times more simple, and others more complex, but was never really relevant to any other company or person. So I thought I would strip out the irrelevant bits and see what was left. and as you can see it is really not much more than Dave’s excellent snippet. He should give himself more credit!

WordPress – Force the Kitchen Sink always on

The two most common questions that our WordPress clients ask us is “where has the colour selector gone?” and “why can I no longer chose which H1 – H6 tag to use?”. The answer is very easy, they need to switch the kitchen sink back on. Sometimes it is easy to forget that there’s a whole world of people out there who just don’t care about things like CMS or WordPress let alone The WYSIWYG content editor. And rightly too.

The answer was to add a short filter to the theme (or plugin) that forces the kitchen sink to always be on. Then there is no confusion.

/**
 * Force the kitchen sink to always be on
 */
add_filter( 'tiny_mce_before_init', 'tcb_force_kitchensink_open' );
function tcb_force_kitchensink_open( $args ) {
  $args['wordpress_adv_hidden'] = false;
  return $args;
}

[UPDATE 2013-04-02]
I have updated this to use WordPress TinyMCE filters. The old way would not work with more recent versions of WordPress (which is probably a good thing).

Why Apache .htaccess files are evil

Evil? Wow, that’s a bit strong. Besides, everybody loves Apache and their .htaccess files! Don’t they? Well, I’m not so keen. I think there are two important issues with Apache. Firstly, out of the box (as it were), it comes badly configured. For anyone wanting to dip their toes in server building and administration, they will soon find their server down and out for the count as it OOMs (Out Of Memory)¬†into oblivion. That’s a subject for another day.

Secondly, I believe that .htaccess files are bad. It’s like giving your three-year old the keys to your house. Yes, it certainly will be easier for you; your child can decide when to come and go without having to interrupt your day. But you really don’t know just when they will give the key to a dodgy so-and-on with thieving¬†intentions

Web servers form part of the host configuration and set up. They direct and manage traffic to and from the server. Who should tell it how it does that? The system administrator. Giving control of the w server to its applications is intrinsically wrong.

Allowing applications to control how the server works, can certainly make peoples’ live’s easier. The pay off, though, is that it makes the sever less secure. To make a simile, it would be like getting rid of passports and border control, or being more exact, it would be like letting every individual person decide what the border controls are and what verifies their passport as being a document that uniquely identifies them. People could just make anything up. Well, on a server, that is what .htaccess files allow you to do.

Personally I no longer support .htaccess files. Just like border control and passports are worth the¬†encumbrance, so is disabling .htaccess (or just not using Apache at all). And I find that gradually, they aren’t missed. It is just a shame that I have to put the time and effort into effectively working around an issue that should not exist¬†in the first place.

jQuery AJAX enable your WordPress forms

I’m often building forms for client projects, and they nearly always prefer them have some AJAX goodness. To this end I’ve built a small jQuery file that gets added to all my projects. It depends on Malsup’s AjaxForm and Bassistance’s Form Validation.

/**
 * Generic *SIMPLE* Ajax Form handling
 */
jQuery(document).ready(function($){
 $('.simpleajaxform').each(function(){
  $(this).attr('method', 'post');
  var target = $(this).attr('target');
  var func   = $(this).attr('function');
  options    = {};
  if( target || func ){
   if( target ) $('#'+target).html('').hide();
   options = {
    success:      simpleajaxform_success,
    beforeSubmit: simpleajaxform_submit
   };
  }

  $(this).ajaxForm(options);
 });
});

/**
 * On submit: clear any previous update and tell the user
 *  that we're trying to update
 */
function simpleajaxform_submit(formData, jqForm, options) {
 if( !jqForm.valid() ) return false;
 target = jqForm.attr('target');

 if( target )
  jQuery('#'+target).html('Updating, please wait...').removeClass('updated').addClass('updating').show();
 return true;
}

/**
 * Response: show message in target div.
 */
function simpleajaxform_success(responseText, statusText, xhr, jQForm){
 if( jQForm === undefined )
  jQForm = xhr;
 if( jQForm === undefined ){
  alert('Cannot handle response properly');
  return;
 }
 target = jQForm.attr('target');
 if( target )
  jQuery('#'+target).removeClass('updating').addClass('updated').html(responseText);

 hide = jQForm.attr('hide');
 if( hide )
  jQuery('#'+hide).hide();

 handler = jQForm.attr('function');
 if( handler )
  eval( handler+'(responseText, jQForm)' );
}

Take any form that submits to an AJAX handler (see below for notes on WordPress and ‘action’), add the ‘simpleajaxform‘ class and either a ‘target‘ or ‘function‘ property. Job done.

Here’s a stripped down example using it:

<form class="simpleajaxform" action="<?php echo admin_url('admin-ajax.php');?>" target="targetdiv">
 <input type="hidden" name="action" value="my_wp_action" />
 <input class="required" type="text" name="message" value="" />
 <input type="submit" name="submit" value="DO STUFF" />
</form>

WordPress, Javascript (jQuery) and ACTION

If you add a field named ‘action‘ in a form, then jQuery can get a bit confused by the syntax ‘jQuery(‘#someformid’).attr(‘action’,ajaxurl)‘. I’ll leave figuring that out as an exercise for the reader (or for a later post).

Download showcase plugin here: simple-ajax-form

Only show your own posts in admin (hiding others’ posts from contributors)

I’ve written some themes and plugins that make extensive use of WordPress custom post types. These are coupled with new roles that lie somewhere between contributor and editor. The member can publish some post types, submit others for review. It has raised the problem that I do not want these members to see other members’¬†posts. The reasons for this are twofold. Firstly the admin screen will get busy, there will be too much noise, this will usually be too complex for them to handle. Secondly I don’t want them looking at other member’s¬†unpublished posts.

The answer is to filter the global $query object, restricting the member to their own posts. This can either be white or black labelled depending on how you wish to go.

/**
 * This restricts posts in wp-admin for Subscribers
 *  and Contributors to their own posts only.
 * However, none of the admin-table-filters hookable into,
 *  so you'll need some CSS too.
 */
add_filter('pre_get_posts', 'tcb_admin_show_only_authors_posts');
function tcb_admin_show_only_authors_posts($query) {
  global $current_user;
  $post_type          = $query->get('post_type');
  $allowed_post_types = array();
  if ( in_array($post_type, $allowed_post_types) ) return $query;

  $restricted_roles = array('subscriber', 'contributor');
  get_currentuserinfo();
  $user_roles = $current_user->roles;
  $role       = reset($user_roles);
  if( $query->is_admin && in_array($role, $restricted_roles) ){
    global $user_ID;
    $query->set('author', $user_ID);
  }
  return $query;
}

The filter only works for the actual editable content. The (useful) menu across the top allowing people to select mine or published uses some separate SQL, and there are no hooks in the code. So these must be hidden using CSS.

This should get you started:

#editor-toolbar,
#misc-publishing-actions,
#slugdiv,
.subsubsub,
.search-box,
.author-other,
.tablenav,
#contextual-help-link-wrap,
#media-upload-header{
 display: none;
}