Nowy system szablonów w uniBoard

Witajcie!

Po długiej przerwie wkońcu pojawił się odpowiedni materiał na nowy wpis. Ponownie bedzie on poświęcony systemowi szablonów uniBoard ;)

Bardziej zainteresowani moim blogiem czytelnicy zapewne pamiętają, że w uniBoard templaty były parsowane w locie. Bardzo zachwalałem ten system, lecz miał on dwie istotne wady.  Parsowane klucze działały, jeśli zostały zapisane w odpowiedniej kolejności, inaczej parser głupiał.  Oprócz tego parser templat potrzebował trochę pamięci aby działać (liczba ta zaczynała się od 100kb i dobiegała do 10mb), co było absolutnie nie do zaakceptowania zwłaszcza, że chciałbym aby mój skrypt przeważnie mieścił się w 4mb ram, zaś gdy trzeba wykonać więcej operacji, i tak nie przekraczał 8mb. Ale to wymagało czegoś wiecej niż poprawek w istniejącym kodzie.

Tak, od tygodnia piszę uniBoard od nowa. Engine który poprzednio potrzebował 6mb aby wyświetlić nagłówek i stopkę, teraz robi to samo nie przekraczając 1mb.  Spadły również czasy generowania strony, co docenia ludzie z wolniejszymi hostami. Ale najwieksza zmiana dotyczy właśnie szablonów.

Jak było?

Poprzednio w uniBoard gdy jakiś szablon był potrzebny, prosiło się obiekt $style aby ten załadował grupę do której on należał. Następnie tworzyło się instancję klasy api_get_template, w konstruktorze zawierającej id szablonu. Potem wrzucało się mu kilka zmiennych metodą „registerValue()”, i parsowało przez „drawTemplate()”.

Jak jest?

Całkiem podobnie. Gdy potrzebujesz jakiegoś szablonu, prosisz obiekt $style, o wskaźnik na grupę. Ten ładuje szablon, lub też tylko zwraca wskaźnik na obiekt. I tutaj zasadnicza różnica. O ile poprzednio obiekt tworzyło się „na miejscu”, o tyle teraz wszystkie szablony są pierw „kompilowane” do obiektów php, i w takiej formie ładowane do kodu. Ma to dwie zalety. Po pierwsze, odpada parsowanie surowego tekstu za każdym razem gdy wyświetlamy szablon. Po drugie, jeśli szablon jest dobrze napisany, nie musimy się martwic o kolejność parsowania elementów, całą robotę odwala za nas parser php. No i po trzecie, szablony cachowane są już w formie funkcjonalnej, do której wystarczy już tylko wrzucić dane.

Trzeba jednak pamiętać że kompilator szablonów jest leniwy. Szablony budowane są tylko w określonych momentach:

  1. Utworzenie nowego szablonu
  2. Wykonanie edycji szablonu
  3. Reczne przebudowanie cache stylu przez ACP
  4. W ostatnim etapie instalacji

Jeśli dokonasz zmien w szablonie bezpośrednio w DB, ale nie wykonasz przebudowy cache w ACP, skrypt dalej będzie używać przestarzałych szablonów, bądź raczyć twoich użytkowników błędęm krytycznym.

<uni[$hello_world]/>

Ostatnią zmianą w szablonach uniBoard są tagi. Tagi to specjalne słowa-klucze, które podczas kompilacji zamieniane są na specjalne odpowiedniki. O ile poprzednio parser doszukiwał się tagów wszędzie gdzie mógł, o tyle kompilator nie jest już taki chętny do zgadywania, co autor templaty miał namyśli umieszczając gdzieś jakiś tag.  Zamiast tego kompilator odróżnia surowy html od tego co ma być skompilowane w taki sam sposób jak parser (np.) php.

Zasada jest prosta. Pierw w szablonie wyszukiwany jest kod który ma zostać skompilowany. Kod ten jest rozpoznawany właśnie wtedy, kiedy znajduje się między <uni[ a ]/>. Następnie następuje sprawdzenie, czy w tagu znajduje się struktura warunkowa, zwykła zmienna, czy funkcja(e).  W zależności od sprawdzenia, zawartość tagu zostanie skompilowana inaczej. Jeśli tag zawiera tylko jakąś wartość, zostanie ona zastąpiona kodem php odpowiedzialnym za jej zwrócenie. Jeśli instrukcję warunkową, ta zostanie zastąpiona odpowiednią pętlą, zaś warunek zostanie przepisany tak, aby działał i niezawierał nieporządanego kodu. Gdy zostanie napotkany blok zawierający funkcje, te zostąną przetłumaczone na odpowiadający im kod php. Z różnych względów, zdecydowałem się nie implementować obsługi funkcji do warunków. I tak do niczego by się w nich nie przydały.

Porównanie

Na zakończenie zademonstruję dwa fragemnty kodu, demonstrujące wykorzystanie templat kiedyś, i dziś:


$this -> style -> loadTemplatesGroup( 'some_templates');
$template = new api_get_template( 'template_id');
$template -> registerValue( 'var_a', 3.14);
$template -> registerValue( 'var_boing_boing', 'Want to register?');
$this -> output -> addToOutput( $template -> drawTemplate());

I nowy kod:


$template = $this -> unisolutions -> style -> loadTemplate( 'some_templates');
echo $template -> template_template_id( array(
var_a' => 3.14,
'var_boing_boing' => 'Want to register?'
));
$this -> output -> drawFullOutput(); //metoda wykonywana na końcu generowania html przez akcję

Leave a comment

2 Comments.

  1. No to się postarałeś :) Martwi mnie jednak fakt iż

    >od tygodnia piszę uniBoard od nowa

    Ja tu sobie już dosyć długo siedzę z wiedzą o uB ale nie jestem pewien czy to na pewno tydzień xD

    No ale wykonałeś kawał dobrej roboty i dużo jeszcze zrobisz.

    Powodzenia, Pozdrawiam.

  2. Od tygodnia piszę nowy engine uniBoard.

    Zaś część akcji zostanie napisana od 0, a część tylko pozmieniana, aby była zgodna z nowym engine.

Leave a Reply


[ Ctrl + Enter ]