TinyMCE: añadir CSS al desplegable de formato
He añadido correctamente una hoja de estilos a TinyMCE usando add_editor_style() para poder previsualizar los estilos en el cuerpo del editor TinyMCE.
Sin embargo, ¿estoy en lo correcto al asumir que la función add_editor_style() solo puede acceder a los estilos del cuerpo del editor?
Si es así, ¿existe otro método o función que pueda usar para acceder también al estilo del menú desplegable de Formato de TinyMCE?
No puedes mejorar la lista desplegable formatselect
. Pero puedes mejorar con el hook tiny_mce_before_init
el segundo menú desplegable styleselect
, que está oculto en una instalación predeterminada de WordPress.
La documentación enumera todos los valores predeterminados y posibilidades.
- inline – Nombre del elemento en línea a producir, por ejemplo "span". La selección de texto actual se envolverá en este elemento en línea.
- block – Nombre del elemento de bloque a producir, por ejemplo "h1". Los elementos de bloque existentes dentro de la selección se reemplazarán con el nuevo elemento de bloque.
- selector – Patrón de selector CSS 3 para encontrar elementos dentro de la selección. Esto se puede usar para aplicar clases a elementos específicos o cosas complejas como filas impares en una tabla.
- classes – Lista separada por espacios de clases para aplicar a los elementos seleccionados o al nuevo elemento en línea/bloque.
- styles – Objeto nombre/valor con elementos de estilo CSS para aplicar como color, etc.
- attributes – Objeto nombre/valor con atributos para aplicar a los elementos seleccionados o al nuevo elemento en línea/bloque.
- exact – Desactiva la función de combinar estilos similares cuando se usa. Esto es necesario para algunos problemas de herencia CSS como text-decoration para subrayado/tachado.
- wrapper – Indica que el formato actual es un formato contenedor para elementos de bloque. Por ejemplo, un wrapper div o blockquote.
El Botón de Estilos
Nota que, por defecto, el menú desplegable de Estilos está oculto en WordPress. Primero añade el botón para formatos personalizados a una barra de menú de TinyMCE, por ejemplo la línea 2 con el hook mce_buttons_2
.
add_filter( 'mce_buttons_2', 'fb_mce_editor_buttons' );
function fb_mce_editor_buttons( $buttons ) {
array_unshift( $buttons, 'styleselect' );
return $buttons;
}
Los Estilos Personalizados
Luego mejora el menú desplegable de este botón. También es útil la mejora mediante valores adicionales en el array, consulta el codex para este ejemplo.
/**
* Añade estilos/clases al menú desplegable "Estilos"
*/
add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );
function fb_mce_before_init( $settings ) {
// Establece en true para incluir los ajustes predeterminados.
$settings['style_formats_merge'] = true;
$style_formats = array(
array(
'title' => 'Enlace de Descarga',
'selector' => 'a',
'classes' => 'download'
),
array(
'title' => 'Mi Prueba',
'selector' => 'p',
'classes' => 'mytest',
),
array(
'title' => 'Caja de Alerta',
'block' => 'div',
'classes' => 'alert_box',
'wrapper' => true
),
array(
'title' => 'Texto Rojo en Mayúsculas',
'inline' => 'span',
'styles' => array(
'color' => 'red', // o valor hexadecimal #ff0000
'fontWeight' => 'bold',
'textTransform' => 'uppercase'
)
)
);
$settings['style_formats'] = json_encode( $style_formats );
return $settings;
}
Resultado
Menú Desplegable Mejorado
También puedes mejorar el menú desplegable con un menú en árbol. Crea la variable del ejemplo anterior con más estructura en el array, como el siguiente código.
$style_formats = array(
array(
'title' => 'Encabezados',
'items' => array(
array(
'title' => 'Encabezado 1',
'format' => 'h1',
'icon' => 'bold'
),
array(
'title' => 'Encabezado 2',
'format' => 'h2',
'icon' => 'bold'
)
)
),
array(
'title' => 'Enlace de Descarga',
'selector' => 'a',
'classes' => 'download'
)
);
Para más posibilidades y parámetros, consulta los valores predeterminados del campo de menú desplegable Formato de Estilo (escrito en JavaScript).
var defaultStyleFormats = [
{title: 'Encabezados', items: [
{title: 'Encabezado 1', format: 'h1'},
{title: 'Encabezado 2', format: 'h2'},
{title: 'Encabezado 3', format: 'h3'},
{title: 'Encabezado 4', format: 'h4'},
{title: 'Encabezado 5', format: 'h5'},
{title: 'Encabezado 6', format: 'h6'}
]},
{title: 'En línea', items: [
{title: 'Negrita', icon: 'bold', format: 'bold'},
{title: 'Cursiva', icon: 'italic', format: 'italic'},
{title: 'Subrayado', icon: 'underline', format: 'underline'},
{title: 'Tachado', icon: 'strikethrough', format: 'strikethrough'},
{title: 'Superíndice', icon: 'superscript', format: 'superscript'},
{title: 'Subíndice', icon: 'subscript', format: 'subscript'},
{title: 'Código', icon: 'code', format: 'code'}
]},
{title: 'Bloques', items: [
{title: 'Párrafo', format: 'p'},
{title: 'Cita', format: 'blockquote'},
{title: 'Div', format: 'div'},
{title: 'Pre', format: 'pre'}
]},
{title: 'Alineación', items: [
{title: 'Izquierda', icon: 'alignleft', format: 'alignleft'},
{title: 'Centro', icon: 'aligncenter', format: 'aligncenter'},
{title: 'Derecha', icon: 'alignright', format: 'alignright'},
{title: 'Justificado', icon: 'alignjustify', format: 'alignjustify'}
]}
];
Añadir Hoja de Estilos Personalizada al Editor
Ahora el último punto es incluir el CSS personalizado para estos formatos, mediante el hook mce_css
.
/**
* Aplica estilos al editor visual
*/
add_filter( 'mce_css', 'fb_mcekit_editor_style');
function fb_mcekit_editor_style($url) {
if ( ! empty( $url ) )
$url .= ',';
// Obtiene la URL del directorio del plugin
// Cambia la ruta aquí si usas directorios diferentes
$url .= trailingslashit( plugin_dir_url( __FILE__ ) ) . '/my-editor-styles.css';
return $url;
}
No olvides añadir estas reglas de hoja de estilos también al CSS del front-end.
Eliminar el Botón de Formato
Como mejora puedes eliminar el botón desplegable formatselect
mediante la comprobación del valor en el array de botones. Añade el siguiente código a la función fb_mce_editor_buttons
en el hook mce_buttons_2
.
$value = array_search( 'formatselect', $buttons );
if ( FALSE !== $value ) {
foreach ( $buttons as $key => $value ) {
if ( 'formatselect' === $value )
unset( $buttons[$key] );
}
}

Creo que entiendo esto conceptualmente: básicamente eliminas el cuadro de Formato estándar de WP y luego agregas tu propio menú desplegable de Estilo para controlar el estilo. ¿Es correcto mi entendimiento?

Correcto. Actualmente no puedo encontrar un hook para cambiar el menú desplegable formatselect
. Este menú desplegable no tiene una función para construir un menú, son valores estáticos en el tinymce.js de WP.

También la pista a esta respuesta, allí lo he encontrado ahora.

Parece que la hoja de estilo solo se aplica al contenido en el editor. Y que el estilo de los elementos en el menú desplegable se hace mediante el ajuste 'styles'
del array de configuración. ¿Es esto correcto? Aunque el ejemplo de tinyMCE parece indicar lo contrario.

Nota: Los estilos predeterminados se pueden agregar al menú desplegable de formatos añadiendo $settings['style_formats_merge'] = true;
en »fb_mce_before_init()«.

@bueltge, ¿es posible adjuntar un enlace de Google Fonts al valor $url antes de que se adjunte nuestra hoja de estilos personalizada? ¿Cómo se vería eso en tu ejemplo anterior dentro de "añadir hoja de estilos personalizada al editor"?

Puedes definir fuentes personalizadas, sí. Respondí esta pregunta hace un tiempo en otra pregunta. Eso debería ayudarte.

Según esta respuesta, la clave para que los estilos aparezcan en el menú desplegable es unset($settings['preview_styles']);
add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );
function fb_mce_before_init( $settings ) {
// personalizar según sea necesario
// eliminar los estilos de vista previa
unset($settings['preview_styles']);`
return $settings;
}

Muy útil y gracias por los indicadores de defaultstyles
. Descubrí que la fusión de arrays no funcionaba hasta convertir esas opciones predeterminadas a JSON válido (no JavaScript válido). Lo siguiente permite agregar al menú desplegable de tinymce de WordPress en lugar de reemplazarlo.
Opciones predeterminadas (JSON):
$defaults = '[{ "title": "Encabezados", "items": [
{ "title": "Encabezado 1", "format": "h1" },
{ "title": "Encabezado 2", "format": "h2" },
{ "title": "Encabezado 3", "format": "h3" },
{ "title": "Encabezado 4", "format": "h4" },
{ "title": "Encabezado 5", "format": "h5" },
{ "title": "Encabezado 6", "format": "h6" }
] },
{ "title": "En línea", "items": [
{ "title": "Negrita", "icon": "bold", "format": "bold" },
{ "title": "Cursiva", "icon": "italic", "format": "italic" },
{ "title": "Subrayado", "icon": "underline", "format": "underline" },
{ "title": "Tachado", "icon": "strikethrough", "format": "strikethrough" },
{ "title": "Superíndice", "icon": "superscript", "format": "superscript" },
{ "title": "Subíndice", "icon": "subscript", "format": "subscript" },
{ "title": "Código", "icon": "code", "format": "code" }
] },
{ "title": "Bloques", "items": [
{ "title": "Párrafo", "format": "p" },
{ "title": "Cita", "format": "blockquote" },
{ "title": "Div", "format": "div" },
{ "title": "Pre", "format": "pre" }
] },
{ "title": "Alineación", "items": [
{ "title": "Izquierda", "icon": "alignleft", "format": "alignleft" },
{ "title": "Centro", "icon": "aligncenter", "format": "aligncenter" },
{ "title": "Derecha", "icon": "alignright", "format": "alignright" },
{ "title": "Justificado", "icon": "alignjustify", "format": "alignjustify" }
] }
]';
En functions.php retorna el hash de opciones más grande:
add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );
function fb_mce_before_init( $settings ) {
$style_formats = array(
//....
$settings['style_formats'] = json_encode( array_merge( json_decode($defaults), $style_formats ) );
return $settings;
}
