Pokaż menu
 

Kilka słów o handyCode.

HandyCode to rozbudowany parser BBcode, którego głównymi zaletami są szybkość oraz fakt iż generuje on w pełni semantyczny kod html. Przejrzysta budowa sprawia, iż w łatwy sposób możemy dodawać własne znaczniki, zarządzać ich parametrami czy np. blokować parsowanie znaczników-dzieci. Dzięki drzewiastej strukturze bez problemu możemy określić rodziców oraz w zależności od nich wygenerować odpowiedni kod.

Standardowo klasa wyposażona jest w sporą listę znaczników:

handyCode nie krzyżuje znaczników oraz nie parsuje znaczników niezamkniętych. Dodatkowo zatrzymuje przetwarzanie rodziców.

Aby wyświetlić kod BBcode należy go skomentować za pomocą backslasha "\".

1
[u] \[b\]pogrubienie\[/b\] [/u]
 

Parametry

Kolejną ciekawą rzeczą są parametry które możemy bezproblemowo wykorzystywać we własnych znacznikach. Standardowo w każdym znaczniku osłygiwanych jest pięć podstawowych parametrów: id, class, position, color oraz size. Dodatkowo znacznik może posiadać parametr główny(bez nazwy np. [url=parametrglowny]link[/url]) oraz parametry specjalne które są konwertowane bezpośrednio przez funkcję znacznika. Wartości parametrów możemy otoczyć cudzysłowem.

1
[u=parametrglowny] [b class="jedenZparametrowGlobalnych" mojwlasny="parametrSpecjalny"]pogrubienie[/b] [/u]
 

Rainbow - aby świat był kolorowy

Dzięki współpracy z oddzielną klasą Rainbow, która koloruje kody źródłowe różnych języków możliwe jest użycie znaczników

Podczas użycia trybu code(lub użycia innego trybu w niepoprawny sposób(wtedy klasa sama zmieni tryb na code)) klasa oprócz kolorowania kodu html i php odnajduje elementy css i JavaScript ukryte pomiędzy znacznikami <style></style>, <script></script> lub w parametrach style="", onmouseover="" etc. Przykład wygenerowanego kodu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<head>
<style type="text/css">
tag #obiekt {
color:red;}
tag.klasa {
font-family:'Arial''Tahoma', sans}
.innaklasa {
background:#345;}
</style>
<title>handyCode - live demo</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript">
for(var i=0; i<string.length;i++)
{
  alert(i + ' glupi kod dla przykladu ;) ' + string.value);
}
</script>
</head>
<body>
<!-- pobrane z art.php.pl -->
<p id="p1"><span class="gfx"></span><span style="color:red;">Pokaż Polskiej społeczności PHP na co Cię stać!</span></p>
<p id="p2"><span class="gfx"></span><span onclick="alert(\"AAAAA\")">Wykaż się swoją wyobraźnią...</span></p>
<p id="p3"><span class="gfx"></span><span>Przedstaw nam Swoja prace!</span></p>

<?php
// komentarz
$zmienna '';
?>
</body>

Oczywiście klasa reaguje w przypadku złego kodu html. Upomina odpowiednim ostylowaniem o małych literach, cudzysłowach etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- kod zaczerpnięty z http://regularexpressions.info -->
<DIV CLASS=top>
  <DIV CLASS=logo>
    <IMG SRC="img/logo.gif" WIDTH=530 HEIGHT=100>
  </DIV>
</DIV>

<DIV CLASS=btntop>
  <A CLASS=btntop HREF="tutorial.html" TARGET="_top"> Tutorial </A>
  <A CLASS=btntop HREF="tools.html" TARGET="_top"> Tools & Languages </A>
  <A CLASS=btntop HREF="examples.html" TARGET="_top"> Examples </A>
  <A CLASS=btntop HREF="books.html" TARGET="_top"> Books & Reference </A>
</DIV>
 

Tworzenie obiektu klasy

Przejdźmy do konkretów. Użycie klasy jest banalnie proste.

1
2
3
4
5
6
7
8
9
include('libs/handycode.class.php');
// zmienna przechowujaca kod BBcode
// w tym przykładzie pobierana z tablicy $_POST
$sCode = ( isset($_POST['code']) ) ? $_POST['code'] : '';

//tworzymy obiekty
$obj = new handyCode();
// wyświetlamy to co nam zwroci parser
echo $obj -> parse$sCodenull0);

Składnia funkcji parse:
parse( string code, [,string id [, bool cache [, bool rainbow]]])

Co zrobić gdy chcemy zadeklarować własną listę znaczników? Możliwości są dwie - przekazać odpowiednie parametry do konstruktora klasy lub stworzyć własną klasę która rozszerzy handyCode

Przekazanie parametrów do konstruktora

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Ograniczmy liste znaczników na potrzeby chata */

// ladujemy plik z klasą
include('libs/handycode.class.php');

/* jest to bardziej zalecana forma(szybsza)
jednak jeśli komuś jest wygodniej może przesłać znaczniki w postaci tablicy */
$tags='b|u|i|color|url';

// tablica aktywnych parametrow globalnych
$parametrs = Array('id''class''color');

// tablica znaczników których dzieci nie będą parsowane, w naszym przypadku puste
$block null;

//tworzymy obiekt
$obj = new handyCode$tags$parametrs$block);

Rozszerzenie klasy handyCode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* Ograniczmy liste znaczników na potrzeby chata */

// ladujemy plik z klasą
include('libs/handycode.class.php');

// tworzymy klasę pochodną
class BBchat extends handyCode
{
   public function 
__construct()
    {
        
$this -> blockChild null;
        
$this -> AllowedParametrs = Array('id''class''color''size');
        
$this -> AllowedTags 'b|u|i|color|url';
    }
}

// tworzymy obiekt
$obj = new BBchat();
 

Własne znaczniki

Dzięki użyciu drugiej metody możliwe jest w bardzo prosty sposób rozszerzenie listy znaczników. Dodajmy znacznik [manual].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// ladujemy plik z klasą
include('libs/handycode.class.php');

// tworzymy klasę pochodną
class BBchat extends handyCode
{

    protected function 
tag_manual$data$mainParam null$addParams null$styles null$specialParams null )
    {
        
// jesli znacznik wywolany [manual=NAZWAFUNKCJI] (...) [/manual]
        
if($mainParam)
        {
           
/* jesli jednym z parametrow [manual] bedzie id(parametr globalnie dostepny) np. [manual id="OBIEKT"] to zmienna
             $addParam przyjmie wartość: id="OBIEKT". W ten sposob mozemy w łatwy sposób operować stylami css ;)
           */
            
return '<a href="http://pl.php.net/manual/pl/function.'.str_replace('_','-',$mainParam).'.php" '.$addParams.'>'.$data.'()</a>';
        }
        else
        {
            
$data str_replace('()','',$data);
            return 
'<a href="http://pl.php.net/manual/pl/function.'.str_replace('_','-',$data).'.php" '.$addParams.'>'.$data.'()</a>';
        }
    }

   public function 
__construct()
    {
        
$this -> blockChild null;
        
$this -> AllowedParametrs = Array('id''class''color''size');
        
$this -> AllowedTags 'b|u|i|color|url|manual';
    }
}

// tworzymy obiekt
$obj = new BBchat();

Ważne jest aby metoda przetwarzająca dany znacznik miała nazwę tag_NazwaZnacznika i nie była metodą prywatną. W przeciwnym wypadu nie zostanie ona odnaleziona.

Składnia funkcji znacznika:
tag_NazwaZnacznika( string data, [,string mainParam [, string addParams [, string styles[ , array specialParams ]]]])

 

Relacje rodzic - dziecko

Klasa handyCode udostępnia dwa rodzaje operacji działających na zasadzie dziedziczności. Po pierwsze rodzic może zabronić dzieciom parsowania się. Po drugie dziecko może w zależności od posiadanego rodzica zwracać różne wartości.

W poniższym przykładzie dodałem dwa nowe znaczniki - [s] oraz [dziecko]. Pierwszy przekreśla swoją zawartość dodatkowo blokując wszystkie swoje dzieci aby się nie parsowały. Drugi, czyli dziecko pobiera informacje z tablicy $this -> parents na temat swoich przodków i wyświetla odpowiednie komunikaty.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class BBchat extends handyCode
{
    protected function 
tag_s$data$mainParam null$addParams null$styles null$specialParams null )
    {
        return 
'<span style="text-decoration: line-through; '.$styles.'"'.$addParams.'>'.$data.'</span>';
    }

    protected function 
tag_dziecko$data$mainParam null$addParams null$styles null$specialParams null )
    {
        
$rodzic end($this -> parents);
        
$dziadek prev($this -> parents);

        if(
$rodzic)
            return 
'Moim rodzicem jest <b style="color:red">'.$rodzic.'</b>'.(($dziadek) ? ' a dziadkiem'.
            
' <b style="color:red">'.$dziadek.'</b>' '').' a ja krzyczę : <i style="color:red">'.$data.'</i>';
        else
            return 
'Czy ja jestem sierotą? :( ('.$data.')';
    }

    public function 
__construct()
    {
        
// Dodalismy znacznik 's' do tablicy blockChild, każde dziecko tego znacznika nie będzie przetwarzane
        
$this -> blockChild = Array('s' => 1);
        
$this -> AllowedParametrs = Array('id''class''color''size');
        
$this -> AllowedTags 's|dziecko|b|u|i|color|size|url|list|li';
    }
}

Dla przykładowego wejścia:

1
2
3
4
5
[s] [b]znacznik ktory mnie otacza nie zostanie przeparsowany[/b] [/s]

[i] [b] [dziecko]Aaa[/dziecko] [/b][/i]
 [u] [dziecko]Aaaaa[/dziecko] [/u]
[dziecko]Aaaaaaa[/dziecko]

Parser zwróci:

[b]znacznik ktory mnie otacza nie zostanie przeparsowany[/b]

Moim rodzicem jest b a dziadkiem i a ja krzyczę : Aaa
Moim rodzicem jest u a ja krzyczę : Aaaaa
Czy ja jestem sierotą? :( (Aaaaaaa)
 

Autor

Michał "SHiP" Środek
kadu: 4152790
devBlog: http://srodek.info

 

Licencja

Klasa jest w pełni darmowa i może być dowolnie modyfikowana i rozprowadzana. Jedynym warunkiem jest umieszczenie informacji o autorze klasy.

Biblioteka jest darmowa dlatego autor nie ponosi żadnej odpowiedzialności za jakiekolwiek skutki spowodowane złym użytkowaniem(szczególnie wersji pochodnych) oraz nie udziela żadnej gwarancji/pomocy technicznej itp.