Il y a deux fonctions principales :
- BBCodeGetEditor qui renvoit le code HTML des boutons, du champ textarea ainsi que le code Javascript d'insertion de balise.
- BBCode2Html qui converti un code BBCode en code HTML.
BBCodeGetEditor
La fonction attend 3 paramètres :
- $aName : le nom et l'identifiant qui seront utilisés pour le champ textarea.
- $aTxt : le texte par défaut dans le champ textarea.
- $aButtonLst : la liste des boutons à afficher. A choisir parmi ['fontsize', 'color', 'bold', 'italic', 'underline', 'stroke', 'sup', 'sub', 'left', 'right', 'center', 'justify', 'img', 'video', 'url', 'email', 'code', 'quote']
Les balises BBCode gérées la fonction
Formatage du texte
[b]gras[/b]
[i]italique[/i]
[u]souligné[/u]
[s]barré[/s]
[sup]texte en exposant[/sup]
[sub]texte en indice[/sub]
[size=20]texte en 20 pixels[/size]
[color=#ff0000]texte en rouge[/color]
Alignement du texte
[left]texte aligné à gauche[/left]
[right]texte aligné à droite[/right]
[center]texte centré[/center]
[justify]texte justifié[/justify]
Liste de type ul
[list]
[*]élément 1
[*]élément 2
[*]élément 3
[/list]
Liste de type ol
[list=1]
[*]élément 1
[*]élément 2
[*]élément 3
[/list]
Image
[img]http://blog.niap3d.com/img/4/20161106103748.png[/img]
Vidéo
Affichage d'une vidéo depuis youtube.com, youtu.be, dailymotion.com, dai.ly, vimeo.
[video]https://www.youtube.com/watch?v=nun_KHA0Lgw[/video]
Url et email
[url]http://blog.niap3d.com[/url]
[url=http://blog.niap3d.com]Accéder au blog[/url]
[email]jipe@jipe-sa.jp[/email]
[email=jipe@jipe-sa.jp]Envoyer un email[/email]
Code
[code]Affichage de code HTML, Javascript, PHP, etc[/code]
Citation de message
[quote]Citation d'un texte[/quote]
[quote=Auteur de la citation]Citation d'un texte[/quote]
Exemple d'utilisation
echo BBCodeGetEditor('commentaireTexte', '', array('fontsize', 'color', 'bold', 'italic', 'underline', 'br', 'left', 'center', 'right'));
Cette ligne va générer le code HTML suivant :
<section>
<select id="bbcode1" onchange="EditorTagInsert('commentaireTexte', '[size=$1]', '[/size]', this.value);">
<option value="">Dimension</option>
<option value="10">10px</option>
<option value="11">11px</option>
<option value="12">12px</option>
<option value="14">14px</option>
<option value="16">16px</option>
<option value="18">18px</option>
<option value="20">20px</option>
<option value="24">24px</option>
</select>
<select id="bbcode2" onchange="EditorTagInsert('commentaireTexte', '[size=$1]', '[/size]', this.value);">>
<option value="">Couleur</option>
<option value="#ff0000">Rouge</option>
<option value="#00ff00">Vert</option>
<option value="#0000ff">Bleu</option>
</select>
<input type="button" id="bbcode3" value="Gras" onclick="EditorTagInsert('commentaireTexte', '[b]', '[/b]', 0);" />
<input type="button" id="bbcode4" value="Italique" onclick="EditorTagInsert('commentaireTexte', '[i]', '[/i]', 0);" />
<input type="button" id="bbcode5" value="Souligné" onclick="EditorTagInsert('commentaireTexte', '[u]', '[/u]', 0);" />
<input type="button" id="bbcode9" value="Aligné à gauche" onclick="EditorTagInsert('commentaireTexte', '[left]', '[/left]', 0);" />
<input type="button" id="bbcode11" value="Centrer" onclick="EditorTagInsert('commentaireTexte', '[center]', '[/center]', 0);" />
<input type="button" id="bbcode10" value="Aligné à droite" onclick="EditorTagInsert('commentaireTexte', '[right]', '[/right]', 0);" />
</section>
<textarea id="commentaireTexte" name="commentaireTexte" rows="10" cols="60"></textarea>
<script type="text/javascript">
//<![CDATA[
var tagLst = [];
function EditorTagInsert(aId, aTag1, aTag2, aOpt){
if(aOpt === '') return 0;
if(aOpt != 0) aTag1 = aTag1.replace("$1", aOpt);
var e = document.getElementById(aId);
if(typeof(e) == "undefined" || e == null) return 0;
var s1 = e.selectionStart;
var s2 = e.selectionEnd;
var txt = e.value;
e.value = (txt.substring(0, s1) + aTag1 + txt.substring(s1, s2) + aTag2 + txt.substring(s2, txt.length));
e.focus;
}
//]]>
</script>
En image, sans aucun style cela donne l'affichage suivant :
Le code de la fonction BBCodeGetEditor
// editeur BBCode dans un champ de type textarea
function BBCodeGetEditor($aName, $aTxt, $aButtonLst=''){
// 1- liste des balises reconnues
$tag = array();
$tag['fontsize'] = array('id'=>'bbcode1', 'title'=>'Taille', 'type'=>'select', 'option'=>[
['title'=>'Dimension', 'value'=>''],
['title'=>'10px', 'value'=>'10'],
['title'=>'11px', 'value'=>'11'],
['title'=>'12px', 'value'=>'12'],
['title'=>'14px', 'value'=>'14'],
['title'=>'16px', 'value'=>'16'],
['title'=>'18px', 'value'=>'18'],
['title'=>'20px', 'value'=>'20'],
['title'=>'24px', 'value'=>'24']
], 'tag1'=>'[size=$1]', 'tag2'=>'[/size]');
$tag['color'] = array('id'=>'bbcode2', 'title'=>'Couleur', 'type'=>'select', 'option'=>[
['title'=>'Couleur', 'value'=>''],
['title'=>'Rouge', 'value'=>'#ff0000'],
['title'=>'Vert', 'value'=>'#00ff00'],
['title'=>'Bleu', 'value'=>'#0000ff']
], 'tag1'=>'[color=$1]', 'tag2'=>'[/color]');
$tag['bold'] = array('id'=>'bbcode3', 'title'=>'Gras', 'type'=>'button', 'tag1'=>'[b]', 'tag2'=>'[/b]');
$tag['italic'] = array('id'=>'bbcode4', 'title'=>'Italique', 'type'=>'button', 'tag1'=>'[i]', 'tag2'=>'[/i]');
$tag['underline'] = array('id'=>'bbcode5', 'title'=>'Souligné', 'type'=>'button', 'tag1'=>'[u]', 'tag2'=>'[/u]');
$tag['stroke'] = array('id'=>'bbcode6', 'title'=>'Barré', 'type'=>'button', 'tag1'=>'[s]', 'tag2'=>'[/s]');
$tag['sup'] = array('id'=>'bbcode7', 'title'=>'Exposant', 'type'=>'button', 'tag1'=>'[sup]', 'tag2'=>'[/sup]');
$tag['sub'] = array('id'=>'bbcode8', 'title'=>'Indice', 'type'=>'button', 'tag1'=>'[sub]', 'tag2'=>'[/sub]');
$tag['left'] = array('id'=>'bbcode9', 'title'=>'Aligné à gauche', 'type'=>'button', 'tag1'=>'[left]', 'tag2'=>'[/left]');
$tag['right'] = array('id'=>'bbcode10', 'title'=>'Aligné à droite', 'type'=>'button', 'tag1'=>'[right]', 'tag2'=>'[/right]');
$tag['center'] = array('id'=>'bbcode11', 'title'=>'Centrer', 'type'=>'button', 'tag1'=>'[center]', 'tag2'=>'[/center]');
$tag['justify'] = array('id'=>'bbcode12', 'title'=>'Justifier', 'type'=>'button', 'tag1'=>'[justify]', 'tag2'=>'[/justify]');
$tag['img'] = array('id'=>'bbcode13', 'title'=>'Image', 'type'=>'button', 'tag1'=>'[img]', 'tag2'=>'[/img]');
$tag['video'] = array('id'=>'bbcode18', 'title'=>'Vidéo', 'type'=>'button', 'tag1'=>'[video]', 'tag2'=>'[/video]');
$tag['url'] = array('id'=>'bbcode14', 'title'=>'Url', 'type'=>'button', 'tag1'=>'[url]', 'tag2'=>'[/url]');
$tag['email'] = array('id'=>'bbcode16', 'title'=>'Email', 'type'=>'button', 'tag1'=>'[email]', 'tag2'=>'[/email]');
$tag['code'] = array('id'=>'bbcode15', 'title'=>'Code', 'type'=>'button', 'tag1'=>'[code]', 'tag2'=>'[/code]');
$tag['quote'] = array('id'=>'bbcode17', 'title'=>'Citation', 'type'=>'button', 'tag1'=>'[quote]', 'tag2'=>'[/quote]');
// 2- initialise les balises à utiliser parmi la liste aButtonLst
$tagSel = array();
if(empty($aButtonLst)){
$tagSel = $tag;
}else{
foreach($aButtonLst as $v){
if(!empty($tag[$v])) $tagSel[] = $tag[$v];
}
}
// 3- affiche les boutons choisis
$h = '<section>';
foreach($tagSel as $v){
switch($v['type']){
case 'button' :
// bouton
$h .= '<input id="'.$v['id'].'" type="button" value="'.$v['title'].'" onclick="EditorTagInsert(\''.$aName.'\', \''.$v['tag1'].'\', \''.$v['tag2'].'\', 0);" />';
break;
case 'select' :
// menu déroulant
$h .= '<select id="'.$v['id'].'" onchange="EditorTagInsert(\''.$aName.'\', \''.$v['tag1'].'\', \''.$v['tag2'].'\', this.value);">';
foreach($v['option'] as $v){
$h .= '<option value="'.$v['value'].'">'.$v['title'].'</option>';
}
$h .= '</select>';
break;
}
}
$h .= '</section><textarea id="'.$aName.'" name="'.$aName.'" rows="10" cols="60">'.$aTxt.'</textarea>';
// 4- code javascript
// ce code permet d'insérer des balises en tenant compte de la sélection.
$h .= '
<script type="text/javascript">
//<![CDATA[
var tagLst = [];
function EditorTagInsert(aId, aTag1, aTag2, aOpt){
if(aOpt === "") return 0;
if(aOpt != 0) aTag1 = aTag1.replace("$1", aOpt);
var e = document.getElementById(aId);
if(typeof(e) == "undefined" || e == null) return 0;
var s1 = e.selectionStart;
var s2 = e.selectionEnd;
var txt = e.value;
e.value = (txt.substring(0, s1) + aTag1 + txt.substring(s1, s2) + aTag2 + txt.substring(s2, txt.length));
e.selectionStart = s1 + aTag1.length;
e.selectionEnd = s2 + aTag1.length;
e.focus();
}
//]]>
</script>';
return $h;
}
Petite explication sur le code Javascript ajouté par BBCodeGetEditor
// 4- code javascript
// ce code permet d'insérer des balises en tenant compte de la sélection.
$h .= '
<script type="text/javascript">
//<![CDATA[
var tagLst = [];
function EditorTagInsert(aId, aTag1, aTag2, aOpt){
si aOpt est une chaine vide, l'appel à la fonction vient du premier élément d'un menu déroulant
if(aOpt === "") return 0;
si aOpt est différent de 0, l'appel vient d'un élément d'un menu déroulant. On remplace $1 dans la tag 1 par aOpt
if(aOpt != 0) aTag1 = aTag1.replace("$1", aOpt);
cherche l'élément
var e = document.getElementById(aId);
if(typeof(e) == "undefined" || e == null) return 0;
début de la sélection
var s1 = e.selectionStart;
fin de la sélection
var s2 = e.selectionEnd;
contenu du champ de texte
var txt = e.value;
remplace le texte en insérant la balise aTag1 avant le début de la sélection et aTag2 après la fin de le sélection
e.value = (txt.substring(0, s1) + aTag1 + txt.substring(s1, s2) + aTag2 + txt.substring(s2, txt.length));
remet le focus sur l'élément pour continuer à taper du texte
e.focus();
Allez plus loin avec BBCodeGetEditor
Si vous voulez plus de couleur (et vous le voudrez surement), il suffit de modifier le code à partir de la ligne 16 ($tag['color'] = ) et changer la liste des options. Chaque option est définit par une valeur (value) et son texte d'affichage (title)
['title'=>'Rouge', 'value'=>'#ff0000']
Le principe est le même pour les tailles de caractère à la ligne 5 ($tag['fontsize']).
Vous pouvez ajouter d'autres menus déroulants avec des caractères spéciaux ou des caractères UTF-8 (par exemple des flèches en UTF-8 : ⤴, ↩, ⇥).
Vous pouvez également facilement ajouter une liste de smiley (émoticon en français de l'académie française).
BBCode2Html
Voici une fonction simple pour convertir un texte avec des balises BBCode en HTML. La fonction contient quelques expressions régulières pour chercher les balises ouvrantes et fermantes et les remplacer par les équivalents HTML.
Ensuite la fonction s'occupe des balises vidéos avec preg_replace_callback. Dès qu'elle trouve des balises [video][/video], elle appelle la fonction VidProviderUrl2Player qui convertit une url Youtube, Dailymotion, Vimeo en lecteur HTML.
Et pour finir elle fait le ménage dans le texte en effaçant les balises BBCode restantes, qui n'ont pas été interprété.
Le code de la fonction BBCode2Html
// conversion d'un message en html
function BBCode2Html($aTxt){
// 1- remplace les retour à la ligne par des balises <br />
$aTxt = nl2br($aTxt);
// 2- liste des balises BBCode
$tag = array(
'/\[b\](.*?)\[\/b\]/is',
'/\[i\](.*?)\[\/i\]/is',
'/\[u\](.*?)\[\/u\]/is',
'/\[s\](.*?)\[\/s\]/is',
'/\[sup\](.*?)\[\/sup\]/is',
'/\[sub\](.*?)\[\/sub\]/is',
'/\[size\=(.*?)\](.*?)\[\/size\]/is',
'/\[color\=(.*?)\](.*?)\[\/color\]/is',
'/\[code\](.*?)\[\/code\]/is',
'/\[quote\](.*?)\[\/quote\]/is',
'/\[quote\=(.*?)\](.*?)\[\/quote\]/is',
'/\[left](.*?)\[\/left\]/is',
'/\[right](.*?)\[\/right\]/is',
'/\[center](.*?)\[\/center\]/is',
'/\[justify](.*?)\[\/justify\]/is',
'/\[list\](.*?)\[\/list\]/is',
'/\[list=1\](.*?)\[\/list\]/is',
'/\[\*\](.*?)(\n|\r\n?)/is',
'/\[img\](.*?)\[\/img\]/is',
'/\[url\](.*?)\[\/url\]/is',
'/\[url\=(.*?)\](.*?)\[\/url\]/is',
'/\[email\](.*?)\[\/email\]/is',
'/\[email\=(.*?)\](.*?)\[\/email\]/is'
);
// 3- correspondance HTML
$h = array(
'<strong>$1</strong>',
'<em>$1</em>',
'<u>$1</u>',
'<span style="text-decoration:line-through;">$1</span>',
'<sup>$1</sup>',
'<sub>$1</sub>',
'<span style="font-size:$1px;">$2</span>',
'<span style="color:$1;">$2</span>',
'<code><pre>$1</pre></code>',
'<blockquote>$1</blockquote>',
'<blockquote><cite>$1 : </cite>$2</blockquote>',
'<div style="text-align:left;">$1</div>',
'<div style="text-align:right;">$1</div>',
'<div style="text-align:center;">$1</div>',
'<div style="text-align:justify;">$1</div>',
'<ul>$1</ul>',
'<ol>$1</ol>',
'<li>$1</li>',
'<img src="$1" />',
'<a href="$1">$1</a>',
'<a href="$1">$2</a>',
'<a href="mailto:$1">$1</a>',
'<a href="mailto:$1">$2</a>'
);
// 4- remplace les balises BBCode par des balises HTMLdans le texte
$n = 1;
while($n > 0){
$aTxt = preg_replace($tag, $h, $aTxt, -1, $n);
}
// 5- balise vidéo
if(function_exists(VidProviderUrl2Player)) $aTxt = preg_replace_callback('/\[video\](.*?)\[\/video\]/is', 'VidProviderUrl2Player', $aTxt);
// 6- fais le ménage dans les balises restantes
return preg_replace(array('/\[(.*?)\]/is', '/\[\/(.*?)\]/is'), '', $aTxt);
}
Ici tout se jour à la ligne 63. On fait une boucle sur un appel preg_replace tant qu'il y a des remplacements. On utilise le paramètre count de la fonction preg_replace.
Exemple d'utilisation
$txt = "Bonsoir,
[size=18]Je vends ma collection de [u]carottes rapées[/u].[/size]
Cette collection comprend environ [b][color=#ff0000]500[/color][/b] pièces en aluminium et [b][color=#ff0000]70[/color][/b] en carbone.
[i]Voici quelques photos[/i]
[img]https://upload.wikimedia.org/wikipedia/commons/6/68/PLM_230_2691-2700.jpg[/img]
[img]https://fr.wikipedia.org/wiki/Train_de_la_Pr%C3%A9sidence_de_la_R%C3%A9publique_fran%C3%A7aise#/media/File:La_brigade_du_train_pr%C3%A9sidentiel_en_1919.jpg[/img]";
echo BBCode2Html($txt);
Le code va générer :
Bonsoir,<br />
<br />
<span style="font-size:18px;">Je vends ma collection de <u>carottes rapées</u>.</span><br />
Cette collection comprend environ <strong><span style="color:#ff0000;">500</span></strong> pièces en aluminium et <strong><span style="color:#ff0000;">70</span></strong> en carbone.<br />
<br />
<em>Voici quelques photos</em><br />
<img src="https://upload.wikimedia.org/wikipedia/commons/6/68/PLM_230_2691-2700.jpg" /><br />
<img src="https://fr.wikipedia.org/wiki/Train_de_la_Pr%C3%A9sidence_de_la_R%C3%A9publique_fran%C3%A7aise#/media/File:La_brigade_du_train_pr%C3%A9sidentiel_en_1919.jpg" />
Voilà pour ces deux fonctions. Bonne intégration !