2026年5月20日
2026年5月20日
ユーザーロールと権限をカスタマイズする方法|add_role・add_cap・カスタム投稿タイプの権限
WordPress では、ユーザーにできること(投稿の公開、プラグインの有効化など)を「権限(capability)」で管理し、権限をまとめたものを「ロール(権限グループ)」としてユーザーに割り当てます。既定のロールで足りないときは、独自のロールを作ったり、既存のロールに権限を足し引きしたりできます。
この記事の関数と既定の権限は、developer.wordpress.org の「Roles and Capabilities」と WordPress 6.9 のソースコード、WP-CLI のコマンドは WP-CLI 本体のヘルプで2026年10月時点の内容を確認しています。
既定のロールと主な権限
単一サイトの WordPress には次の5つのロールがあります(マルチサイトでは、これに全サイトを管理する「特権管理者」が加わります)。
| ロール(スラッグ) | できること | 代表的な権限 |
|---|---|---|
管理者(administrator) |
サイトのすべての管理 | manage_options、activate_plugins、edit_theme_options、create_users |
編集者(editor) |
他人の投稿・固定ページも含めた編集と公開、コメントやカテゴリーの管理 | edit_others_posts、edit_pages、manage_categories、moderate_comments |
投稿者(author) |
自分の投稿の作成・公開、画像のアップロード | publish_posts、edit_published_posts、upload_files |
寄稿者(contributor) |
自分の投稿の作成(公開はできず、レビュー待ちで提出) | edit_posts、delete_posts |
購読者(subscriber) |
ログインとプロフィールの編集 | read |
ロールと権限の一覧はデータベースの wp_options テーブルに、オプション名 wp_user_roles(wp_ はテーブル接頭辞)として保存されています。現在の状態は WP-CLI で確認できます。
# ロールの一覧
wp role list
# 編集者ロールが持つ権限の一覧
wp cap list editor
WP-CLI の基本は WP-CLIの基本コマンド を参照してください。
大事な前提: ロールの変更はデータベースに保存される
add_role()・remove_role()・add_cap()・remove_cap() は、実行するとその結果がデータベースに書き込まれます。コードを消しても変更は残り、毎回のリクエストで実行する必要はありません。
initなどで毎回実行すると、そのたびにデータベースへの書き込みが起き、管理画面やプラグインで変えた権限がコードの内容で上書きされます。- テーマやプラグインのコードでは、「一度だけ実行する」仕組み(バージョン番号をオプションに保存して比較する、プラグインの有効化時に実行する)を用意します。
手順1: 独自のロールを作る
例として、投稿の編集・公開とカテゴリー・コメントの管理はできるが、固定ページ・テーマ・プラグイン・設定には触れない「コンテンツ管理者」ロールを作ります。
<?php
// functions.php またはサイト用の独自プラグイン
function mytheme_setup_roles() {
$version = '1';
if ( get_option( 'mytheme_roles_version' ) === $version ) {
return; // 実行済みなら何もしない
}
remove_role( 'content_manager' ); // 作り直すときのために一度消す(無ければ何もしない)
add_role(
'content_manager', // ロールのスラッグ
'コンテンツ管理者', // 画面に表示される名前
array(
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'publish_posts' => true,
'delete_posts' => true,
'delete_others_posts' => true,
'delete_published_posts' => true,
'upload_files' => true,
'manage_categories' => true,
'moderate_comments' => true,
)
);
update_option( 'mytheme_roles_version', $version );
}
add_action( 'admin_init', 'mytheme_setup_roles' );
add_role()は、同じスラッグのロールが既にあると何もしません。権限の内容を変えたいときは、$versionを'2'に上げると、remove_role()で消してから作り直されます。- 権限の配列に書かなかった権限は「持っていない」扱いです。
'manage_options' => falseのように書く必要はありません。 - ロールを作り直しても、そのロールが割り当てられたユーザーの設定は保たれます(ユーザーにはロールのスラッグが保存されているため)。
コードを書かずに作る場合は WP-CLI で既存ロールを複製できます。
# 投稿者ロールの権限をコピーして新しいロールを作る
wp role create content_manager 'コンテンツ管理者' --clone=author
# 権限を追加する
wp cap add content_manager edit_others_posts delete_others_posts manage_categories moderate_comments
作ったロールは、「ユーザー」→ 各ユーザーの編集画面の「権限グループ」で選べます。WP-CLI なら wp user set-role <ユーザー名> content_manager です。
手順2: 既存のロールに権限を足す・外す
既存ロールの権限は get_role() でロールを取り出し、add_cap()・remove_cap() で変えます。例として、編集者に「外観」→「メニュー」と「ウィジェット」を触らせるため、edit_theme_options を与えます。
<?php
function mytheme_update_editor_caps() {
if ( get_option( 'mytheme_editor_caps_version' ) === '1' ) {
return;
}
$editor = get_role( 'editor' );
if ( $editor ) {
$editor->add_cap( 'edit_theme_options' ); // 外観のメニュー・ウィジェットなど
$editor->remove_cap( 'moderate_comments' ); // コメントの承認はさせない
}
update_option( 'mytheme_editor_caps_version', '1' );
}
add_action( 'admin_init', 'mytheme_update_editor_caps' );
edit_theme_optionsを与えると、メニュー・ウィジェットに加えてカスタマイザーや、ブロックテーマではサイトエディターも使えるようになります。与える権限が何を開放するかを確かめてから追加してください。- プラグインのインストール(
install_plugins)やユーザー作成(create_users)を管理者以外に与えると、その人がサイト全体を操作できるのと変わらなくなります。
既定のロールを WordPress の初期状態に戻すには、WP-CLI の wp role reset を使います。
# 編集者ロールを既定の権限に戻す
wp role reset editor
手順3: カスタム投稿タイプに専用の権限を付ける
既定では、カスタム投稿タイプは通常の投稿と同じ権限(edit_posts など)で編集できます。「ニュースだけ編集できる人」を作るには、投稿タイプの登録時に capability_type と map_meta_cap を指定して専用の権限名にします。
<?php
function mytheme_register_news() {
register_post_type( 'news', array(
'label' => 'ニュース',
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'supports' => array( 'title', 'editor', 'thumbnail' ),
'capability_type' => array( 'news_item', 'news_items' ), // 単数形・複数形
'map_meta_cap' => true,
) );
}
add_action( 'init', 'mytheme_register_news' );
capability_type を単数形と複数形の配列で渡すと、次の権限名が使われます(文字列で 'news' とだけ書くと、複数形は末尾に s を付けた edit_newss のような名前になります)。
| 意味 | 権限名 |
|---|---|
| 自分のニュースを編集・新規作成 | edit_news_items |
| 他人のニュースを編集 | edit_others_news_items |
| 公開済みのニュースを編集 | edit_published_news_items |
| 非公開のニュースを編集・閲覧 | edit_private_news_items、read_private_news_items |
| ニュースを公開 | publish_news_items |
| ニュースを削除 | delete_news_items、delete_others_news_items、delete_published_news_items、delete_private_news_items |
edit_news_item・read_news_item・delete_news_item(単数形)は「この1件を編集できるか」を判定するメタ権限で、map_meta_cap が上の権限に置き換えて判定します。ロールに与えるのは上の表の権限だけです。
登録しただけでは、管理者を含めて誰もこの権限を持っていないため、管理画面に「ニュース」が表示されなくなります。管理者とコンテンツ管理者に権限を与えます。
<?php
function mytheme_grant_news_caps() {
if ( get_option( 'mytheme_news_caps_version' ) === '1' ) {
return;
}
$caps = array(
'edit_news_items',
'edit_others_news_items',
'edit_published_news_items',
'edit_private_news_items',
'read_private_news_items',
'publish_news_items',
'delete_news_items',
'delete_others_news_items',
'delete_published_news_items',
'delete_private_news_items',
);
foreach ( array( 'administrator', 'content_manager' ) as $role_name ) {
$role = get_role( $role_name );
if ( ! $role ) {
continue;
}
foreach ( $caps as $cap ) {
$role->add_cap( $cap );
}
}
update_option( 'mytheme_news_caps_version', '1' );
}
add_action( 'admin_init', 'mytheme_grant_news_caps' );
自分のニュースだけを書かせて公開はさせない人には、edit_news_items と delete_news_items だけを与えます(通常の投稿の寄稿者と同じ考え方です)。
手順4: コードの中で権限を確かめる
自作の処理で「この人に実行させてよいか」を判定するときは、ロール名ではなく権限名で current_user_can() を呼びます。
<?php
// 正しい: 権限で判定する
if ( current_user_can( 'publish_news_items' ) ) {
// ニュースを公開できる人だけの処理
}
// 特定の投稿を編集できるか(メタ権限は投稿IDと一緒に使う)
$post_id = 123;
if ( current_user_can( 'edit_post', $post_id ) ) {
// この投稿を編集できる人だけの処理
}
// ロールそのものを確かめる必要があるときは、ユーザーのロール一覧を見る
$user = wp_get_current_user();
if ( in_array( 'content_manager', (array) $user->roles, true ) ) {
// コンテンツ管理者の処理
}
current_user_can( 'content_manager' ) のようにロール名を渡す書き方は一部動きますが、WordPress のリファレンスで「信頼できない結果になることがあるので推奨しない」とされています。
手順5: 管理画面のメニューを整理する
権限を持たないメニューは WordPress が自動で隠します。それでも表示を減らしたいときは remove_menu_page() を使えます。
<?php
function mytheme_simplify_menu_for_content_manager() {
$user = wp_get_current_user();
if ( in_array( 'content_manager', (array) $user->roles, true ) ) {
remove_menu_page( 'tools.php' ); // 「ツール」を隠す
}
}
add_action( 'admin_menu', 'mytheme_simplify_menu_for_content_manager', 999 );
remove_menu_page() はメニューを隠すだけで、URL を直接開けば画面に入れます。操作を禁止したいときは、メニューを隠すのではなく、その操作の権限をロールから外してください。
ロールを削除する・元に戻す
独自ロールを削除すると、そのロールだったユーザーはロールなしの状態になり、管理画面に入れなくなります。先に別のロールへ移してから削除します。
# content_manager のユーザーを確認して、投稿者に移す
wp user list --role=content_manager --fields=ID,user_login
wp user set-role 12 author
# ロールを削除する
wp role delete content_manager
テーマの切り替え時にコードで片付ける場合は switch_theme フックで remove_role() を呼び、手順1〜3で使ったバージョン用のオプションも削除します。
<?php
function mytheme_cleanup_roles() {
remove_role( 'content_manager' );
delete_option( 'mytheme_roles_version' );
delete_option( 'mytheme_news_caps_version' );
}
add_action( 'switch_theme', 'mytheme_cleanup_roles' );
注意点
- 権限を変えたら、そのロールのテスト用ユーザーでログインし、必要な画面が開けること、開けてはいけない画面が開けないことを確認します。
- 1人のユーザーに複数のロールを持たせることもできますが(
$user->add_role())、標準のユーザー編集画面では1つしか表示・選択できません。 - ロール管理のプラグインを使っている場合、コードとプラグインの両方で同じロールを変えると、どちらの設定が残るかわかりにくくなります。どちらか一方に寄せてください。
まとめ
- ロールと権限はデータベースに保存されるので、
add_role()・add_cap()は一度だけ実行する - 独自ロールは
add_role()かwp role create --clone=で作り、権限はadd_cap()・remove_cap()かwp cap add・wp cap removeで調整する - カスタム投稿タイプは
capability_type(単数形・複数形)とmap_meta_capで専用の権限にし、管理者にも権限を与える - 判定は
current_user_can()に権限名を渡す。メニューを隠しても操作の制限にはならない