Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Szablony a'la ZF
Forum PHP.pl > Forum > PHP > Object-oriented programming
kicaj
Jak wykonywane sa szablony w ZendFramework?
Plik szablonu (.phtml):
  1. <html>
  2. <head></head>
  3. <body><?php echo $this -> text; ?></body>
  4. </html>


Plik kontrolera:
  1. <?php
  2. class NazwaController
  3. {
  4. function IndexAction()
  5. {
  6. $this -> view -> text = 'Napis';
  7. }
  8. }
  9. ?>


Jak to sie odbywa, jak w pliku .phtml odbierana jest wartosc 'text'?
Probowalem przegladac Zend_View ale nie moglem dojsc do tego...
mike
Podejrzewam, że wykorzystane są do tego wszystkie metody magiczne. Przede wszystkim __get() i __set().
Szukaj pod tym kątem. Podobnie jets w symfony.
kicaj
Dokladnie to nie o to chodzilo mi...
Wykorzystanie metod magicznych sam dotychczas uzywalem, bardziej mi chodzi o to w jaki sposob pobierany (file, file_get_contents?) jest plik szablonu (sciezka tworzy sie z: kontroler/akcja) i jak w pliku szablonu odczytywane sa te wartosci?
Nie wiem czy wyrazilem sie jasno:/
LBO
zwykły include

edit:

Proszę, wszystko jest w metodzie Zend_View::_run()
kicaj
Mam w sumie problem jak zrobic cos a`la Zend_View

1. W wywolanym kontrolerze ustawiam zmienne:
  1. <?php
  2. class NewsController
  3. {
  4. function IndexAction()
  5. {
  6. $this -> view -> title = 'Tytul news';
  7. }
  8.  
  9. function OtherAction()
  10. {
  11. $this -> view -> something = array( 0, 1, 2, 3, 4 );
  12. }
  13. }
  14. ?>


Pliki szablonow:
  1. <hr />
  2. Tytul: <b><?php echo $this -> view; ?></b>
  3. <hr />


Chcialbym uruchamiac to w sposob taki:
  1. <?php
  2. $o = new NewsController; 
  3. $o -> IndexAction(); // zapelnianie zmiennych trescia
  4.  
  5. echo Controller::Dispatch(); // wyswietlanie spreparowanej strony z wypelniona trescia
  6. ?>


Mam problem jak to wszystko polaczyc ze soba, zeby zgrabnie dzialalo
jang
Ja mam tak:
index.php :
  1. <?php
  2. $objFront = new CCC_Controller_Front;
  3. $objFront->dispatch();
  4. ?>

FrontController :
  1. <?php
  2. public function dispatch()
  3. {
  4. $this->objRouter = new CCC_Router($this->objInput, $this->objConfig);
  5. CCC::registrySet('router', $this->objRouter);
  6.  
  7. $this->objView = new CCC_View;
  8. CCC::registrySet('view', $this->objView);
  9.  
  10.  
  11. $controller = strtolower($this->objRouter->getController());
  12. $action = strtolower($this->objRouter->getAction());
  13. $this->perform($controller, $action);
  14. }
  15.  
  16. public function perform($controller, $action)
  17. {
  18. $objController = new $controller($this);
  19. $objController->$action();
  20. }
  21. ?>

Kontroller akcji :
  1. <?php
  2. class CCC_Controller_Action
  3. {
  4. function __construct($objFront)
  5. {
  6. $this->objFront = $objFront;
  7. $this->objView = $this->objFront->getView();
  8. $this->objInput = $this->objFront->getInput();
  9.  
  10. $this->init();
  11. }
  12.  
  13.  
  14. public function init()
  15. {
  16. }
  17.  
  18. }
  19. ?>

  1. <?php
  2. class CCC_View
  3. {
  4. /**
  5.  * string $fileName Nazwa pliku PHP który znajduje się w katalogu /app/views
  6.  * bez rozszeżenia (.php)
  7.  * np. $this->view->display('welcome_message');  
  8.  */  
  9. final public function display($fileName = null)
  10. {
  11. if(null === $fileName)
  12. throw new Exception ('Klasa CCC_View::display($fileName = null) : $fileName musi być podane');
  13.  
  14. $filePath = DIR_APP.'views/'.$fileName.'.php';
  15.  
  16. if(!is_readable($filePath))
  17. throw new Exception ('Klasa CCC_View::display($fileName = null) : Nie ma pliku '.$filePath);
  18.  
  19. include ($filePath);
  20. $sContents = ob_get_clean();
  21. return $sContents;
  22. }
  23.  
  24.  
  25. } // end : class CCC_View
  26. ?>

Akcja :
  1. <?php
  2. class IndexController extends CCC_Controller_Action
  3. {
  4.  
  5. public function init()
  6. {
  7. $this->objView->basePath = $this->objInput->getBasePath();
  8. $this->objView->baseUrl = $this->objInput->getBaseUrl();
  9. $this->objView->router = $this->objFront->getRouter();
  10. }
  11.  
  12.  
  13. public function IndexAction()
  14. {
  15. $this->objView->title = 'Welcome';
  16. $site = $this->objView->display('index/index');
  17. echo $site;
  18. }
  19. ?>

tpl :
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  6. <title><?php echo htmlentities($this->title, ENT_QUOTES, 'utf-8'); ?></title>
  7. <link rel="stylesheet" type="text/css" media="screen" 
  8. href="<?php echo $this->basePath ?>/public/styles/skidoo_too.css" />
  9. </head>
  10.  
  11. <body>
  12. <div id="pageWrapper">
  13. <div id="masthead" class="inside">
  14. <img src="<?php echo $this->basePath ?>/public/images/CCC_nag_brown.gif" alt="Cash City">
  15. <hr class="hide">
  16. </div>
  17. <div class="hnav">
  18. <ul>
  19.  <li><a href="<?php echo $this->router->createURL(); ?>">Home</a></li
  20. ><li><a href="<?php echo $this->router->createURL('index', 'server'); ?>">Dane servera</a></li

W tpl nie tak jak Ty napisałeś
  1. Tytul: <b><?php echo $this -> view; ?></b>

tylko :
  1. Tytul: <b><?php echo $this -> title; ?></b>

a tablice albo foreach albo $array[0]

Pozdrawiam
kicaj
Ooo dzieki o wlasnie takie nakreslenie chcialem "uslyszec", mam kilka zastrzezen:

1. Zmien CCC_Controller_Action na abstrakcje:
  1. <?php
  2. abstract class Controller
  3. {
  4. protected $view;
  5.  
  6. function __construct()
  7. {
  8. // ...
  9.  
  10. $this -> init();
  11. }
  12.  
  13. abstract function init();
  14. abstract function IndexAction(); // podstawowa akcja
  15. }
  16. ?>


2. Zastanawiam sie jak najciekawiej wyeliminowac powtarzane liniki w metodach kontrolera:
$site = $this->objView->display('index/index');

  1. <?php
  2. class ViewHelper
  3. {
  4. final public function Display( $strFileName )
  5. {
  6. include( $strFileName );
  7. }
  8.  
  9. final public function __destruct()
  10. {
  11. return $this -> Display( 'nazwa_wywolanej_akcji' ); // automactyczne przypisanie do $nazwa_...
  12. }
  13. }
  14. ?>

Probowalem z debug_backtrace() ale nie zwraca mi nic ciekawego...
jang
  1. <?php
  2. abstract function IndexAction(); // podstawowa akcja
  3. ?>

To akurat bez sensu, u mnie w każdym kontrollerze akcja Index robi coś innego, a jeśli chodzi Ci o wywołanie to robi to Router (jeśli nie jest podana akcja to Router zwraca index)
  1. <?php
  2. final public function __destruct()
  3. {
  4. $con = $this->router->getController();
  5. $akc = $this->router->getAction();
  6. return $this -> Display(DIR_APP. '/views/'."$con/$akc".'.php' ); // automactyczne przypisanie do $nazwa_...
  7. }
  8. ?>

$con - to nazwa podkatalogu w views a jednocześnie nazwa wywoływanego przez Router kontrollera
$akc - to nazwa tpl w /views/$akc/ a jednocześnie nazwa wywoływanej akcji
kicaj
1. oznaczenie metody jako abstrakcyjnej nie definiuje ciala, lecz tylko wymaga na dziedziczonej klasie istnienia danej metody
2. W sumie to podobnie rozwiazalem:)

Dzieki wielkie za nakreslenie...
LBO
Cytat(kicaj @ 25.10.2007, 22:32:49 ) *
1. oznaczenie metody jako abstrakcyjnej nie definiuje ciala, lecz tylko wymaga na dziedziczonej klasie istnienia danej metody


I w ten sposób ograniczyłeś elastyczność Zend Framework'a. Domyślną akcję (index) można w prosty sposób zmienić na dowolnie inną
Kod
Zend_Controller_Front::setDefaultAction()


edit: Sorry, nie doczytałem za dokładnie, że robisz coś własnego. Tak czy siak Zendowe rozwiązanie jest multielastyczne.
jang
ad 2. Nie mam tak rozwiązane, ale wymyśliłem to dla Ciebie.

ad 1. Chyba coś Ci się pomyliło z interfejsem. Jeśli utworzysz pustą metodę abstrakcyjną to dostaniesz coś takiego : Fatal error: Abstract function CCC_Controller_Action::init() cannot contain body in /var/www/jg_8/lib/CCC/Controller/Action.php on line 17 ohmy.gif

edit : i to samo oczywiście będzie z abstract function IndexAction(); // podstawowa akcja
LBO
Cytat(jang @ 25.10.2007, 23:41:59 ) *
ad 1. Chyba coś Ci się pomyliło z interfejsem. Jeśli utworzysz pustą metodę abstrakcyjną to dostaniesz coś takiego : Fatal error: Abstract function CCC_Controller_Action::init() cannot contain body in /var/www/jg_8/lib/CCC/Controller/Action.php on line 17 ohmy.gif


Wiesz co napisałeś w ogóle? Metoda abstrakcyjna musi być pusta i o tym informuje treść błędu.
kicaj
@jang: Tworzac klase abstrakcyjna z metodami abstrakcyjnymi (czytaj: bez ciala metody) wymuszasz istnienie tych metod w klasie potomka...
jang
  1. <?php
  2. abstract class CCC_Controller_Action
  3. {
  4. public function __construct($objFront)
  5. {
  6. $this->objFront = $objFront;
  7. $this->objView = $this->objFront->getView();
  8. $this->objInput = $this->objFront->getInput();
  9.  
  10. $this->init();
  11. }
  12.  
  13.  
  14. abstract function init()
  15. {
  16. }
  17. }
  18. ?>

  1. <?php
  2. class IndexController extends CCC_Controller_Action
  3. {
  4.  
  5. public function init()
  6. {
  7. $this->objView->basePath = $this->objInput->getBasePath();
  8. $this->objView->baseUrl = $this->objInput->getBaseUrl();
  9. $this->objView->router = $this->objFront->getRouter();
  10. }
  11. ?>
To w takim razie skąd ten błąd ?
LBO
Stąd:
Kod
abstract function init()
{
}

To powinno wyglądać tak:
Kod
abstract function init();
jang
Faktycznie, o tym zapomniałem. Dzięki za przypomnienie, ale i tak pozostanę przy moim rozwiązaniu - bez abstract. Na pewno trafią się kontrollery w których metoda init() nie będzie mi potrzebna. Pewnie też dlatego w Zend tak też to zrobili.
envp
Panowie, od tego są interfajsy smile.gif

Btw. mamy w Rapide identyczny system szablonów (jeśli można to nazwać szablonem, bo webmaster ma tu dostęp do silnika php) - jest on najszybszy z obecnie znanych...
Strzałek
Cyk, o to chodzi. Najprostsza implementacja: http://forum.php.pl/index.php?showtopic=42897 jeżeli potrzebujesz czegoś więcej - patrz Savant.
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.