Personalization

As the audience of your website grows, it becomes more challenging to publish content that is relevant to all readers. Personalization gives you the ability to profile each user’s behavior and capture their preferences, allowing you to display more relevant content and ultimately, keep your audience engaged.

What is personalization?

Personalization can mean different things to different people but it mainly involves providing your audience with a more customized and engaging experience. It could mean that you’re providing content that is more relevant to their geographic location or that you’re providing them more relevant content based on what they’ve viewed or liked in the past. Personalization could also mean that your users are able to share content with each other and follow people or topics that they are interested in.

Considerations

Before diving into using the most popular plugins for personalization, there are a few items that you would want to keep in mind, regardless of the type of personalization that you’re interested in. 

  • Sending data to the personalization vendor: If the personalization requires you to send them any data (user data, activity data, etc.),  you will have to include a javascript snippet in all of your pages. Be sure to choose a reliable third party vendor as slow response times on their end could affect your end-user experience.
  • Serving recommendations from the personalization vendor: As the recommendations for a specific type of user may change, the recommended list of content is typically sent dynamically from the personalization vendor’s systems. Some vendors store the user’s behavior in a cookie so that your users don’t have to rely on their service being online but make sure you understand what features of your site (if any) will be impacted if the service vendor’s systems go offline.
  • Limiting the user information that is shared: If you require users to sign in with their account, you have the added advantage of using their historical preferences to personalize. However, this would require you to share additional information with the personalization vendor. It is best to let your personalization vendor know just the username or a separate unique identifier for the user.
  • Supporting cross-channel interactions: If you want the flexibility to capture data from your users across various channels (social media, email, mobile apps, website, etc.), you will need a vendor that can unify data from all of these channels to a single user profile (typically based on the email address). Most personalization vendors that support cross-channel data gathering will also let you publish your recommendations through any of these channels.

Types of personalization

There are no limits to how you can personalize your content but the most popular options include:

Customer Identity & Access Management

Personalizations rely heavily on understanding who your customers are. A sophisticated customer identity and access management solution will help you identify your customers regardless of the device or channel they’re engaging from, allowing you to keep your message consistent across a diverse platform.

Janrain, a Featured Partner of VIP, provides a platform that combines your ability to acquire users across multiple digital and marketing channels. In addition to providing a Single Sign-On solution, they provide a hosted user database and provide integration for social sharing.

We have also had VIP clients use Gigya, another popular platform to securely manage and update user profiles, thereby giving you a great starting point to provide personal experiences.

Custom Social Network

If you have built a community, you may be looking to empower your users to share stories, like each other’s’ contributions and have a newsfeed of updates from the people or things that they follow.

The popular BuddyPress plugin built by the WordPress community provides a lot of social network features out of the box. It provides both private messaging and public sharing. However, the vision of some of our clients were better met by using a Featured Partner for custom development.

Predictive Marketing

You might have noticed that some sites have a ‘You might also like’ section, listing content related to what you have been reading. There is another variant of this personalization where content related to the current page is listed. These dynamically shortlisted links are more relevant to your users and have a higher click-through rate.

One of our featured partners: Sailthru, is the leading provider of personalized marketing communications. Their WordPress plugin makes it easy to provide personalized content through their Scout and Concierge modules. Scout provides content relevant to a page whereas Concierge provides content that is recommended for the specific user. Under the covers, both modules use predictive marketing algorithms to determine the best recommendations for your users.  We have had multiple VIP clients use Sailthru’s straightforward integration to personalize their content.

If you’re looking to add a simple ‘Related Posts’ section to your website, WordPress.com’s Related Posts feature may be all you need. It’s powered by the popular Jetpack addon, which uses ElasticSearch to analyze your content and understand its relevance to the rest of your website. You can finetune how the recommendations are displayed using the customization options.

Geo-specific content

As your audience grows, you might find it challenging to provide content that is engaging to your users regardless of where they’re from. WP.com Geo Uniques allows you to target distinct geographic markets with different content. You also have the option of defining custom location groups so that you can target groups smaller than countries.

Keyring

Keyring is a generalized framework for WordPress which handles authentication with, and authenticated requests to remote services. It provides a set of predefined “Services” which describe how to communicate with a collection of popular platforms, and also makes it easy for you to plug into that framework and define your own Services for other systems.

On WordPress.com VIP, Keyring is used in it’s “headless” state, which means there is no UI and credentials need to be set within theme code.

Please refer to the Keyring documentation.

List Posts By A Co-Author

When using Co-Authors Plus, you may want to create a listing of all posts by a given co-author. Co-Authors Plus deviates slightly from how core WordPress works in that it stores byline information in a custom ‘author’ taxonomy. It works in this manner because a post (let it be a Post, Page, or Custom Post Type) can have multiple taxonomy terms associated with it.

To list some or all posts from a co-author, you’ll want to create a new WP_Query object based on the author term for a given user or guest author. Here’s an example of what that might look like:

// Build the query arguments
$args = array(
	'post_type' => 'post',
	'posts_per_page' => 10,
	'post_status' => 'publish',
	'author_name' => $user_login,
);
$author_query = new WP_Query( $args );

if ( $author_query->have_posts() ) :
	while ( $author_query->have_posts() ) : $author_query->the_post();

	// Do your presentation

	endwhile;
endif;

Configure Ad Code Manager to manage the advertisements on your site

Ad Code Manager is a VIP-sponsored plugin designed to make it easier to manage the ad codes used to display advertisements on your site. There’s a little bit of work you’ll need to do up front, however, in order to integrate Ad Code Manager with your theme.

Note: WordPress.com Enterprise users should contact support and we’ll take care of the configuration for you.

The high-level idea behind Ad Code Manager is that it gives non-developers an admin interface to manage your ad codes. It then permits users to (optionally) target specific ad codes using conditionals like is_home() and is_single(). Ad codes are associated with positions in the theme through the use of ad tags.

Currently, Ad Code Manager easily integrates with Google Doubleclick For Publishers Async and Google AdSense. Other ad providers are supported with additional configuration.

Google AdSense and DoubleClick For Publishers Async

Let’s use AdSense as our first example. You’ll want to incorporate some of the default ad tags into your theme by use of do_action(). Here’s an example you might put in your header.php file:

do_action( 'acm_tag', '728x90_leaderboard' );

Once you’ve done so, you can select the “Google AdSense” provider in the admin. Ad codes can be registered against ad tags (positions) by choosing the ad tag from the drop down, entering the tag ID and publisher ID, and hitting “Add New Ad Code”.

Google AdSense configuration

And like that, your 728×90 leaderboard will appear on your site.

The Google AdSense configuration comes with many of Google’s suggested sizes. Additional ad tags can be registered by the way of filtering:

add_filter( 'acm_ad_tag_ids', 'acmx_filter_ad_tag_ids' );
function acmx_filter_ad_tag_ids( $ids ) {

	$ids[] = array(
		'tag'       => '100x100_smallsquare',
		'url_vars'  => array(
			'tag'       => '100x100_smallsquare',
			'height'    => '100',
			'width'     => '100',
			),
		'enable_ui_mapping' => true,
	);

	return $ids;
}

Keep in mind that you’ll still need to incorporate a do_action( 'acm_tag', '100x100_smallsquare' ); in your theme in order to display the ad tag.

If you choose Google DFP Async as your provider, you’ll likely need to register additional ad tags, as we only package two default ad tags.

Custom Ad Provider Implementations

As mentioned previously, other ad code providers are supported with additional configuration. Here’s an example of the different filters you would use to configure the older version of Google Doubleclick For Publishers:

<?php
/**
 * Define the default URL to be used when rendering ad codes
 */
add_filter( 'acm_default_url', 'acmx_filter_default_url' ) ;
function acmx_filter_default_url( $url ) {
	if ( 0 === strlen( $url )  ) {
		return "http://ad.doubleclick.net/adj/%site_name%/%zone1%;s1=%zone1%;s2=;pid=%permalink%;fold=%fold%;kw=;test=%test%;ltv=ad;pos=%pos%;dcopt=%dcopt%;tile=%tile%;sz=%sz%;";
	}
}

/**
 * Whitelist the DFP URL to be used in ad tags. The whitelist
 * helps prevent execution of arbitrary scripts
 */
add_filter( 'acm_whitelisted_script_urls', 'acmx_filter_whitelisted_script_urls');
function acmx_filter_whitelisted_script_urls( $whitelisted_urls ) {
	$whitelisted_urls = array( 'ad.doubleclick.net' );
	return $whitelisted_urls;
}

/**
 * Define the different ad tags (locations) you'd like to use in your theme
 */
add_filter( 'acm_ad_tag_ids', 'acmx_ad_tags_ids' );
function acmx_ad_tags_ids( $ad_tag_ids ) {
	return array(
			array(
					'tag' => '728x90-atf',
					'url_vars' => array(
						'sz' => '728x90',
						'fold' => 'atf',
						'width' => '728',
						'height' => '90',
				)
			),
			array(
					'tag' => '728x90-btf',
					'url_vars' => array(
						'sz' => '728x90',
						'fold' => 'btf',
						'width' => '728',
						'height' => '90',
				)
			) ,
			array(
					'tag' => '300x250-atf',
					'url_vars' => array(
						'sz' => '300x250',
						'fold' => 'atf',
						'width' => '300',
						'height' => '250',
				)
			),
			array(
					'tag' => '300x250-btf',
					'url_vars' => array(
						'sz' => '300x250',
						'fold' => 'btf',
						'width' => '300',
						'height' => '250',
				)
			),
			array(
					'tag' => '160x600-atf',
					'url_vars' => array(
						'sz' => '160x600',
						'fold' => 'atf',
						'width' => '160',
						'height' => '600',
				)
			),
			array(
					'tag' => '1x1',
					'url_vars' => array(
						'sz' => '1x1',
						'fold' => 'int',
						'pos' => 'top',
					)
			)
		);	
}

/**
 * Register the full <script> output to use with each ad tag
 */
add_filter( 'acm_output_html','acmx_filter_output_html', 5, 2 );
function acmx_filter_output_html( $output_html, $tag_id ) {
	$output_html = '<!-- DFP %pos% %sz% ad tag --> 
	<script language="JavaScript" type="text/javascript">
if (typeof ord=='undefined') {ord=Math.random()*10000000000000000;}
if (typeof(dfp_tile) == 'undefined') dfp_tile=%tile%;
document.write('<script language="JavaScript" src="%url%ord=' + ord + '?" type="text/javascript"></script>');
</script><noscript><a href="%url%ord=%random%?" target="_blank"><img src="%url%ord=%random%?" width="%width%" height="%height%" border="0" alt=""></a></noscript>
<!-- //DFP %pos% %sz% tag -->';
	return $output_html;
}

/**
 * Fine tune our output tokens
 * This is the real example of how easily you can modify output
 * depending on your ad network specs
 */
add_filter('acm_output_tokens', 'acmx_filter_output_tokens', 5, 3 );
function acmx_filter_output_tokens( $output_tokens, $tag_id, $code_to_display ) {
	global $dfp_tile;
	global $dfp_ord;
	global $dfp_pos;
	global $dfp_dcopt;
	global $wp_query;
	
	// We can't really rely on get_permalink() so use $_SERVER['REQUEST_URI] as bulletproof solution for generating unique pids
	$link = strlen( $_SERVER['REQUEST_URI'] ) > 1 ? sanitize_key( $_SERVER['REQUEST_URI'] ) : home_url();
	$output_tokens['%permalink%'] = str_replace( array( '/',':', '.' ), "", $link ); 
	$output_tokens['%random%'] = $dfp_ord;
	$output_tokens['%tile%'] = ++$dfp_tile;
	if (  false === $dfp_pos[ $code_to_display['url_vars']['sz'] ] ) {
		$output_tokens['%pos%'] = 'top';
		$dfp_pos[ $code_to_display['url_vars']['sz'] ] = true;
	} else {
		$output_tokens['%pos%'] = 'bottom';
	}
	if ( ! $dfp_dcopt ) {
		$output_tokens['%dcopt%'] = 'ist';
		$dfp_dcopt = true;
	} else {
		$output_tokens['%dcopt%'] = '';
	}
	
	$output_tokens['%test%'] = isset( $_GET['test'] ) && $_GET['test'] == 'on' ? 'on' : '';
	
	return $output_tokens;
}

Plugins on WordPress.com VIP

Here at WordPress.com VIP, we maintain a list of plugins that have been reviewed and approved by our engineers.These pre-reviewed plugins help speed up review for your projects on VIP and ensure the 3rd-party code you’re using is safe and scalable.

There are 3 different “types” of plugins on WordPress.com VIP:

  • The Shared Plugin repository, which is reviewed and maintained by the WordPress.com VIP team
  • The Reviewed Plugins list, which are reviewed and recommended by the WordPress.com VIP team. These plugins are not maintained by the VIP team.
  • Custom Plugins developed by your team and added to your theme.

Shared plugins

The Shared Plugin repository is collection of plugins that are reviewed and maintained by the WordPress.com VIP team. As a VIP developer you will have read access to our shared plugins repository, which contains some Automattic plugins as well as plugins from our Featured Partners. There are two ways to activate a shared plugin: from your VIP Dashboard or in your theme’s code. We recommend choosing one method and sticking to it to make it easy to determine which plugins are enabled for your site.

Note: On VIP Go, shared plugins are not necessarily available automatically – see the mu-plugins repo for what’s available out of the box.

Activating a Shared Plugins from your Dashboard

Simply navigate to Plugins and Services in your VIP dashboard, find the plugin you’d like, and click “Activate.”

Activating a Plugin

Activating a Shared Plugin In Your Theme

Once you have SVN access to your VIP theme, you will also have read access to the Shared Plugins repository. To test these plugins in your development environment, use your WordPress.com username and password to check out a copy of them from https://vip-svn.wordpress.com/plugins/ using Subversion. To match our environment, they should be checked out to wp-content/themes/vip/plugins/ and not wp-content/plugins/ like you would normally.

svn co https://vip-svn.wordpress.com/plugins/

To load plugins from the shared plugins folder, you can use the following function call:

wpcom_vip_load_plugin( 'zoninator', 'plugins', '0.6' );

Note that the third parameter, `$version` specifies the specific version you wish to load.

Updating Shared Plugins

We maintain two versions of each shared plugin at any one time, allowing you to upgrade to new versions at more of your own pace. We very much recommend you always use the latest available version which you can find by looking in the shared plugins repository itself.

New versions are announced through the VIP Lobby and the oldest version is deprecated simultaneously. Older versions are removed one month after a new version is committed, giving you plenty of time to test and upgrade.

If you need assistance, or would like to request an upgrade, don’t hesitate to open up a ticket with us.

Reviewed Plugins

Each time we review a plugin (or a new version), we update this list of Reviewed Plugins. You can then bundle any of those plugins into your theme, and it won’t need to be reviewed. To use a plugin on this list, simply commit the plugin to your theme in a single commit, letting us know in the message that it’s a reviewed plugin. We will review and deploy. Please note that we do not maintain these plugins, so your team will be responsible for updates.

Activating plugins that you bundle in your theme is as simple as placing them into a plugins directory, and loading them within your functions.php like so;

wpcom_vip_load_plugin( 'custom-plugin', 'my_theme_directory_name' );

If an open-source plugin you’d like to use is not on this list, please open a ticket to ask us to review (more details on that here). Once the review is complete, we’ll add the plugin to this Reviewed Plugins list, benefiting all VIP clients.

We’ll use the VIP Lobby to post about updates to the reviewed list, so you can keep up-to-date on this list.

Custom Plugins

These are any plugins that you develop yourself and bundle in your theme. These will always be reviewed according to the same process as your theme – you can read more about plugin review here.

If the plugin is around 1,000 lines of code (excluding CSS), you can commit it to the deploy queue as part of your regular work. If it is larger, please zip the plugin and submit it via tickets for review.

Once your plugin is approved, add it to the “plugins” directory within your theme directory. To activate it, use wpcom_vip_load_plugin in functions.php with ‘my_theme_directory_name’ as the second parameter, e.g.:

wpcom_vip_load_plugin( 'custom-plugin', 'my_theme_directory_name' );

Using the Liveblog Plugin

Introduction

The Liveblog Premium Add-On helps with quick and simple blogging for following fast-paced events. It allows authors to edit the post quickly, and readers to receive realtime updates.

Activating the Liveblog Plugin

To activate the Liveblog Premium Add-On, please get in touch!

Creating a Liveblog

The liveblog lives inside of a regular WordPress post. First create a new post, complete with title, category, and maybe a short introduction. Once the liveblog plugin is installed, you will see a liveblog box on your “Edit Post” page. Simply click “Enable” to activate it, and publish the post.

If you can’t find the box, be sure that it is toggled on under “Screen Options” in the top right corner of posting page.

Screen Shot 2013-01-18 at 12.19.13 PM

Posting to the Liveblog

To post to the liveblog, navigate to the live post, and start typing. Click “Publish Update,” and your readers will see the post appear at the top of their screen. That’s all there is to it.

Screen Shot 2013-01-18 at 12.21.43 PM

Adding a Photo

To add a photo to your update, simply drag-and-drop it into the posting box from your desktop. It will upload the image and include a link. To see the image, click “Preview.”

You can also add photos from the internet by pasting in the direct URL to the image.

drag

Embedding Media

To embed tweetsYouTube videos, Vimeo videosInstagram photosHulu clips, or Spotify songs, simply paste the URL while viewing the media into the posting box on its own line. More details can be found about each media type in the links above.

Screen Shot 2013-01-18 at 12.32.59 PM

Formatting a Post

The liveblog posting box takes standard HTML formatting. To format text, simply wrap it in HTML tags.

Examples:

<strong>bold</strong>
<i>itals</i>
<u>underline</u>
<blockquote>

quote

</blockquote>
<a href=”http://www.wordpress.com”> a link </a>

Links that are pasted directly the posting box will also be automatically hyperlinked.

Manually embed a Liveblog

Sometimes you may need to manually insert the Liveblog into your theme. For this, we provide a function which simply outputs the Liveblog HTML on a post where the Liveblog is enabled.

wpcom_liveblog_get_output()

Editing Previous Posts

While a liveblog is enabled, you can edit previous posts by clicking the “Edit” button next to the update.

Screen Shot 2013-01-18 at 11.40.43 AM

Archiving a Liveblog

Once the event has wrapped up, you can archive your liveblog. This means that visitors will still be able to see the blog, but the editing tools will go away and the post will stop polling for updates. You can archive and re-enable a liveblog from the Edit Post page.

Screen Shot 2013-01-18 at 11.15.12 AM

When a liveblog is archived, your editors will see a notification that says the liveblog must be enabled to accept new posts.

Screen Shot 2013-01-18 at 11.19.52 AM

“Smart” Updates

The liveblog uses smart updates, making it easy for your readers to enjoy your liveblog without being overwhelmed with updates. If the reader’s browser is at the top of the post, new posts will automatically appear, highlighted in yellow.

Screen Shot 2013-01-18 at 11.32.38 AM

However, if your reader has scrolled down the post to catch up on previous updates, liveblog will wait to update with new posts. Instead, a notification bar will appear at the top of the screen. When the reader clicks on the bar, the new updates will resume loading at the top of the page.

Screen Shot 2013-01-18 at 11.30.51 AM

Post times are also now relative, which means it will display as “2 minutes ago,” with the time updating every minute.

Overriding default templates

Templates used by the plugin can be found in the /templates/ directory of the plugin.

You can edit these files in an upgrade-safe way using overrides. Copy the files you want to change into a directory named /liveblog within the root of your theme, keeping the same filename.

Eg: In order to override a single entry template copy templates/liveblog-single-entry.php to yourtheme/liveblog/liveblog-single-entry.php

The copied file will now override the Liveblog default template file.

Check out the related code on GitHub.

Custom location for Liveblog templates

In case the /liveblog directory in the root of your theme is not what would suit your needs, you can take advantage of the `liveblog_template_path` filter and pass in a custom absolute path without trailing slash which would then be used for template look-up.

Check out the related code.

Need more help?

If you have further questions, please don’t hesitate to contact us.

Incorporate Co-Authors Plus template tags into your theme

Co-Authors Plus is a plugin maintained by WordPress.com VIP which makes it easy to assign one or more bylines to a post. Upon activation, you’ll be able to start assigning multiple bylines right away. In order for those bylines to appear on the frontend, you may need to make some small modifications to your theme.

Available Template Tags

WordPress offers template tags like the_author() and the_author_posts_link() to display byline information associated with each post post. You might see these inside files like single.php and author.php

Co-Authors Plus has similar template tags for displaying multiple bylines. These are located in the template-tags.php file. The most relevant are:

/**
 * Outputs the co-authors display names, without links to their posts.
 * Co-Authors Plus equivalent of the_author() template tag.
 *
 * @param string $between Delimiter that should appear between the co-authors
 * @param string $betweenLast Delimiter that should appear between the last two co-authors
 * @param string $before What should appear before the presentation of co-authors
 * @param string $after What should appear after the presentation of co-authors
 * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
 */
function coauthors( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ){
	return coauthors__echo('display_name', 'field', array(
		'between' => $between,
		'betweenLast' => $betweenLast,
		'before' => $before,
		'after' => $after
	), null, $echo );
}

/**
 * Outputs the co-authors display names, with links to their posts.
 * Co-Authors Plus equivalent of the_author_posts_link() template tag.
 *
 * @param string $between Delimiter that should appear between the co-authors
 * @param string $betweenLast Delimiter that should appear between the last two co-authors
 * @param string $before What should appear before the presentation of co-authors
 * @param string $after What should appear after the presentation of co-authors
 * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
 */
function coauthors_posts_links( $between = null, $betweenLast = null, $before = null, $after = null, $echo = true ){
	return coauthors__echo('coauthors_posts_links_single', 'callback', array(
		'between' => $between,
		'betweenLast' => $betweenLast,
		'before' => $before,
		'after' => $after
	), null, $echo );
}

/**
 * Outputs the co-authors display names, with links to their websites if they've provided them.
 *
 * @param string $between Delimiter that should appear between the co-authors
 * @param string $betweenLast Delimiter that should appear between the last two co-authors
 * @param string $before What should appear before the presentation of co-authors
 * @param string $after What should appear after the presentation of co-authors
 * @param bool $echo Whether the co-authors should be echoed or returned. Defaults to true.
 */
function coauthors_links($between = null, $betweenLast = null, $before = null, $after = null, $echo = true ) {
	return coauthors__echo('coauthors_links_single', 'callback', array(
		'between' => $between,
		'betweenLast' => $betweenLast,
		'before' => $before,
		'after' => $after
	), null, $echo );
}

Each of these template tags will present different aspects of the multiple bylines. For instance, the first will display the first and last name of each co-author without any links. The second will display the first and last name of co-author linking back to their author profile page. And so on.

Integrating Template Tags Into Your Theme

To integrate Co-Authors Plus, you’ll want to replace existing author template tags in your theme with a simple conditional that uses the Co-Authors Plus template tags if Co-Authors Plus is available. The conditional prevents your site from breaking (e.g. white screen of death) if Co-Authors Plus isn’t activated.

For example, here’s how you would update the_author_posts_link() to instead use coauthors_posts_links():

if ( function_exists( 'coauthors_posts_links' ) ) {
    coauthors_posts_links();
} else {
    the_author_posts_link();
}

However, the example above is a relatively simplistic way of presenting bylines. There’s a good chance your theme will need an adaptation of it.

For instance, here’s how the change looks for the Hybrid theme:

function hybrid_entry_author_shortcode( $attr ) {
	$attr = shortcode_atts( array( 'before' => '', 'after' => '' ), $attr );
	if ( function_exists( 'coauthors_posts_links' ) ) {
		$author = coauthors_posts_links( null, null, null, null, false );
	} else {
		$author = '<span class="author vcard"><a class="url fn n" href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '" title="' . esc_attr( get_the_author_meta( 'display_name' ) ) . '">' . get_the_author_meta( 'display_name' ) . '</a></span>';
	}
	return $attr['before'] . $author . $attr['after'];
}

Here’s the new function for TwentyTen:

if ( ! function_exists( 'twentyten_posted_on' ) ) :
/**
 * Integrate Co-Authors Plus with TwentyTen by replacing twentyten_posted_on() with this function
 */
function twentyten_posted_on() {
	if ( function_exists( 'coauthors_posts_links' ) ) :
		printf( __( '<span class="%1$s">Posted on</span> %2$s <span class="meta-sep">by</span> %3$s', 'twentyten' ),
			'meta-prep meta-prep-author',
			sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><span class="entry-date">%3$s</span></a>',
				get_permalink(),
				esc_attr( get_the_time() ),
				get_the_date()
			),
			coauthors_posts_links( null, null, null, null, false )
		);
	else:
		printf( __( '<span class="%1$s">Posted on</span> %2$s <span class="meta-sep">by</span> %3$s', 'twentyten' ),
			'meta-prep meta-prep-author',
			sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><span class="entry-date">%3$s</span></a>',
				get_permalink(),
				esc_attr( get_the_time() ),
				get_the_date()
			),
			sprintf( '<span class="author vcard"><a class="url fn n" href="%1$s" title="%2$s">%3$s</a></span>',
				get_author_posts_url( get_the_author_meta( 'ID' ) ),
				esc_attr( sprintf( __( 'View all posts by %s', 'twentyten' ), get_the_author() ) ),
				get_the_author()
			)
		);
	endif;
}
endif;

Here are a couple more threads you can look at for insights:

Add custom author biographies with Post Author Box

The Post Author Box plugin allows you to append or prepend an informational box on any post, page, or other view without having to modify your theme. It has no opinions about what information is displayed or how it’s presented.

To activate Post Author Box, navigate to plugins in your dashboard and click “Activate.” Once this plugin is activated, you can edit the settings under Settings > Post Author Box.

Here, you can select whether you want the custom Author Bio to appear at the top or bottom of your content. You can also specify which content types you would like this custom bio to appear.

Under display configuration, you can customize your author bios using HTML. Simply use the tokens presented to fill in the author information. For example:

This display configuration:

<p>Contact %display_name% at <a href="mailto:%email%">%email%</a></p>

Displays as:
Contact Daniel Bachhuber at daniel@automattic.com

Co-Authors Plus: Add guest bylines to your content

Co-Authors Plus is a plugin maintained by WordPress.com VIP which makes it easy to assign one or more bylines to a post. With the guest authors feature, you can assign a byline to content without having to create a corresponding WordPress account. And, if your theme is using the appropriate template tags, you can create guest bylines without any additional configuration.

Creating or Editing Guest Authors

On WordPress.com VIP, guest authors can be created and managed under “Users” -> “Guest Authors”.

Each guest author can have many of same fields a normal WordPress user would typically have, including display name, email address, and website. You can assign a featured image in order to override the avatar typically associated with the email address.

Once you’ve created your guest author, his or her byline can be assigned to a post using the normal Co-Authors Plus interface.

Details for Developers

Incorporating new profile fields

The guest authors feature of Co-Authors Plus was written with extensibility in mind. The default set of profile fields can easily be manipulated using accessible filters. If you want to place your field in one of the existing post meta boxes, it can be as simple as the following example:

Then, for use on the frontend, the new field is automatically loaded onto the $coauthor object.

Migrating users to guest authors with wp-cli

If you’re performing a migration of users to co-author guest authors, there are a couple of helpful wp-cli commands packaged with the plugin:

  • wp co-authors-plus create-guest-authors will create guest authors for all of your existing users
  • wp co-authors-plus assign-user-to-coauthor will then assign all of the posts associated with old user to your new guest author

So, the steps to migrate all of your users/authors to your WordPress.com VIP site would include:

  1. Install the Co-Authors Plus plugin on your staging site
  2. Run the create-guest-authors CLI command to create the Guest Authors automatically
  3. Perform an export from your staging site and save the resulting WXR file. The WP-CLI guest authors will be included in this export.
  4. Invite all of your normal authors to your WordPress.com VIP site and have them create their own WordPress.com user accounts.
  5. Create a mapping CSV file for editorial users who require real logins from their login on the staging site to their login on WP.com.
    The CSV file format is as simple as:

    johnsmith, johnsmithwp
    janesmith, janesmithwp
    johndoe, johndoewp
    
  6. Send us the WXR and mapping CSV, and we’ll run the import for you. While Co-Authors Plus will bring over all the bylines, we’ll use the mapping CSV to preserve the bylines for users with real logins.
  7. Have your team QA the imported authors.

Allow Contributors to Upload Images

When images or other attachments are uploaded to a non-private WordPress site, the images are immediately public and can be shared on the Internet. This is why Contributors cannot normally upload images or files.

The VIP plugin repository file vip-helper-wpcom.php includes a helper function called vip_contrib_add_upload_cap() which will allow Contributors to upload. For Enterprise sites, there’s a plugin that can be activated from the admin called “Allow Contributors to Upload.”

Ready to get started?

Tell us about your needs

Let us lead the way. We’ll help you select a top tier development partner. We’ll train your developers, operations, infrastructure, and editorial teams. We’ll coarchitect your deployment processes. We will provide live support for peak events. We’ll help your people avoid dark alleys and blind corners, and reduce wasted cycles.