¿permitir que los editores modifiquen los menús?
Me gustaría poder otorgar a mis editores la capacidad de cambiar el menú, ¿es esto posible?
La pestaña de apariencia no parece ser una opción disponible, ¿puedo hacer que lo sea?

Agrega esto al archivo functions.php
de tu tema:
// otorga al editor el privilegio de editar el tema
// obtiene el objeto del rol
$role_object = get_role( 'editor' );
// añade la capacidad $cap a este objeto de rol
$role_object->add_cap( 'edit_theme_options' );
Actualización (sugerido en los comentarios):
Probablemente no deberías hacer esto en cada solicitud, ya que según mi conocimiento esto causa una escritura en la base de datos. Es mejor hacerlo en el hook
admin_init
y solo si!$role_object->has_cap('edit_theme_options')

@Mild Fuzz - no en sí misma, pero devuelve una instancia de WP_Role

Probablemente no deberías hacer esto en cada solicitud, ya que esto causa una escritura en la base de datos según lo que entendí. Mejor hacerlo en admin_init
y solo if !$role_object->has_cap('edit_theme_options')

Esta configuración se guarda en la base de datos (en la tabla wp_options, campo wp_user_roles), por lo que podría ser mejor ejecutarla durante la activación del tema/plugin. Consulta https://codex.wordpress.org/Function_Reference/add_cap

EDITO: actualización para WP 4.9 y solo ocultar elementos del menú para Editor
Si deseas que tus usuarios puedan cambiar el menú de navegación, pero no las otras opciones bajo Apariencia: usa esto
// Haz esto solo una vez. Puede ir en cualquier parte dentro de tu archivo functions.php
$role_object = get_role( 'editor' );
$role_object->add_cap( 'edit_theme_options' );
Puedes comentar todo este código después de haber actualizado tu panel de administración, porque el código anterior realizará cambios persistentes en la base de datos.
Ahora tendrás todas las opciones bajo Apariencia visibles para los editores. Puedes ocultar las otras opciones así:
function hide_menu() {
if (current_user_can('editor')) {
remove_submenu_page( 'themes.php', 'themes.php' ); // oculta el submenú de selección de temas
remove_submenu_page( 'themes.php', 'widgets.php' ); // oculta el submenú de widgets
remove_submenu_page( 'themes.php', 'customize.php?return=%2Fwp-admin%2Ftools.php' ); // oculta el submenú del personalizador
remove_submenu_page( 'themes.php', 'customize.php?return=%2Fwp-admin%2Ftools.php&autofocus%5Bcontrol%5D=background_image' ); // oculta el submenú de fondo
// estos son específicos del tema. Pueden tener otros nombres o simplemente no existir en tu tema actual.
remove_submenu_page( 'themes.php', 'yiw_panel' );
remove_submenu_page( 'themes.php', 'custom-header' );
remove_submenu_page( 'themes.php', 'custom-background' );
}
}
add_action('admin_head', 'hide_menu');
Las últimas 3 líneas en la función hide_menu()
son específicas para mi tema. Puedes encontrar el segundo parámetro haciendo clic en el submenú que deseas ocultar, en el panel de administración. Tu URL será algo como: ejemplo.com/wp-admin/themes.php?page=yiw_panel
Así que, en este ejemplo, el segundo parámetro para la función remove_submenu_page()
será yiw_panel

Cuando observo la estructura del menú de administración, parece que el enlace nav-menus.php
está vinculado a la capacidad edit_theme_options
. ¿Puedes modificar el rol de editor para incluir esta capacidad? Esto también les daría la opción de editar widgets, no sé si esto sería un problema. Toda la funcionalidad Ajax de menús está restringida por esta capacidad, así que simplemente cambiar la capacidad del menú de administración para editar menús probablemente no funcione.

Es 2020, WordPress ya ha superado la versión 5.3, así que pensé en contribuir con una versión actualizada en la que la configuración se guarda solo una vez en la base de datos: al activar el tema, y se elimina cuando el tema se desactiva.
function add_theme_caps(){
global $pagenow;
// obtiene el rol de editor
$role = get_role('editor');
if ('themes.php' == $pagenow && isset($_GET['activated'])) {
// Comprueba si el tema está activado
// El tema está activado
// Esto solo funciona porque accede a la instancia de la clase.
// permitiría al editor editar las opciones del tema
$role->add_cap('edit_theme_options');
} else {
// El tema está desactivado
// Elimina la capacidad cuando el tema se desactiva
$role->remove_cap('edit_theme_options');
}
}
add_action( 'load-themes.php', 'add_theme_caps' );
También prefiero programar en un estilo OOP, así que aquí está una versión OOP:
/**
* Clase YourClient
*
* @author John Doe
* @package YourClient
* @since 1.0
*/
if (!defined('ABSPATH')) {
exit;
}
if (!class_exists('YourClient')) {
/**
* La clase principal YourClient
*/
class YourClient
{
/**
* Configura la clase
*/
public function __construct()
{
// Otorga más privilegios al activar el tema
add_action('load-themes.php', array($this, 'add_theme_caps'));
}
function add_theme_caps()
{
global $pagenow;
// obtiene el rol de editor
$role = get_role('editor');
if ('themes.php' == $pagenow && isset($_GET['activated'])) { // Comprueba si el tema está activado
// El tema está activado
// Esto solo funciona porque accede a la instancia de la clase.
// permitiría al editor editar las opciones del tema solo para el tema actual
$role->add_cap('edit_theme_options');
} else {
// El tema está desactivado
// Elimina la capacidad cuando el tema se desactiva
$role->remove_cap('edit_theme_options');
}
}
}
}

He descubierto que el menú funcionará de esta manera: instala el plugin "User Role Editor" y allí podrás editar las condiciones para el rol de editor y otros también. Activa la opción edit_theme_options. Pero ahora: verás la opción "menú" dentro de "temas", "widgets".
En mi caso: Después de hacer clic en "menú" (como editor) no veía las opciones rellenadas sino vacías. Así que desactivé el plugin "User Role Editor" y las opciones del "menú" aparecieron correctamente. Ten en cuenta que al desactivar el plugin "User Role Editor" ¡las condiciones para el editor permanecen activas! Me funcionó, quizás también te ayude a ti.
