Make P2 posts private by default (and control them with tags)

The WordPress theme P2 is great for collaboration and team discussion. Sometimes that discussion can be entirely public, and at other times it makes sense to put the entire site behind a login screen. But what if you want to combine a private discussion stream with public pages? Or mix public posts with private ones? P2 emphasizes quick and easy posting by streamlining the process, but this comes at the expense of options.

This post will show you how to mix and match private and public posts on your P2 blog and will set up a framework for controlling post behavior through tags.

No changes to P2’s files are needed, and this trick will work even with older versions on the theme. This code should be placed in your child theme’s functions.php file or in a plugin of your own. There’s a combined block at the bottom of this post for easy copy and paste.

1. Hook P2’s post save mechanism

While P2 exposes limited posting options, authors using the back-end dashboard have access to the full publishing UI. So we want to make sure to target only posts made from the front-end to avoid confusion for authors using full UI.

Loading our handlers this way allows us to ensure that only P2 posts are affected by these magic tags.

1
2
3
4
5
6
7
8
/**
 * Use this action to catch requests to P2 AJAX functions
 */
function gtp2_add_hooks() {
	add_filter( 'wp_insert_post_data', 'gtp2_maybe_make_post_private', 10, 2 );
	add_action( 'pre_get_posts', 'gtp2_include_private_posts' );
}
add_action('p2_ajax', 'gtp2_add_hooks' );

2. Check for magic tags when saving

Having hooked the action above, we know that the function below will only run on P2 posts. First, the list of tags is split into an array so we can look for them more easily. Then, we search for any tags we have decided will control post behavior, and change the post accordingly.

Check out lines 21-24 — this is where the magic happens. We check whether the post is tagged public. If it is, we leave it alone (P2 posts are public by default). If it isn’t, we change its status to private.

This example only implements a single check, but you can create as many as you want.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * Change post status to private unless it is tagged "public"
 */
function gtp2_maybe_make_post_private( $data, $postarr ) {
 
	$tags = $postarr['tags_input'];
 
	/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */
	if ( ! is_array( $tags ) ) {
		$comma = _x( ',', 'tag delimiter' );
		if ( ',' !== $comma )
			$tags = str_replace( $comma, ',', $tags );
		$tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
	}
 
	/**
	 * Look for tags and control what they do here
	 */
	if( ! in_array( 'public', $tags ) ) {
		// Change attributes of the post here
		$data['post_status'] = 'private';
	}
 
	// Make sure to return the data!
	return $data;
 
}

3. Fix the in-page refresh

P2’s fancy in-page refresh only loads public posts. To make our change seamless to users, this needs to be expanded to load private posts too. We’ll need to add one more short function to accomplish this. You may have seen a hint of it in Step 1, but here’s the function itself.

1
2
3
4
5
6
/**
 * Expand query to include all post status values visible to current user
 */
function gtp2_include_private_posts( $obj ) {
	$obj->set( 'post_status', 'any' );
}

That’s it! Users logged in with Editor or Administrator privileges won’t notice a difference, but other users and anonymous visitors will see only their own posts and those tagged public.

Feel free to drop me a line in the comments if you have any questions or find a use for this on your own sites!


The whole thing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
 * Make all P2 posts Private unless they are tagged "public"
 */
 
/**
 * Use this action to catch requests to P2 AJAX functions
 */
function gtp2_add_hooks() {
	add_filter( 'wp_insert_post_data', 'gtp2_maybe_make_post_private', 10, 2 );
	add_action( 'pre_get_posts', 'gtp2_include_private_posts' );
}
add_action('p2_ajax', 'gtp2_add_hooks' );
 
/**
 * Change post status to private unless it is tagged "public"
 */
function gtp2_maybe_make_post_private( $data, $postarr ) {
 
	$tags = $postarr['tags_input'];
 
	/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */
	if ( ! is_array( $tags ) ) {
		$comma = _x( ',', 'tag delimiter' );
		if ( ',' !== $comma )
			$tags = str_replace( $comma, ',', $tags );
		$tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
	}
 
	/**
	 * Look for tags and control what they do here
	 */
	if( ! in_array( 'public', $tags ) ) {
		// Change attributes of the post here
		$data['post_status'] = 'private';
	}
 
	// Make sure to return the data!
	return $data;
 
}
 
/**
 * Expand query to include all post status values visible to the current user
 */
function gtp2_include_private_posts( $obj ) {
	$obj->set( 'post_status', 'any' );
}

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>