Wie füge ich TinyMCE benutzerdefiniertes CSS (Theme-Option) hinzu?

14

Ich versuche, dem visuellen TinyMCE-Editor in WordPress benutzerdefiniertes CSS (über Designoptionen festgelegt) hinzuzufügen. Am Frontend generiert das Theme dieses CSS und gibt es am wp_headHook aus. Das Problem, auf das ich stoße, ist, dass ich diese CSS-Ausgabe zum Editor hinzufügen kann.

Dies ist nicht möglich, add_editor_style( 'editor-style.css' )da wir PHP verwenden müssen, um auf die Theme-Option zuzugreifen.

Ein Beispiel dafür, wie es am Frontend funktioniert:

add_action( 'wp_head', 'my_custom_colors' );

function my_custom_colors() {
    $color_1 = get_theme_mod( 'color_1', 'cc4a00' );

    echo "<style type='text/css'>a { color: #{$color_1}; }";
}

Ich brauche eine Methode, um diesen benutzerdefinierten Stil in den visuellen Editor zu übernehmen. Jede Hilfe wäre sehr dankbar.

Justin Tadlock
quelle
1
Hinweis: Benutzerdefiniertes Post-Content-CSS ist das Plug-in-Gebiet und sollte nicht in ein Thema eingefügt werden. Andernfalls verlieren Benutzer ihr benutzerdefiniertes CSS, wenn sie zu einem anderen Thema wechseln.
Chip Bennett
@ChipBennett Ich stimme nur teilweise zu. Dies hängt stark davon ab, was Sie stylen. Abgesehen davon ist es egal, wo es ist (für diese Frage).
Kaiser
@ChipBennett Dies hat mit Designstilen zu tun, nicht mit benutzerdefiniertem Post-Content-CSS. Das ist ziemlich normales Zeug, das Sie mit dem Theme-Customizer machen können. Es ist nur die Anwendung dieser Stile, die mich verblüfft hat. Es ist als Kompliment gedacht editor-style.css, was ein Themengebiet ist.
Justin Tadlock
Warten Sie: sprechen Sie über dynamischen benutzerdefinierten Editor-Stil ? Wie in: Machen Sie den visuellen Editor (TinyMCE) auf Stile aufmerksam, die durch Themenoptionen definiert sind? Wenn ja, ignoriere meinen ursprünglichen Kommentar und +1 für die Frage.
Chip Bennett
Könnten Sie eine Bearbeitung und ein Beispiel für einen vollständigen Satz für den Themenstil zeigen? Wäre dann einfacher zu testen.
Kaiser

Antworten:

7

Lösung 1

Dies funktioniert als Javascript-Lösung:

Beispiel:

tinyMCE.activeEditor.dom.addStyle('p {color:red; font-size:28px;}');

öffne einfach deine js-konsole und füge sie für einen schnellen test ein. Um einen bestimmten Editor anzusprechen, sollten Sie Folgendes verwenden:

tinyMCE.getInstanceById('##editorID##').dom.addStyle('p {color:red; font-size:28px;}');

Dadurch wird der bereitgestellte String in den iframe des Editors eingefügt <head><style id="mceDefaultStyles"></style> ...

Lösung 2

Verwenden Sie wp_ajax als Callback-Handler, um dem Editor-Init mithilfe eines Filters dynamische Stile hinzuzufügen

add_filter('tiny_mce_before_init', 'dynamic_editor_styles', 10);

function dynamic_editor_styles($settings){
    // you could use a custom php file as well, I'm using wp_ajax as
    // callback handler for demonstration
    // content_css is a string with several files seperated by a comma
    // e.g. file1, file2, ... extend the string

    $settings['content_css'] .= ",".admin_url('admin-ajax.php') ."/?action=dynamic_styles";

    return $settings;
}

// add wp_ajax callback
add_action('wp_ajax_dynamic_styles', 'dynamic_styles_callback');
function dynamic_styles_callback(){
    echo "p {color:red} h1{font-size:48px;}";
}
ungestaltbar
quelle
2
Ich bin mir nicht ganz sicher, was ich damit anfangen soll.
Justin Tadlock
Lösung Nr. 2 macht für mich sehr viel Sinn. Ich werde das mal testen.
Justin Tadlock
Ich habe Lösung 2 gewählt. Der Unterschied besteht darin, dass ich die erste Funktion gelöscht und verwendet habe, add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )da dies die Standardmethode für Designs ist, um Editorstile hinzuzufügen.
Justin Tadlock
Nur zu meiner eigenen Erbauung wäre ich gespannt, ob ich mce_cssfür Sie gearbeitet habe (wenn Sie es ausprobiert haben).
Chip Bennett
Ich habe es eigentlich nicht ausprobiert, weil ich wusste, dass Sie eine Nicht-CSS-Datei übergeben können add_editor_style(), aber es sollte funktionieren, wenn Sie den Code betrachten. Verwenden mce_cssist eigentlich eine bessere Lösung für den Fall, dass Sie nach über hinzugefügten Stilen einbinden müssen add_editor_style(). Ein solcher Grund für ein Thema ist, dass vollständige URLs, die über hinzugefügt wurden add_editor_style(), trotz der Reihenfolge, in der sie hinzugefügt wurden, zuerst ausgegeben werden.
Justin Tadlock
10

WordPress bietet einen mce_cssFilter , mit dem Sie dem visuellen Editor benutzerdefinierte Stylesheets hinzufügen können. Nach dem Kodex:

Die Datei kann eine .php-Datei sein, die die dynamische Generierung von CSS-Regeln für den Inhaltseditor ermöglicht.

Beispiel für einen Codex-Filter-Rückruf, der für ein Thema geändert wurde:

function wpse120831_mce_css( $mce_css ) {
    if ( ! empty( $mce_css ) )
        $mce_css .= ',';

    $mce_css .= get_template_directory_uri() . '/dynamic-css.php';

    return $mce_css;
}

add_filter( 'mce_css', 'wpse120831_mce_css' );
Chip Bennett
quelle
Mr.Bennett war schneller, fügte das nur meiner Antwort unten hinzu :), aber etwas anders.
ungestaltbar
@ungestaltbar wir verwenden eigentlich zwei völlig verschiedene Filter. :)
Chip Bennett
mit dem gleichen Ergebnis :)
ungestaltbar
4

Ich habe die obige Lösung von @ungestaltbar akzeptiert. Ich wollte diese Antwort jedoch ein wenig mit der vollständigen Lösung, die ich verwende, erweitern, damit andere sehen können, wie es funktioniert.

add_action( 'after_setup_theme', 'my_theme_setup' );

function my_theme_setup() {

    add_editor_style(
        array(
            'editor-style.css',
            add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) ),
        )
    );
}

add_action( 'wp_ajax_my_editor_styles', 'my_editor_styles_callback' );
add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );

function my_editor_styles_callback() {

    // @todo sanitize
    $color_1 = get_theme_mod( 'color_1', 'cc4a00' );

    echo "a { color: #{$color_1}; }";

    die();
}

Ich hoffe, dass es in Ordnung ist, hier eine weitere Antwort zu posten. Ich habe keine Möglichkeit gefunden, dies als direkte Antwort auf meine akzeptierte Lösung zu veröffentlichen. Ich lerne immer noch, wie man WPSE benutzt.

Justin Tadlock
quelle
Möglicherweise sollten Sie hinzufügen, add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );ob der Editor im Frontend verwendet wird (für nicht angemeldete Benutzer).
OriginalEXE
Ja, eine Antwort mit erheblichen Änderungen / Optimierungen ist vollkommen in Ordnung. :) FYI, wenn es über ein Problem war, das in der ursprünglichen Antwort behoben werden sollte, dann wäre es weit.
Rarst
@OriginalEXE - Ja. Ich werde es aktualisieren.
Justin Tadlock
Nur ein Tipp für alle anderen, die das später finden, ich konnte es nicht richtig zum Laufen bringen, wie es präsentiert wird. Schließlich stellte ich fest, dass ich Header-Informationen in den Rückruf einbeziehen musste, damit dies als CSS angesehen werden konnte. Header ("Inhaltstyp: Text / CSS; Zeichensatz: UTF-8"); Ich bin mir nicht sicher, ob dies in meinem .htaccess etwas anderes ist oder was.
SkyShab,
4

Ich bin wahrscheinlich zu spät zu dieser Party, aber nachdem ich die obige Lösung verwendet hatte, wurde mir schnell klar, dass die Seitenladegeschwindigkeit des Editors stark beeinträchtigt war! Als ich mir den Code genauer ansah, wurde mir klar, dass der Code noch lange nach der Initialisierung von tinyMCE.activeEditor ausgeführt wird. Der Code verwendet die setInterval () -Methode, die einen Ausdruck in festgelegten Intervallen auswertet. Ich glaube, das lag daran, dass Sie nicht feststellen konnten, zu welchem ​​Zeitpunkt während der Codeausführung "activeEditor" verfügbar sein wird. Dies brachte die Seitengeschwindigkeit auf die Knie.

Eine viel bessere Lösung, die ich verwende, um ein Plugin zu erstellen, ist diese

   /**
     * Extend TinyMCE config with a setup function.
     * See http://www.tinymce.com/wiki.php/API3:event.tinymce.Editor.onInit

     */
    function custom_tinymce_css($init) {

      $css = get_option('some_css'); 

     ?>

        <script type="text/javascript">            

            function addTempCSS( ed ) {
                ed.onInit.add( function() {
                    tinyMCE.activeEditor.dom.addStyle(<?php echo json_encode($css) ?>);
                } );
            };
        </script>

        <?php
        if (wp_default_editor() == 'tinymce')
            $init['setup'] = 'addTempCSS';

        return $init;
    }
    add_filter('tiny_mce_before_init', 'custom_tinymce_css');

Hier wird ein nativer TinyMCE-Listener verwendet, um den Code auszuführen, nachdem der aktive Editor initialisiert wurde. Ich hoffe das hilft jemandem da draußen. Mit freundlichen Grüßen.

Ayebare M
quelle
1
Dies funktioniert für mich, es gibt nur einen veralteten API-Aufruf in Tinymce 4.0, den Sie ändern müssen. Ed.onInit.add (function () {... zu ed.on ('init', function () {...
Mohammed
1

Dies ist eine geänderte Lösung, die in den WordPress.org-Foren für diese Frage veröffentlicht wurde: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573

Das funktioniert definitiv. Ich bin allerdings kein JS-Guru, daher bin ich mir nicht ganz sicher, ob dies die beste Lösung ist.

add_action( 'before_wp_tiny_mce', 'my_tinymce_callback' );

function my_tinymce_callback() {

    $color_1 = get_theme_mod( 'color_1', 'cc4a00' ); ?>

    <script type="text/javascript">
    jQuery( document ).ready(

        function() {
            var my_style = 'a { color: #<?php echo $color_1; ?>; }';

            var checkInterval = setInterval(
                function() {

                    if ( 'undefined' !== typeof( tinyMCE ) ) {
                        if ( tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) {

                            jQuery( '#content_ifr' ).contents().find( 'head' ).append( '<style type="text/css">' + my_style + '</style>' );

                            clearInterval( checkInterval );
                        }
                    }
                }, 
                500 
            );
        }
    );
    </script>
<?php }

Dies könnte auch zu einer JS-Datei hinzugefügt werden. Damit könnten Sie einfach Variablen übergeben wp_localize_script().

Justin Tadlock
quelle