WordPress の管理画面は、以前よく使ってた Movable Type や他の CMS に比べても、とても分かりやすく出来ていると思いますが、さらに使いやすくするために、案件に応じて不要なメニュー項目を削除したり、逆に投稿一覧画面などにはあったら便利という項目を表示させたりしています。

今回、編集者にカスタムメニューの操作権限を与える必要がありました。

まず、通常編集者はカスタムメニューを操作することはできないので、functions.php に以下を記述して操作権限を与えます。

function add_theme_caps(){
  $role = get_role( 'editor' );
  $role->add_cap( 'edit_theme_options' );
}
add_action( 'admin_init', 'add_theme_caps' );

これで編集者にも[外観]メニューが表示されますが、[テーマ]や[カスタマイズ]などのサブメニューは操作してほしくないのでこれらを消す必要がありましたが、この内[カスタマイズ]については他のサブメニューと URL の形式が異なるため、ちょっと工夫が必要でした。

メニューから不要な項目を削除する方法は、以下のような感じでいろいろなブログ記事等で紹介されています。

function remove_menus() {
  remove_menu_page('edit.php'); // 投稿
  remove_menu_page('edit.php?post_type=page'); // 固定ページ
  remove_submenu_page('edit.php', 'edit-tags.php?taxonomy=category'); // 投稿->カテゴリ
  remove_submenu_page('edit.php', 'edit-tags.php?taxonomy=post_tag'); // 投稿->タグ
}
add_action('admin_menu', 'remove_menus');

この 'edit.php' や 'edit.php?post_type=page''edit-tags.php?taxonomy=category' は各メニュー項目の href 属性の値であることが分かります。サブメニューの場合は、親メニューの href 属性の値と合わせてカンマ区切りで記述します。

同じようにして、[外観]メニューから[テーマ]や[カスタマイズ]のサブメニューを削除しようとしたのですが、[カスタマイズ]メニューについてはどうも href 属性の値が一定ではありません。

よく確かめてみると、
ダッシュボードを表示している時は
'customize.php?return=%2Fwp%2Fwp-admin%2Findex.php'
投稿一覧を表示している時は
'customize.php?return=%2Fwp%2Fwp-admin%2Fedit.php'
というように、return パラメータの値が、現在表示しているページのパスを URL エンコードしたものとなっています。

そこで、php の $_SERVER["REQUEST_URI"] で現在のURI(ドメイン以下のパス)を取得し、これを URL エンコードしたものを 'customize.php?return=' に繋げることでうまく行きました。

function remove_menus() {
  if (!current_user_can('administrator')) {
    remove_submenu_page('themes.php', 'themes.php'); // 外観->テーマ
    remove_submenu_page('themes.php', 'customize.php?return='. urlencode($_SERVER["REQUEST_URI"])); // 外観->カスタマイズ
  }
}
add_action('admin_menu', 'remove_menus');

管理者には表示させておきたいので、現在のユーザーの権限で条件分岐しています。