Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Smarty + klasy
Forum PHP.pl > Forum > PHP
slimboj
Witam,
Piszę właśnie aplikację z zastosowaniem wzorca MVC i z obsługą smarty i napotkałem pewien problem, z którym nie bardzo jestem w stanie sobie poradzić.
Struktura katalogów i plików wygląda tak:

--ROOT
|
+-controller (frontcontroller.php + inne kontrolery)
+-model
+view (test.tpl)
+libs/smarty
|
-index.php

W pliku index.php mam "include" wszystkich klas z katalogów powyżej (poza view), a także wywołanie klasy FrontController
W pliku frontcontroller.php klasa FrontController dziedziczy po klasie Smarty.
I teraz jeśli napiszę klasę tak:
  1. <?php
  2. class FrontController extends Smarty
  3. {
  4. public function __construct()
  5. {
  6.  $this -> template_dir =  ROOT_PATH."/view/";
  7.  $this -> compile_dir = ROOT_PATH.'/libs/smarty/templates_c/';
  8.  $this -> config_dir = ROOT_PATH.'/libs/smarty/configs/';
  9.  $this -> cache_dir = ROOT_PATH.'/libs/smarty/cache/';
  10.  
  11.  $this -> display('test.tpl')
  12. }
  13. }
  14. ?>


To plik test.tpl zostaje załadowany poprawnie.
Ale chciałbym aby zamiast wpisywania w każdej klasie ścieżek do ładowania smart zastosować jedną klasę, np.

  1. <?php
  2. class LoadSmarty extends Smarty
  3. {
  4. public function __construct()
  5. {
  6.  $this -> template_dir =  ROOT_PATH."/view/";
  7.  $this -> compile_dir = ROOT_PATH.'/libs/smarty/templates_c/';
  8.  $this -> config_dir = ROOT_PATH.'/libs/smarty/configs/';
  9.  $this -> cache_dir = ROOT_PATH.'/libs/smarty/cache/';
  10. }
  11. }
  12. ?>


frontcontroller.php
  1. <?php
  2. class FrontController extends Smarty
  3. {
  4. public function __construct()
  5. {
  6.  $display = new LoadSmarty();
  7.  $display -> display('test.tpl')
  8. }
  9. }
  10. ?>



Problem polega na tym, że jeżeli zastosuję ten sposób to w kontrolerze, który ma wywołać dany template pojawia się komunikat:
Warning: Smarty error: unable to read resource: "test.tpl" in ..//libs/smarty/Smarty.class.php on line 1092

I jeszcze mam pytanie, czy jest jakiś sposób aby obejść ładowanie smarty do każdej klasy z osobna, tylko załadować raz i mieć to z głowy.

P.S. Piszę z "palca" z pracy więc gdzieś w kodzie mogą być błędy.
Zyx
Po pierwsze, krótki kurs języka angielskiego. "Smarty" jest to słowo w liczbie pojedynczej, które po konwersji na język polski zyskuje rodzaj męski. TEN Smarty, a nie jakieś "te smarty". Wybacz, ale naprawdę wkurzające to jest, jak wszyscy tworzą jakieś potworki językowe...

Wracając do tematu, problem leży w tym, że źle wykorzystałeś programowanie obiektowe i wcale nie zbudowałeś wzorca MVC, tylko coś dziwnego. Dlaczego kontrolery dziedziczą po klasie "Smarty"? Przecież zadania jednych i drugich nie są nawet do siebie podobne. Dziedziczenia w tym miejscu nie powinno w ogóle być. Powinieneś mieć jakąś klasę reprezentującą widok i kontroler powinien przechowywać obiekt tej klasy (kompozycja!), zamiast po niej dziedziczyć. Natomiast jak nie duplikować konfiguracji między obiektami widoków... w Smartym jest pewien ból, mianowicie ten system szablonów może i używa klas, ale z programowaniem obiektowym ma to niewiele wspólnego. Tutaj mogę zaproponować kilka rozwiązań:
- Widoki są niezależne od systemu szablonów. Masz jeden globalny obiekt Smarty'ego i w momencie gdy chcesz wyświetlić widok, przepisujesz z niego dane do systemu szablonów.
- Widoki rozszerzają klasę Smarty - konstruktor w tle przepisuje konfigurację z globalnej konfiguracji systemu.
- Zmienić system szablonów na bardziej obiektowy, np. OPT, który jest zaprojektowany właśnie do pracy z wzorcem MVC i domyślnie operuje takimi pojęciami, jak widoki.
slimboj
Cytat(Zyx @ 19.05.2009, 10:40:09 ) *
...Dlaczego kontrolery dziedziczą po klasie "Smarty"?...


To było raczej w ramach testów, żeby sprawdzić czy w ten sposób smarty zostanie dobrze załadowany do klasy.


Mam jeszcze pytanie, gdzie powinienem sprawdzać poprawność danych np. formularza? W kontrolerze, czy w modelu?
Sorki za post po poście, ale nie chciałem zakładać nowego tematu.
pgrzelka
Cytat
Mam jeszcze pytanie, gdzie powinienem sprawdzać poprawność danych np. formularza? W kontrolerze, czy w modelu?
w klasie formularza smile.gif

$formularz = new Formularz();

if ($_SERVER[REQUEST_METHOD==POST && $formularz -> isValid()) {
// dodanie do bazy, itp
} else {
echo $formularz->pokaz();
}

jeśli dane pochodzą z posta to funkcja isValid przypisuje zmienne do pól formularza, sprawdza czy są one poprawne i odpowiednio oznacza,
jeśli wszystko jest ok to np dodajesz do bazy, jeśli nie to pokazujesz formularz, i przy pokazywaniu albo pokazujesz z błędami albo 'czysty'
mniej więcej tak to jest rozwiązane w zend frameworku
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.