Tom Maitland

Creates digital things at Agency. WordPress developer. Web designer. Communicates for UN Youth Australia.

WordPress Plugin: Restrict Page Parents

09 December 2012

Note: Restrict Page Parents has grown up!

It’s been rewritten from the ground up, using much better (proper) coding techniques. It’s faster, more comprehensive, reliable and available from the WordPress plugin repository. The new plugin includes an options page to control your permissions, and the ability to make a ‘page parent’ required.

You can find out more at the plugin site and Github project.



The new UN Youth Australia website involves an extremely granular permissions management system behind the scenes. I’ve had to use a range of plugins to pigeon-hole specific users into only being able to edit their content in their little corner of the website.

Most of this was easily accomplished with existing plugins, except restricting the parent pages a user can select for their pages. To solve this, I’ve quickly made a plugin that restricts the page parent options under ‘Page Attributes’ to only the pages the current user is an author of. The plugin only applies these restrictions for users without the edit_others_pages capability.

The plugin simply disables the option for any pages that aren’t owned by the current user.

I’ve included the plugin code below, or download the zip. Just drop the restrict-page-parents.php file into your plugins directory.

Note: There may be bugs, use at your own risk. It was written for a fairly specific purpose.

[codesyntax lang=”php”]

Plugin Name: Restrict Page Parents
Plugin URI:
Description: Restricts parent page options to pages authored by the current user.
Author: Tom Maitland
Version: 0.1Beta
Author URI:

	Copyright (c) 2012 Tom Maitland (
	Default Page Parent is released under the GNU General Public
	License (GPL)

	This is a WordPress 3 plugin (

function restrict_parent_pages($content) {

	global $current_user;

	if (!current_user_can('edit_others_pages')) {

	    $args = array(
			'sort_order' => 'ASC',
			'sort_column' => 'menu_order',
			'hierarchical' => 1,
			'authors' => $current_user->ID,
			'post_type' => 'page',
			'post_status' => 'publish'
		$pages = get_pages($args); 

		$content = str_replace('<option value="">(no parent)</option>', '<option disabled value="">(no parent)</option>', $content);
		$content = str_replace('<option class="level-0"', '<option disabled class="level-0"', $content);
		$content = str_replace('<option class="level-1"', '<option disabled class="level-1"', $content);
		$content = str_replace('<option class="level-2"', '<option disabled class="level-2"', $content);
		$content = str_replace('<option class="level-3"', '<option disabled class="level-3"', $content);
		$content = str_replace('<option class="level-4"', '<option disabled class="level-4"', $content);

		foreach ($pages as $page) {
			$content = str_replace('<option disabled class="level-0" value="' . $page->ID . '"', '<option class="level-0" value="' . $page->ID . '" selected', $content);	
			$content = str_replace('<option disabled class="level-1" value="' . $page->ID . '"', '<option class="level-1" value="' . $page->ID . '"', $content);
			$content = str_replace('<option disabled class="level-2" value="' . $page->ID . '"', '<option class="level-2" value="' . $page->ID . '"', $content);
			$content = str_replace('<option disabled class="level-3" value="' . $page->ID . '"', '<option class="level-3" value="' . $page->ID . '"', $content);
			$content = str_replace('<option disabled class="level-4" value="' . $page->ID . '"', '<option class="level-4" value="' . $page->ID . '"', $content);


	return $content;


if( strstr($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php?post_type=page') || strstr($_SERVER['REQUEST_URI'], 'wp-admin/post.php' ) ) {


Update: Fixed a silly bug where the plugin only ran on new posts, not on the edit screen.

Update 2: Fixed a bug with WordPress 3.5 where Page Templates and Publish options were disabled. The code above and downloads are all updated.

Update 3: Fixed a bug where pages could be created without a parent. Now a parent is forced. Will try to make this an on/off option on a settings page in the future.