web-dev-qa-db-fra.com

Basculer librement entre l'onglet visuel et HTML

Cette question a donc été soulevée à maintes reprises sous différents drapeaux. Toutefois, j'aimerais présenter un fil conducteur pour une solution ultime à ce problème.

Dans WordPress, par défaut, lors du basculement entre les éditeurs HTML et Visual dans TinyMCE, certaines balises sont vidées de leur contenu et d’autres fonctionnalités étranges se produisent. Deux solutions de contournement connues pour écrire du code HTML plus efficace consistent à supprimer la fonction wp_auto_p à l'aide de filtres, à installer TinyMCE Advanced et à activer l'option "Arrêter de supprimer les balises P & br".

Cela ne fonctionne que très bien, malheureusement.

Prenons, par exemple, l'exemple suivant:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the Zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre>
&lt;script type=&quot;text/javascript&quot; src=&quot;/path/to/jquery.easycolumns.js&quot;&gt;&lt;/script&gt;
</pre>

Si je tape ce code dans l'éditeur HTML, alors que les deux options répertoriées ci-dessus sont déjà activées, rien ne se produit lorsque je commute entre les deux éditeurs différents, ce qui est attendu. Malheureusement, lors de la sauvegarde, le code se convertit automatiquement en ceci:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the Zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre>
<script type="text/javascript" src="/path/to/jquery.easycolumns.js"></script>
</pre>

Comme vous pouvez le constater, toutes les entités de la balise pre sont reconverties en caractères HTML réels. Ensuite, si je sauvegarde à nouveau le même message, je reçois un résultat similaire à celui-ci:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the Zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre><br />
<script type="text/javascript" src="/path/to/jquery.easycolumns.js"></script><br />
</pre>

Notez que Wordpress va réellement injecter des balises br dans le post. Inutile de dire que lorsque ce message a été mis à jour plusieurs fois, lors de son affichage sur le front-end, l’affichage est loin de l’affichage voulu.

Le seul moyen par lequel j'ai semblé me ​​débarrasser de toute la "fonctionnalité de formatage" ajoutée a été de désactiver l'éditeur visuel via mon profil.

C'est une bonne solution pour moi, étant donné que je suis un développeur Web professionnel. Pour mes clients, cette solution est loin d’être élégante. La plupart de mes clients utiliseront l'éditeur visuel. Beaucoup de mes clients ne sont pas très férus de technologie et ont parfois besoin que je répare leurs messages lorsque la mise en page est brisée. Cela me limite à utiliser l'éditeur visuel, car je ne peux pas passer à l'éditeur HTML sans craindre de casser la mise en page.

Principalement (et je pense qu’une grande communauté pourrait bénéficier de cette réponse), quelles étapes explicites puis-je suivre pour assurer les points suivants:

  1. Un article peut être édité à partir de l'éditeur visuel ou HTML.
  2. Le contenu d'un message n'est modifié d'aucune manière lors du basculement entre les deux onglets.
  3. Lorsque vous enregistrez une publication à partir de l'éditeur HTML, aucun contenu supplémentaire n'est ajouté.
  4. Lorsque vous enregistrez une publication à partir de l'éditeur HTML, aucune entité n'est convertie.
  5. BONUS: lors de l’enregistrement d’une publication à partir de l’éditeur HTML, tout code (HTML par exemple) qui est encapsulé dans une balise pré et qui n’a pas déjà été converti en entités sera automatiquement converti en entités.

En gros, si nous pouvons créer le comportement susmentionné dans TinyMCE en utilisant un plug-in tiers, nous pourrons éliminer toutes les autres questions concernant le formatage erroné en utilisant TinyMCE. Je pense que beaucoup de gens pourraient en bénéficier.

Il semble tout simplement logique qu'il existe une certaine fonctionnalité que l'on pourrait attendre d'un éditeur WYSIWIG, et cela va à l'encontre. Selon toute logique et raison, les fonctions de formatage intégrées de Wordpress sont plutôt inutiles avec leur configuration actuelle. Il me semble que s’ils veulent utiliser ces options de formatage, leur meilleur choix est d’activer un éditeur ou l’autre, pas les deux.

ET S'IL VOUS PLAÎT: Ne répondez pas à ce fil avec des solutions de contournement et des téléchargements pour d'autres éditeurs WYSIWIG qui "résolvent" le problème. Ceci est un problème sous-jacent (bien que ce ne soit pas vraiment un bogue) avec le noyau Wordpress qui doit être corrigé.

EDIT: Très bien, je travaille sur ce sujet et je pense que l’ingénierie inverse sera le meilleur moyen de résoudre ce problème. Donc pour le moment, j'ai désactivé wpautop (qui, pour plus de clarté, est une fonction qui s’accroche au filtre "the_content" pour ajouter des balises p et br avant que le texte ne soit affiché, pas lorsque le texte est sauvegardé. Je pense qu'il existe une certaine confusion quant au fonctionnement de cette fonction. Wpautop n'est pas responsable des changements que vous voyez se produire lorsque vous passez d'un onglet de l'éditeur à un autre.

Quoi qu'il en soit, j'ai désactivé wpautop, comme il est de bonne pratique lorsque vous utilisez l'éditeur HTML. À partir de ce moment, j'ai désactivé l'éditeur visuel pour commencer par les erreurs d'entité HTML présentes lors de la sauvegarde d'un article. Grâce à l’aide de C. Bavota, j’ai trouvé un extrait de code qui convertissait les balises de l’éditeur HTML en entités équivalentes avant de les afficher au début du site (crédit: http://bavotasan.com/2012/convert-pre-tag-contenus-en-html-entités-in-wordpress/ ).

#add_filter( 'the_content', 'pre_content_filter', 0 );
/**
 * Converts pre tag contents to HTML entities 
 *
 * This function is attached to the 'the_content' filter hook.
 *
 * @author c.bavota
 */

function pre_content_filter( $content ) {
        return preg_replace_callback( '|<pre.*>(.*)</pre|isU' , 'convert_pre_entities', $content );
}


function convert_pre_entities( $matches ) {
        return str_replace( $matches[1], htmlentities($matches[1] ), $matches[0] );
}

add_filter( 'the_content', 'pre_content_filter', 10, 2 ); 

Cela élimine efficacement les problèmes liés à la conversion par Wordpress de toutes les entités en balises lors de l'enregistrement en le contournant. Maintenant, vous pouvez utiliser l'éditeur HTML et écrire du code standard entre les balises "pre" sans effectuer vous-même la conversion d'entité. Cela résout tous les problèmes de conversion d’entités dans Wordpress et s’assure que tout s’affiche correctement sur le front-end. Nous devons maintenant trouver à quoi s’attacher pour modifier le comportement rencontré lorsqu’on clique en arrière entre les onglets. À l’heure actuelle, il semblerait que lorsqu’on passe de l’onglet HTML à l’affichage visuel, le contenu de cet onglet soit interprété par javascript ou par quelque chose d’autre pour tenter de fournir une mise à jour en direct de ce à quoi le contenu devrait ressembler. Cela provoque le traitement des balises (affichées sous une forme non entité dans l'onglet HTML) au lieu de les afficher. Ensuite, lors du retour à l'onglet HTML, il semblerait que TinyMCE transmet les données actuelles. Cela signifie que lorsque vous revenez en arrière, vous perdez votre structure HTML. Nous devons trouver un moyen de dire à TinyMCE de convertir tout ce qui se trouve dans les balises pre en ses entités équivalentes avant de le charger dans la fenêtre (essentiellement la version backend de ce que nous avons fait sur le front-end mais avec tinymce et javascript au lieu de php et hooks), afin qu'il soit affiché au lieu d'être traité. Suggestions?

EDIT 2 :

Après quelques recherches supplémentaires, la conversion des entités de la balise pré lorsqu’elles sont affichées fonctionne bien pour le contenu de la balise pré, mais disons que j’ai un article de blog avec une ligne comme celle-ci:

"Ensuite, nous devons ajouter cette ligne à notre fichier HTML: <p> Bonjour, Monde! </ P>"

En regardant cette ligne, vous pouvez voir que le code est censé être affiché sur le site, et non analysé. Cependant, lorsque la publication est enregistrée, ces entités sont décodées lors du prochain chargement d'édition, et lors de chaque enregistrement suivant. en tant que balises html brutes, ce qui les amène à être analysées en amont. La seule solution à laquelle je puisse penser jusqu’à présent serait d’écrire dans un code similaire à celui de la balise "code" que j’utilise pour le pré, puis d’envelopper les petites doublures dans la balise "code" et les gros morceaux dans la "pre" tag. Quelqu'un a d'autres idées?

20

Très bien, j'ai déjà mis à jour cette question une tonne et elle commence à être surchargée, alors je me suis dit que j'écrirais cette réponse comme une réponse même si elle n'était pas complète.

Extrapolant à partir de la réponse de @ bueltge, je suis en fait retourné et j'ai trouvé son précédent message en question. Dans ce post, il y avait un plugin répertorié que je n'avais jamais vu auparavant: "Préservé Editeur HTML". Ce plugin n'a pas été mis à jour depuis un moment, mais je viens de le tester avec WP 3.6.1 et il est entièrement fonctionnel. Ce plugin s'occupe automatiquement de wpautop, fournit un format unifié pour l'insertion de balises br et p dans l'éditeur visuel et préserve votre balisage lorsque vous passez d'un onglet à l'autre.

Pour mes propres besoins, j'ai développé ce plugin avec ma propre fonctionnalité: conversion automatique de toutes les balises html dans les balises "<code>" en leurs entités respectives lors de l'enregistrement. Cela signifie que vous pouvez écrire du code HTML standard dans les balises de code de l'onglet Texte, puis l'enregistrer. Tous les éléments des balises de pré-conversion seront convertis en entités pour permettre un affichage correct sur le front du site et l'éditeur visuel. Ce n'est pas la solution la plus élégante que j'ai trouvée à ce jour, mais cela semble fonctionner. Ajoutez cette ligne à votre fichier functions.php après avoir activé le plugin:

function code_content_conversion_filter( $content ) {
        return preg_replace_callback( '|<code.*>(.*)</code|isU' , 'convert_entities', $content );
}

function convert_entities( $matches ) {
        return str_replace( $matches[1], htmlspecialchars($matches[1], ENT_QUOTES | ENT_HTML5, 'UTF-8', FALSE ), $matches[0] );
}

add_filter( 'content_save_pre', 'code_content_conversion_filter', 0);

Maintenant, il suffit de taper n'importe quel code HTML valide entre les balises de code, et lorsque vous enregistrez, lorsque l'éditeur apparaît, ils sont tous convertis en entités. Cela vous permet d’écrire du code plus rapidement. Maintenant, la seule chose qui reste un problème est que si vous avez un champ "pre" avec une balise de code imbriquée et HTML, et que vous allez dans l'onglet visuel et essayez d'insérer une nouvelle ligne dans le code, une balise br est injecté dans votre balise de code dans le code HTML. Il doit y avoir une option pour désactiver cela dans TinyMCE. Quoi qu'il en soit, tant que vous modifiez vos champs de pré à partir de l'onglet texte, vous pouvez librement basculer d'un onglet à l'autre, ajouter du contenu dans n'importe quel onglet, enregistrer dans l'un ou l'autre de ces onglets sans avoir à vous soucier de la mise en forme!

Cela résout effectivement les 5 points de ma question initiale. Le point 2 est encore un peu flou, mais je pense que pour la plupart des gens, cela règle le problème. Je prévois de parcourir ce plugin à un moment donné, d'extraire les parties nécessaires, de le combiner avec mes trouvailles et de le reconditionner pour un téléchargement public. Mon objectif ici est de créer un plug-in d'installation simple en un clic qui soit conforme aux attentes.

J'espère que cela aide tout le monde!

5

Au début, je pense que ce problème a été résolu depuis WP version 3.5; voir billet 19666 en trac . Mais le tinyMCE a un crochet qui nous donne la possibilité de changer le contenu dans l'éditeur et vous ne devez pas analyser en sortie sur le front-end.

Un petit script source. Je n'ai pas testé ceci avec une version actuelle de WP, qui était une solution plus ancienne pour un client.

Ajoutez cette source via un plugin et améliorez le balisage. La vérification de la fonction pour la balise html <pre et si elle existe, sera remplacée par une balise.

add_filter( 'tiny_mce_before_init', 'fb_correction_content_tiny_mce' );

function fb_correction_content_tiny_mce( $init ) {

    $init['setup'] = "function(ed) {
        ed.onBeforeSetContent.add( function(ed, o) {

            if ( o.content.indexOf('<pre') != -1 ) {
                o.content = o.content.replace(
                    /<pre[^>]*>[\\s\\S]+?<\\/pre>/g,
                    function(a) {
                        return a.replace(/(\\r\\n|\\n)/g, '<br />');
                    }
                );
            }
        } );
    }";

    return $init;
}
3
bueltge

J'ai eu un problème similaire à OP, mais pour moi, garder <h1> dans <div> posait un problème. Voici ce que je voulais conserver lors du basculement entre les onglets Texte et Visuel:  h1 in div and with div inside 

Chaque fois que j'ai changé l'onglet <h1> a disparu. J'ai fait beaucoup de recherches et pour Wordpress 4.7.3, j'ai découvert qu'il y avait beaucoup de corrections obsolètes. Il y a eu une mise à niveau majeure de TinyMCE de la version 3 à la version 4. Les solutions pour la v.3 n'ont pas fonctionné pour la v.4. Après plus de recherches sur Google et la lecture de la documentation originale de TinyMCE version 4, j'ai trouvé la solution, en particulier pour mon cas:

  1. Installer le plugin Advanced TinyMCE Configuration
  2. définir le paramètre valid_children de TinyMCE sur +div[h1],h1[div]
  3. J'ai également configuré indent=true, forced_root_block=false et schema=html5 (quand j'ai lu la description de forced_root_block, j'ai compris qu'il s'agissait d'un substitut de wpautop).

En conséquence, je reçois ceci (et il est résistant à la commutation des onglets)  enter image description here 

0
Marecky