-
Notifications
You must be signed in to change notification settings - Fork 28
Add Command Palette support #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5215215
d6006fe
4ec2af9
18e250f
77bdff1
b8894cf
6fce2a9
f28d69d
6e4431c
65485ac
b06b8a7
f5a6cba
4c6f5da
c592beb
3907d63
60b8184
af46e4a
b2d95ab
101de27
4b6a953
1a62407
47c480c
9bed553
dfa0104
54176c5
a23722c
887f2cf
9944ea2
4def381
1df01fe
ccb0edc
b5f9199
71342ac
57ea58c
7f57f51
3f99a4e
ff6bb99
3b547c3
2af1415
857b84f
85cd929
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/** | ||
* Admin Commands | ||
* | ||
* Core WordPress commands for Secure Custom Fields administration. | ||
* This file registers navigation commands for all primary SCF admin screens, | ||
* enabling quick access through the WordPress commands interface (Cmd+K / Ctrl+K). | ||
* | ||
* @since SCF 6.5.0 | ||
*/ | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { createElement } from '@wordpress/element'; | ||
import { Icon } from '@wordpress/components'; | ||
import { dispatch } from '@wordpress/data'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Register admin commands for SCF | ||
*/ | ||
const registerAdminCommands = () => { | ||
if ( ! dispatch( 'core/commands' ) || ! window.acf?.data ) { | ||
return; | ||
} | ||
|
||
const commandStore = dispatch( 'core/commands' ); | ||
const adminUrl = window.acf?.data?.admin_url || ''; | ||
|
||
const commands = [ | ||
{ | ||
name: 'field-groups', | ||
label: __( 'Field Groups', 'secure-custom-fields' ), | ||
url: 'edit.php', | ||
urlArgs: { post_type: 'acf-field-group' }, | ||
icon: 'layout', | ||
description: __( | ||
'SCF: View and manage custom field groups', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ | ||
'acf', | ||
'custom fields', | ||
'field editor', | ||
'manage fields', | ||
], | ||
}, | ||
{ | ||
name: 'new-field-group', | ||
label: __( 'Create New Field Group', 'secure-custom-fields' ), | ||
url: 'post-new.php', | ||
urlArgs: { post_type: 'acf-field-group' }, | ||
icon: 'plus', | ||
description: __( | ||
'SCF: Create a new field group to organize custom fields', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ | ||
'add', | ||
'new', | ||
'create', | ||
'field group', | ||
'custom fields', | ||
], | ||
}, | ||
{ | ||
name: 'post-types', | ||
label: __( 'Post Types', 'secure-custom-fields' ), | ||
url: 'edit.php', | ||
urlArgs: { post_type: 'acf-post-type' }, | ||
icon: 'admin-post', | ||
description: __( | ||
'SCF: Manage custom post types', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'cpt', 'content types', 'manage post types' ], | ||
}, | ||
{ | ||
name: 'new-post-type', | ||
label: __( 'Create New Post Type', 'secure-custom-fields' ), | ||
url: 'post-new.php', | ||
urlArgs: { post_type: 'acf-post-type' }, | ||
icon: 'plus', | ||
description: __( | ||
'SCF: Create a new custom post type', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'add', 'new', 'create', 'cpt', 'content type' ], | ||
}, | ||
{ | ||
name: 'taxonomies', | ||
label: __( 'Taxonomies', 'secure-custom-fields' ), | ||
url: 'edit.php', | ||
urlArgs: { post_type: 'acf-taxonomy' }, | ||
icon: 'category', | ||
description: __( | ||
'SCF: Manage custom taxonomies for organizing content', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'categories', 'tags', 'terms', 'custom taxonomies' ], | ||
}, | ||
{ | ||
name: 'new-taxonomy', | ||
label: __( 'Create New Taxonomy', 'secure-custom-fields' ), | ||
url: 'post-new.php', | ||
urlArgs: { post_type: 'acf-taxonomy' }, | ||
icon: 'plus', | ||
description: __( | ||
'SCF: Create a new custom taxonomy', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ | ||
'add', | ||
'new', | ||
'create', | ||
'taxonomy', | ||
'categories', | ||
'tags', | ||
], | ||
}, | ||
{ | ||
name: 'options-pages', | ||
label: __( 'Options Pages', 'secure-custom-fields' ), | ||
url: 'edit.php', | ||
urlArgs: { post_type: 'acf-ui-options-page' }, | ||
icon: 'admin-settings', | ||
description: __( | ||
'SCF: Manage custom options pages for global settings', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'settings', 'global options', 'site options' ], | ||
}, | ||
{ | ||
name: 'new-options-page', | ||
label: __( 'Create New Options Page', 'secure-custom-fields' ), | ||
url: 'post-new.php', | ||
urlArgs: { post_type: 'acf-ui-options-page' }, | ||
icon: 'plus', | ||
description: __( | ||
'SCF: Create a new custom options page', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'add', 'new', 'create', 'options', 'settings page' ], | ||
}, | ||
{ | ||
name: 'tools', | ||
label: __( 'SCF Tools', 'secure-custom-fields' ), | ||
url: 'admin.php', | ||
urlArgs: { page: 'acf-tools' }, | ||
icon: 'admin-tools', | ||
description: __( | ||
'SCF: Access SCF utility tools', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'utilities', 'import export', 'json' ], | ||
}, | ||
{ | ||
name: 'import', | ||
label: __( 'Import SCF Data', 'secure-custom-fields' ), | ||
url: 'admin.php', | ||
urlArgs: { page: 'acf-tools', tool: 'import' }, | ||
icon: 'upload', | ||
description: __( | ||
'SCF: Import field groups, post types, taxonomies, and options pages', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'upload', 'json', 'migration', 'transfer' ], | ||
}, | ||
{ | ||
name: 'export', | ||
label: __( 'Export SCF Data', 'secure-custom-fields' ), | ||
url: 'admin.php', | ||
urlArgs: { page: 'acf-tools', tool: 'export' }, | ||
icon: 'download', | ||
description: __( | ||
'SCF: Export field groups, post types, taxonomies, and options pages', | ||
'secure-custom-fields' | ||
), | ||
keywords: [ 'download', 'json', 'backup', 'migration' ], | ||
}, | ||
]; | ||
|
||
commands.forEach( ( command ) => { | ||
commandStore.registerCommand( { | ||
name: 'scf/' + command.name, | ||
label: command.label, | ||
icon: createElement( Icon, { icon: command.icon } ), | ||
context: 'admin', | ||
description: command.description, | ||
keywords: command.keywords, | ||
callback: ( { close } ) => { | ||
document.location = command.urlArgs | ||
? addQueryArgs( adminUrl + command.url, command.urlArgs ) | ||
: adminUrl + command.url; | ||
close(); | ||
}, | ||
} ); | ||
} ); | ||
}; | ||
|
||
if ( 'requestIdleCallback' in window ) { | ||
window.requestIdleCallback( registerAdminCommands, { timeout: 500 } ); | ||
} else { | ||
setTimeout( registerAdminCommands, 500 ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* Custom Post Type Commands | ||
* | ||
* Dynamic commands for user-created custom post types in Secure Custom Fields. | ||
* This file generates navigation commands for each registered post type that | ||
* the current user has access to, creating both "View All" and "Add New" commands. | ||
* | ||
* Post type data is provided via acf.data.customPostTypes, which is populated | ||
* by the PHP side after capability checks ensure the user has appropriate access. | ||
* | ||
* @since SCF 6.5.0 | ||
*/ | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { createElement } from '@wordpress/element'; | ||
import { Icon } from '@wordpress/components'; | ||
import { dispatch } from '@wordpress/data'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Register custom post type commands | ||
*/ | ||
const registerPostTypeCommands = () => { | ||
// Only proceed when WordPress commands API and there are custom post types accessible | ||
if ( | ||
! dispatch( 'core/commands' ) || | ||
! window.acf?.data?.customPostTypes?.length | ||
) { | ||
return; | ||
} | ||
|
||
const commandStore = dispatch( 'core/commands' ); | ||
const adminUrl = window.acf.data.admin_url || ''; | ||
const postTypes = window.acf.data.customPostTypes; | ||
|
||
postTypes.forEach( ( postType ) => { | ||
// Skip invalid post types or those missing required labels | ||
if ( ! postType?.name || ! postType?.all_items || ! postType?.add_new_item ) { | ||
return; | ||
} | ||
|
||
// Register "View All" command for this post type | ||
commandStore.registerCommand( { | ||
name: `scf/cpt-${ postType.name }`, | ||
label: postType.all_items, | ||
icon: createElement( Icon, { icon: 'admin-page' } ), | ||
context: 'admin', | ||
description: postType.all_items, | ||
keywords: [ | ||
'post type', | ||
'content', | ||
'cpt', | ||
postType.name, | ||
postType.label, | ||
].filter( Boolean ), | ||
callback: ( { close } ) => { | ||
document.location = addQueryArgs(adminUrl + 'edit.php', { | ||
post_type: postType.name | ||
}); | ||
close(); | ||
}, | ||
} ); | ||
|
||
// Register "Add New" command for this post type | ||
commandStore.registerCommand( { | ||
name: `scf/new-${ postType.name }`, | ||
label: postType.add_new_item, | ||
icon: createElement( Icon, { icon: 'plus' } ), | ||
context: 'admin', | ||
description: postType.add_new_item, | ||
keywords: [ | ||
'add', | ||
'new', | ||
'create', | ||
'content', | ||
postType.name, | ||
...( postType.label ? [ postType.label ] : [] ), | ||
priethor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
], | ||
callback: ( { close } ) => { | ||
document.location = addQueryArgs(adminUrl + 'post-new.php', { | ||
post_type: postType.name | ||
}); | ||
close(); | ||
}, | ||
} ); | ||
} ); | ||
}; | ||
|
||
if ( 'requestIdleCallback' in window ) { | ||
window.requestIdleCallback( registerPostTypeCommands, { timeout: 500 } ); | ||
} else { | ||
setTimeout( registerPostTypeCommands, 500 ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
/** | ||
* SCF Commands Integration | ||
* | ||
* @package Secure Custom Fields | ||
*/ | ||
|
||
if ( ! defined( 'ABSPATH' ) ) { | ||
exit; // Exit if accessed directly. | ||
} | ||
|
||
/** | ||
* Initializes SCF commands integration | ||
* | ||
* This function handles the integration with WordPress Commands (Cmd+K / Ctrl+K), | ||
* providing navigation commands for SCF admin pages and custom post types. | ||
* | ||
* The implementation follows these principles: | ||
* 1. Only loads in screens where WordPress commands are available. | ||
* 2. Performs capability checks to ensure users only see commands they can access. | ||
* 3. Core administrative commands are only shown to users with SCF admin capabilities. | ||
* 4. Custom post type commands are conditionally shown based on edit_posts capability | ||
* for each specific post type. | ||
* 5. Post types must have UI enabled (show_ui setting) to appear in commands. | ||
* | ||
* @since SCF 6.5.0 | ||
*/ | ||
function acf_commands_init() { | ||
// Ensure we only load our commands where the WordPress commands API is available. | ||
if ( ! wp_script_is( 'wp-commands', 'registered' ) ) { | ||
priethor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return; | ||
} | ||
|
||
$custom_post_types = array(); | ||
|
||
$scf_post_types = acf_get_acf_post_types(); | ||
|
||
foreach ( $scf_post_types as $post_type ) { | ||
// Skip if post type name is not set (defensive) or post type is inactive. | ||
if ( empty( $post_type['post_type'] ) || ( isset( $post_type['active'] ) && ! $post_type['active'] ) ) { | ||
continue; | ||
} | ||
|
||
$post_type_obj = get_post_type_object( $post_type['post_type'] ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I ask not knowing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In theory it could in very edge cases, but we already checked |
||
|
||
// Three conditions must be met to include this post type in the commands: | ||
// 1. Post type object must exist | ||
// 2. Current user must have permission to edit posts of this type. | ||
// 3. Post type must have admin UI enabled (show_ui setting). | ||
if ( $post_type_obj && | ||
current_user_can( $post_type_obj->cap->edit_posts ) && | ||
$post_type_obj->show_ui ) { | ||
|
||
$labels = get_post_type_labels( $post_type_obj ); | ||
|
||
$custom_post_types[] = array( | ||
'name' => $post_type['post_type'], | ||
'all_items' => $labels->all_items, | ||
'add_new_item' => $labels->add_new_item, | ||
'icon' => $post_type['menu_icon'] ?? '', | ||
); | ||
} | ||
} | ||
|
||
if ( ! empty( $custom_post_types ) ) { | ||
acf_localize_data( | ||
priethor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
array( | ||
'customPostTypes' => $custom_post_types, | ||
) | ||
); | ||
wp_enqueue_script( 'scf-commands-custom-post-types' ); | ||
} | ||
|
||
// Only load admin commands if user has SCF admin capabilities. | ||
if ( current_user_can( acf_get_setting( 'capability' ) ) ) { | ||
wp_enqueue_script( 'scf-commands-admin' ); | ||
} | ||
} | ||
|
||
add_action( 'admin_enqueue_scripts', 'acf_commands_init' ); |
Uh oh!
There was an error while loading. Please reload this page.