bbcode editor и parser
05-06-2011
Здравейте, тъй като много хора търсят bbcode а тук уроците не са много богати реших да направя един простичък функционален bbcode editor и съответно bbcode parser. Взех един начален код и добавих още няколко функционалности като добавяне на html таблица. Смесих javascript с jquery защото някои неща не можах да ги преведа на jquery (като createRange и т.н) а с jquery ми е по-лесно да работя, но все пак всичко си работи перфекто.

Ето и файловете които написах.
BBbutons.js (тук са функциите за бутоните и за добавяне в посочената textarea, по-долу ще ви покажа как да посочите в коя textarea да се добавят нещата )
document.write("<script src='http://code.jquery.com/jquery-latest.js'></script>");//добяме последната версия на jquery
var textarea;
var content;

function bbcodetoolbar(obj) { //създаваме функцията за показване на bbcode editor-a
document.write("<style>.button {border: 1px solid #ccc;margin: 1px;padding: 2px;}.button:hover {filter:progid:DXImageTransform.Microsoft.Alpha(opacity=60);-moz-opacity: 0.6;opacity:0.6;}.ed {width: 400px;height: 150px;}</style>");//стила на бутоните
document.write("<div class=\"toolbar\">");
document.write("<img class=\"button\" src=\"images/bold.gif\" name=\"btnBold\" title=\"Удебеленяване\" onClick=\"addtags('','','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/italic.gif\" name=\"btnItalic\" title=\"Наклоняване\" onClick=\"addtags('[i]','[/i]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/underline.gif\" name=\"btnUnderline\" title=\"Подчертаване\" onClick=\"addtags('[u]','[/u]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/strike.gif\" name=\"btnUnderline\" title=\"Зачеркване\" onClick=\"addtags('[s]','[/s]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/left.png\" name=\"btnUnderline\" title=\"Подравняване в ляво\" onClick=\"addtags('[l]','[/l]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/center.png\" name=\"btnUnderline\" title=\"Подравняване в центъра\" onClick=\"addtags('[c]','[/c]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/right.png\" name=\"btnUnderline\" title=\"Подравняване в дясно\" onClick=\"addtags('[r]','[/r]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/justify.png\" name=\"btnUnderline\" title=\"Двостранно подравняване\" onClick=\"addtags('[j]','[/j]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/unordered.gif\" name=\"btnUnderline\" title=\"Списък\" onClick=\"addlist('" + obj + "','un')\">");
document.write("<img class=\"button\" src=\"images/ordered.gif\" name=\"btnUnderline\" title=\"Списък с номерация\" onClick=\"addlist('" + obj + "','or')\">");
document.write("<img class=\"button\" src=\"images/link.gif\" name=\"btnLink\" title=\"Добави линк\" onClick=\"addurl('" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/picture.gif\" name=\"btnPicture\" title=\"Добави снимка\" onClick=\"addimage('" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/linkpic.gif\" name=\"btnPicture\" title=\"Добави снимка с линк\" onClick=\"addimgurl('" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/quote.gif\" name=\"btnQuote\" title=\"Цитат\" onClick=\"addtags('[quote]','[/quote]','" + obj + "')\">");
document.write("<img class=\"button\" src=\"images/code.gif\" name=\"btnQuote\" title=\"Код\" onClick=\"addtags('[code]','[/code]','" + obj + "')\">");
document.write("<br><select name=\"fontcolor\" id=\"font\" onChange=\"addtags('[color='+$('#font').val()+']','[/color]','" + obj + "')\">");
document.write("<option value=\"0\" style=\"color:black\">Изберете цвят</option>");
document.write("<option value=\"black\" style=\"color:black\">Черенo</option>");
document.write("<option value=\"silver\" style=\"color:silver\">Сребро</option>");
document.write("<option value=\"gray\" style=\"color:gray\">Сиво</option>");
document.write("<option value=\"maroon\" style=\"color:maroon\">Кестеняво</option>");
document.write("<option value=\"red\" style=\"color:red\">Червено</option>");
document.write("<option value=\"navy\" style=\"color:navy\">Тъмносиньо</option>");
document.write("<option value=\"blue\" style=\"color:blue\">Синьо</option>");
document.write("<option value=\"green\" style=\"color:green\">Зелено</option>");
document.write("<option value=\"olive\" style=\"color:olive\">Маслиненозелено</option>");
document.write("<option value=\"yellow\" style=\"color:yellow;background-color:red;\">Жълто</option>");
document.write("<option value=\"white\" style=\"color:white;background-color:#ADADAD;\">Бяло</option>");
document.write("<option value=\"purple\" style=\"color:purple\">Пурпурен</option>");
document.write("</select>");
document.write("<select name=\"size\" id=\"size\" onChange=\"addtags('[size='+$('#size').val()+']','[/size]','" + obj + "')\">");
document.write("<option value=\"0\">Изберете размер</option>");
document.write("<option value=\"7\">Много малък</option>");
document.write("<option value=\"9\">Малък</option>");
document.write("<option value=\"12\">Нормален</option>");
document.write("<option value=\"18\">Голям</option>");
document.write("<option value=\"24\">Много голям</option>");
document.write("</select> ");
document.write("Колони: <input type='text' name='cols' id='cols' size='1' maxlength='2'/>");
document.write("Редове: <input type='text' name='rows' id='rows' size='1' maxlength='2'/>");
document.write("<input type='button' name='addt' value='Добави таблица' onClick=\"addtable('"+obj+"')\"/>");
document.write("</div>");
document.write("<div id='smiles' style='width:600px;'></div>");//ако не искате да имате smiles махнете този ред!

var dir = "smiles/";//въведи папката в която са картинките
var link=['smile.gif','sad.gif','laught.gif'];//въведи името на всяка една картинка
var icon=[':)',':(',':D'];//въведи съответния текст(иконката) който ще се добавя в textarea-та
jQuery.each(link, function(i,v) {//за всяки веведен линк...
var cont = $('#smiles').html();
$('#smiles').html(cont+"<img src='"+dir+v+"' onClick=\"addtags('',' "+icon[i]+" ','" + obj + "')\" /> ");//... ще се добавя нов img над textareata
});
}

function addlist(obj,ord){//функция за създаване на списък
var textarea = $('#'+obj);//взимаме id-то на textarea-та
var value = textarea.val();//стойноста на textarea-та
var listvalue = "init";
var thelist = "";
while ( (listvalue != "") && (listvalue != null) ) {//докато не натиснем "отказ" или оставим празно полето...
listvalue = prompt("Въведи предмет в списъка. Кликни на 'Отказ' или остави празно и натисни 'ОК', за да завършиш списъка", "");//... ще ни се появява input в който да напишем елемента от списъка
if ( (listvalue != "") && (listvalue != null) ) {
thelist += "[*]"+listvalue+"[/*]\n";
}
}
if ( thelist != "") {
thelist = "\n[list="+ord+"]\n"+thelist+"[/list]\n";
addtags('',thelist,obj);//добавяме списъка към textarea-та
}
}

function addtable(obj) {//функция за създаване на таблица
var textarea = $('#'+obj);//взимаме id-то на textarea-та
var value = textarea.val();//стойноста на textarea-та
var rows=$('#rows').val();//стойноста на input rows т.е колко реда да има таблицата
var cols=$('#cols').val();//стойноста на input cols т.е колко колони да има таблицата
var text = "\n[table]\n";
for(i=1;i<=rows;i++) {//за всяки ред добавяме код за редове
text +="[tr]\n";
for(k=1;k<=cols;k++){//за всяки колона добавяме код за колона
text +="[td]";
text +="[/td]\n";
}
text +="[/tr]\n";
}
text += "[/table]\n";
addtags('',text,obj);//добавяме таблицата към textarea-та
$('#rows').val("");
$('#cols').val("");//изчистваме 2-та input-а
}


function addimage(obj){//функция за добавяне на снимка към
textarea = document.getElementById(obj);
var url = prompt('Въведи линк към картинката','http://');//прозорче в което да въведеш линка към картинката
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
if (url != '' && url != null) {//ако сте въвели стойност в input полето ще продължи долния код

if (document.selection) {
textarea.focus();//фокусираме textareata
var sel = document.selection.createRange();//взема се стойноста на селектирания текст
sel.text = '[img]' + url + '[/img]';
}//ако сте селектирали текст(линк) [img] ще бъде добавено след него
else {
textarea.focus();//фокусираме textareata
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var sel = textarea.value.substring(start, end);
var rep = '[img]' + url + '[/img]';
textarea.value = textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
textarea.scrollTop = scrollTop;
textarea.scrollLeft = scrollLeft;
}//ако не сте ще селектирали текст(линк) [img] ще бъде добавено там където е курсора
}
}

function addurl(obj){//фунция за добавяне на линк
textarea = document.getElementById(obj);
var url = prompt('Въведете линк:','http://');//прозорче в което да въведеш линка
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
if (url != '' && url != null) {//ако сте въвели стойност в input полето ще продължи долния код
if (document.selection) {
textarea.focus();//фокусираме textareata
var sel = document.selection.createRange();//взема се стойноста на селектирания текст

if(sel.text==""){
var url2 = prompt('Име на линка','');//ако не сте селектирали текст който да играе ролята на име на линка то тогава ще ви излезе input поле където да въведете име
sel.text = '[url=' + url + ']' + url2 + '[/url]';
}
else {sel.text = '[url=' + url + ']' + sel.text + '[/url]';}
}
else {
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var sel = textarea.value.substring(start, end);
if(sel=="") {
var url2 = prompt('Име на линка','');
var rep = '[url=' + url + ']' + url2 + '[/url]';
}
else {var rep = '[url=' + url + ']' + sel + '[/url]';}
textarea.value = textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
textarea.scrollTop = scrollTop;
textarea.scrollLeft = scrollLeft;
}
}
}

function addimgurl(obj){//функция за добавяне на картинка с линк
textarea = document.getElementById(obj);
var url = prompt('Въведете линк:','http://');
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
if (url != '' && url != null) {
if (document.selection) {
textarea.focus();//фокусираме textareata
var sel = document.selection.createRange();//взема се стойноста на селектирания текст

if(sel.text==""){
var img = prompt('Линка към снимката','http://');
sel.text = '[img=' + url + ']' + img + '[/img]';
}
else {sel.text = '[img=' + url + ']' + sel.text + '[/img]';}
}
else {
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var sel = textarea.value.substring(start, end);
if(sel=="") {
var img = prompt('Линка към снимката','http://');
var rep = '[img=' + url + ']' + img + '[/img]';
}
else {var rep = '[img=' + url + ']' + sel + '[/img]';}
textarea.value = textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
textarea.scrollTop = scrollTop;
textarea.scrollLeft = scrollLeft;
}
}
}

function addtags(tag1,tag2,obj){//функция за добавяне на тагове
if(tag2=="[/color]" || tag2=="[/size]") {$("option[value='0']").attr('selected','selected');}//ако таг2 е [/color] или [/size] при изпълнение на функцията ще се селектне отново първия option
textarea = document.getElementById(obj);
//IE
if (document.selection) {
var sele = document.selection.createRange();//взема се стойноста на селектирания текст
sele.text = tag1 + sele.text + tag2;

}
else { //Mozilla
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
var sel = textarea.value.substring(start, end);
var rep = tag1 + sel + tag2;
textarea.value = textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
textarea.scrollTop = scrollTop;
textarea.scrollLeft = scrollLeft;

}
}




bbcode.php (функцията в този файл преобразува bbcode-а в html)
<?php
function bbcode($text){
$text=preg_replace("/\[b\](.+?)\[\/b\]/s", '<b>$1</b>',$text); //заменяме bbcode текст с html-а <b>текст</b>... надолу се прави абсолютно същотото за всеки bbcode

$text=preg_replace("/\[i\](.+?)\[\/i\]/s", '<i>$1</i>',$text);

$text=preg_replace("/\[u\](.+?)\[\/u\]/s", '<u>$1</u>',$text);

$text=preg_replace("/\[l\](.+?)\[\/l\]/s", '<div style="text-align:left;">$1</div>',$text);

$text=preg_replace("/\[c\](.+?)\[\/c\]/s", '<div style="text-align:center;">$1</div>',$text);

$text=preg_replace("/\[r\](.+?)\[\/r\]/s", '<div style="text-align:right;">$1</div>',$text);

$text=preg_replace("/\[j\](.+?)\[\/j\]/s", '<div style="text-align:justify;">$1</div>',$text);

$text=preg_replace("/\[s\](.+?)\[\/s\]/s", '<strike>$1</strike>',$text);

$patterns = array(
'/\[url\=(.*?)\](.*?)\[\/url\]/is',
'/\[img\=(.*?)\](.*?)\[\/img\]/is',
'/\[url\](.*?)\[\/url\]/is',
'/\[img\](.*?)\[\/img\]/is',
'/((^http|https)(\S+))/is'
);
$replaces = array(
'<a href="$1" target="_blank">$2</a>',
'<a href="$1" target="_blank"><img src="$2" target="_blank"/></a>',
'<a href="$1" target="_blank">$1</a>',
'<img src="$1" target="_blank"/>',
'<a href="$1" target="_blank">$1</a>'
);

$text = preg_replace($patterns, $replaces, $text);

$text=preg_replace("/\[list=un\](.+?)\[\/list\]/s", '<ul>$1</ul>',$text);

$text=preg_replace("/\[list=or\](.+?)\[\/list\]/s", '<ol>$1</ol>',$text);

$text=preg_replace("/\[\*\](.+?)\[\/\*\]/s", '<li>$1</li>',$text);

$text=preg_replace("/\[quote\](.+?)\[\/quote\]/s", '<table cellspacing="1" width="100%" border="0"><tr><td>Цитат:</td></tr><tr><td width="100%" style="background-color:#C7C7C7;border:solid 1px black">$1</td></tr></table>',$text);

$text=preg_replace("/\[quote\=(.+?)](.+?)\[\/quote\]/s", '<table cellspacing="1" width="100%" border="0"><tr><td>$1 каза:</td></tr><tr><td width="100%" style="background-color:#C7C7C7;border:solid 1px black">$2</td></tr></table>',$text);

$text=preg_replace("/\[color\=(.+?)\](.+?)\[\/color\]/s", '<span style="color:$1">$2</span>',$text);

$text=preg_replace("/\[size\=(.+?)\](.+?)\[\/size\]/s", '<span style="font-size:$1px;">$2</span>',$text);

$text=preg_replace("/\[code\](.+?)\[\/code\]/s",'<table cellspacing="1" width="100%" border="0"><tr><td>Code:</td></tr><tr><td width="100%" style="background-color:#C7C7C7;border:solid 1px black">$1</td></tr></table>',$text);

$dir= "smiles";//папката в която са картинките
$smiles = array(':)',':(',':D');//текста който е бил в textarea-та
$smileslink = array('smile.gif','sad.gif','laught.gif');//въведи съответното име на всяка една картинка
$i = 0;
foreach($smiles AS $sm) {
$text = str_replace($sm,"<img src='$dir/$smileslink[$i]'/>",$text);
$i++;
}

$text = nl2br($text); //преобразува всички празни редове до <br />

$s1s = array('/\[table\]\<br \/\>/s','/\[td\]\<br \/\>/s','/\[\/td\]\<br \/\>/s','/\[tr\]\<br \/\>/s','/\[\/tr\]\<br \/\>/s','/\<li\>\<br \/\>/s','/\<\/li\>\<br \/\>/s','/\<ol\>\<br \/\>/s','/\<ul\>\<br \/\>/s');
$bez = array('[table]','[td]','[/td]','[tr]','[/tr]','<li>','</li>','<ol>','<ul>');
$text = preg_replace($s1s,$bez,$text);//махам <br /> от някои места за да се изместват нещата

$text=preg_replace("/\[table\](.+?)\[\/table\]/s", '<table border="1" max-width="600">$1</table>',$text);

$text=preg_replace("/\[tr\](.+?)\[\/tr\]/s", '<tr>$1</tr>',$text);

$text=preg_replace("/\[td\](.+?)\[\/td\]/s", '<td>$1</td>',$text);


return stripslashes($text); //връща променото съдържание
}
?>


примерна страница

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>bbcode editor+parser</title>
<script src="BBbutons.js" type="text/javascript"></script> //добавяме js файла
</head>
<body style="background: #ececec;">
<form method="post">
<script>bbcodetoolbar('area'); </script> //bbcodetoolbar(id-то на textarea-та в която ще се добавя)
<textarea id="area" name="txtarea" cols="130" rows="20"></textarea><br />
<input type="submit" name="submit" value="Прегледай"/>
</form>
<br />
<?php
if(isset($_POST['submit'])) {
include "bbcode.php";//добавяне на страницата с функцията за преобразуване в html
echo bbcode($_POST['txtarea']); //bbcode($text) преобразуване на текста в html
}
?>
</body>
</html>


TIP (за smiles): ако искате да добавите нова усмивка добавете в js и php документа линка(или по точно името) на картинката и текста който ще се добавя или съответно ще се търси и заменя в textarea-та

Всички файлове от урока(+картинките и 3 smiles)
Резервен линк 1
Резервен линк 2
Резервен линк 3

Демо
Резервно демо 1
Резервно демо 2

Дано да съм ви бил от полза :).При проблеми пишете ми ЛС или пишете в форума :)

Урока е авторски и забранявам копирането му в други сайтове без разрешението ми или това на администраторите!!!







/ Трябва да сте регистриран за да напишете коментар /
От: BorislawBotew
12:32 05-06-2011
Браво много полезно, въпреки че си има tinymce :)
От: IzKuFeLiQqQqQ
12:57 05-06-2011
Да има, но на някои им трябва нещо по обикновено... затова направих това :)
От: voTkaPoweR
19:38 06-06-2011
станало му жал... в урока на hunter покава как се прави... това.. :)
От: root321
21:02 06-06-2011
получило се е супер! Поздравления
От: viking
15:15 07-06-2011
Оправи си кодировката в демотата на utf-8. Иначе само поздравления за урока.
От: IzKuFeLiQqQqQ
22:29 07-06-2011
кодировката е utf... оправи си browser-a :D и благодаря :)
От: viking
23:10 07-06-2011
Погледни бутоните когато искаш да изпратиш заявката - на маймуница са. ;)
От: IzKuFeLiQqQqQ
11:39 08-06-2011
http://prikachi.com/images/17/3428017w.png ... и никой друг не се оплаква от това оправи си browser
От: viking
17:26 08-06-2011
На моя браузър всичко му е наред. Проблема не е като му оправя кодировката.
От: viking
18:01 08-06-2011
На моя браузър всичко му е наред. Проблема не е като му оправя кодировката.
От: mimzity
11:54 09-06-2011
никой не сподели че трябва да имаме jQuery ... ?
От: IzKuFeLiQqQqQ
12:11 09-06-2011
защото съм добавил библиотеката...

document.write(""); най горе в js файла е :P
От: Hous
23:17 09-06-2011
Да така е трябваше да се спомене кое какво се използва е не само 100ина реда код нали все пак е урок , мисля,че админата трябва да наложи по -подробни описания сега как да разбереш кое какво прави,това е един готов код който автора е ползвал просто го е пейстнал тук аз лично съм доволен като идея и изпълнение но от обяснението 1/10 .
От: IzKuFeLiQqQqQ
0:56 10-06-2011
ми окей... утре ще му сложа обяснения (коментари) на нещата и ще помоля админа да го "неодобри" за няколко минути за да променя кодовете и готово :)

демек скоро очаквайте обяснения кое какво прави :P е много много няма да си изграя да обяснявам в php файла защото повечето неща са еднотипни :)
От: admin
20:45 11-06-2011
Това е в категория "Кодове" или "Готови кодове" и не се изисква непременно пълно обяснение на всичко.
Урока си е ок.
От: IzKuFeLiQqQqQ
0:20 12-06-2011
ni6to 6efe az ve4e go napraih, slojih i po nenatovarva6t na4in za nqkoi ne6ta... utre 6e si podgotvq ne6tata i 6e ti kaja za 5 min da go neodobri6 :):) az slojih obqsneniq kolkoto da ima de xD:P
От: dignat
11:19 15-06-2011
здравейте, предполагам, че не съм в правилния форум ноче опитам
за дипломната си работа трябва да направя админ панел на уеб сайта, който подгатвям. започнах са база данни в mysql съхранявам страниците там, но се затрудних с edit скрипта i new искаме се да може администратора от панел да влиза в съответната страница да я актуализира или изтрива, някой може ли да ми помогне?
Благодаря, предварително
От: youandI
21:01 16-06-2011
Евала за системата ! Поздравления !
От: IzKuFeLiQqQqQ
1:48 24-06-2011
радвайте на още едно демо http://izkufeliq.byethost14.com/bbcode/ xD
От: zlatincho0
14:10 02-09-2011
При мене имам проблем всичко е ок обаче не ми искарва бутоните искарвами само текст ареата и нутона за изпраща не !!
От: dakata__92
17:51 11-03-2012
За д аработи под ИЕ - заменете функцията от урока така :

function addtags(tag1,tag2,obj){//функция за добавяне на тагове
if(tag2=="[/color]" || tag2=="[/size]") {$("option[value='0']").attr('selected','selected');}//ако таг2 е [/color] или [/size] при изпълнение на функцията ще се селектне отново първия option
textarea = document.getElementById(obj);
textarea.focus();
//IE
if (document.selection && document.selection.createRange) {
var sele = document.selection.createRange();//взема се стойноста на селектирания текст
if (sele.parentElement() == textarea) sele.text = tag1 + sele.text + tag2;


}
else { //Mozilla
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
var sel = textarea.value.substring(start, end);
var rep = tag1 + sel + tag2;
textarea.value = textarea.value.substring(0,start) + rep + textarea.value.substring(end,len);
textarea.scrollTop = scrollTop;
textarea.scrollLeft = scrollLeft;

}
}
1