Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> MVC - stałe elementy strony
anas
post
Post #1





Grupa: Zarejestrowani
Postów: 172
Pomógł: 0
Dołączył: 22.09.2002
Skąd: Gorzów Wlkp

Ostrzeżenie: (0%)
-----


Witam.

Po raz kolejny pytanie dotyczące MVC - tym razem chodzi mi o fakt kiedy na stronie mamy jakieś stałe elementy - czy każdy widok musi je generować z osobna i za każdym razem uzywajac systmu szablonów przypisywać jakieś wartości dla nagłówka, stopki, stałego menu - itd itd.

Tak naprawdę akcje decydują u mnie o tym co się wyświetla w głównej części serwisu i chciałbym żeby stałe elementy były wyświetlane wyłącznie w jednym pliku, a takze uruchamiany kontroler ktory zdecyduje co wygenerowac dla glownej czesci serwisu.

Czy to ma prawo bytu? Jezeli nie - jak najlatwiej rozwiazac ten problem - licze na wasze jak zawsze dobre pomysly.

pozdrowka

anas
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 19)
bregovic
post
Post #2





Grupa: Zarejestrowani
Postów: 562
Pomógł: 15
Dołączył: 8.08.2003
Skąd: Denmark/Odense

Ostrzeżenie: (0%)
-----


Nie do końca rozumiem o co tobie chodzi, lecz możesz zawsze użyć cachoe'owania - jeśli używasz Smarty możesz z powodzeniem cachoe'ować tylko niektóre elementy template'ów.


--------------------
Prank - for the fun. Mac - for the simplicity. Deviantart - for the kick.
Life is ours, We live it our way -- Metallica
Go to the top of the page
+Quote Post
anas
post
Post #3





Grupa: Zarejestrowani
Postów: 172
Pomógł: 0
Dołączył: 22.09.2002
Skąd: Gorzów Wlkp

Ostrzeżenie: (0%)
-----


Hej.

Co do cashowania to jasna sprawa - chodzi mi raczej o fakt iż mam serwis www, a w nim naglowek, stopke, menu z lewej strony - ktorej na kazdej podstronie wygladaja tak samo - zmienia sie czesc glowna serwisu(srodek) - tym ma zarzadzac wlasnie moja aplikacja oparta o MVC - ale nie chce tez rozdzielac jednego od drugiego - to co chcialbym osiagnac to taki defaultowy widok do ktorego dolaczane bylyby widoki wywolywane przez jakies tam akcje. A pytanie moje brzmi jak to zrobic - bo sama idee mam - gozej z implementacja... nie wiem od ktorej strony sie do tego zabrac.

pozdrawiam

anas
Go to the top of the page
+Quote Post
bregovic
post
Post #4





Grupa: Zarejestrowani
Postów: 562
Pomógł: 15
Dołączył: 8.08.2003
Skąd: Denmark/Odense

Ostrzeżenie: (0%)
-----


To czego chcesz przypomina zalążek mojego frameworka - zakładając że używasz Smarty, robisz sobie jednego template'a - nazwijmy go index.tpl.
I teraz robisz tak, że w każdej akcji definiujesz zmienną template'ową "page" - używając:
  1. <?php
  2.  $objSmarty->assign('page', 'id-strony-do-wyswietlenia');
  3. ?>

A w templacie, na początku:
  1. {include file="$page.tpl" assign="zawartosc-templatu-podstrony"}

Dalej w templacie, już po zdefinowaniu headera, menu, itp, wyświetlasz zainkludowany środek strony, pisząc:
  1. {$zawartosc-templatu-podstrony}


--------------------
Prank - for the fun. Mac - for the simplicity. Deviantart - for the kick.
Life is ours, We live it our way -- Metallica
Go to the top of the page
+Quote Post
aleksander
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


ja mam w plikui konfiguracyjnym sekcje preLoadingActions i postLoadingActions które zawierają nazwy akcji które mają być wykonane przed wywołaniem właściwej akcji i po.
Go to the top of the page
+Quote Post
bregovic
post
Post #6





Grupa: Zarejestrowani
Postów: 562
Pomógł: 15
Dołączył: 8.08.2003
Skąd: Denmark/Odense

Ostrzeżenie: (0%)
-----


olo twoje rozwiązanie też jest jeśli reszta strony ma być niestatyczna. Można w sumie też mieć akcję bazową, w której wykonujemy wszystkie czynności które mają zostać wykonane na każdej stronie, a wszystkie inne akcje extend'ują od niej.


--------------------
Prank - for the fun. Mac - for the simplicity. Deviantart - for the kick.
Life is ours, We live it our way -- Metallica
Go to the top of the page
+Quote Post
anas
post
Post #7





Grupa: Zarejestrowani
Postów: 172
Pomógł: 0
Dołączył: 22.09.2002
Skąd: Gorzów Wlkp

Ostrzeżenie: (0%)
-----


@bregovic - tak tez zrobilem - popatrzylem i w phiend jest to rozwiazane wlasnie tak jak mowiles - klasa akcji bazowej, a po niej dziedzicznone pozostale klasy... sprytne rozwiazanie.

@olo - tez nieglupi pomysl - tylko martwi mnie fakt iz zmuszasz aplikacje do wywolanie czegos na stale - chociaz jak kto woli

Ps. a jak sie ma sprawa wydajnosci - moze testowaliscie co dziala szybciej - dziedziczenie po akcji bazowej czy taka sama akcja ktora ma przedakcje i akcje wywolywane po czesci glownej.

pozdrowka

anas
Go to the top of the page
+Quote Post
aleksander
post
Post #8





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


albo można zrobić tak: dla każdej akcji masz zdefiniowane kiedy ma być odpanala (jaki argument GET ma być) i robisz tam always - czyli zawsze. tylko nie wiem za bardzo jak zdefiniować kolejność wyświetlania poszczególnych elementów.
Go to the top of the page
+Quote Post
bela
post
Post #9


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


Cytat(olo @ 2004-12-29 16:08:14)
tylko nie wiem za bardzo jak zdefiniować kolejność wyświetlania poszczególnych elementów.

moze na chama smile.gif zserializowac tablice i do sesji wrzucic


--------------------
Go to the top of the page
+Quote Post
DeyV
post
Post #10





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




ja standardowo wykorzystuję dziedziczenie po róznych rodzajach akcji.
Jest to bardzo przydatne, bo można np. tylko raz zdefiniować, co ma być wykonywane na np. stronie z wydrukiem, (np. nie drukuje menu, wiec nie muszę go generować)

Następnie wszystkie akcje związane z wydrukiem dziedziczą po tejże, i odpowiednio ją rozszeżają.

Czasem można ten proces skomplikowac jeszcze bardziej. Jakiś przykład?
Sonda wyświetlana jest na głownej stronie, gdzie jest menu boczne i górne. Nie ma jednak innych dynamicznych elementów.
dziedziczy wiec po abstrakcyjnej pseudo akcji "strona głowna" "wyłączają" w niej pewne bloki.
A teraz pojawia się akcja OddajGłos ... Wyświetlana oczywiście w takim samym "środowskiu" . Wystarczy więc dziedziczyć z sondy, dodając tylko odpowiednie mechanizmy.

Oczywiśćie konieczna jest bardzo duża ostrożność, by nie zgbubić się w tych związkach, ale w wielu przypadkach może to znacznie ułatwić życie.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
anas
post
Post #11





Grupa: Zarejestrowani
Postów: 172
Pomógł: 0
Dołączył: 22.09.2002
Skąd: Gorzów Wlkp

Ostrzeżenie: (0%)
-----


@DeyV:
Tak tez to rozwiazuje - wlasnie sie tym zajalem i all dziala jak nalezy - jak dla mnie najbardziej przejrzysty i sprawdzony sposob smile.gif

Thx za tyle ciekawych propozycji... ide dalej meczyc klawiature.

pozdrowka

anas

Ten post edytował anas 29.12.2004, 16:40:46
Go to the top of the page
+Quote Post
aleksander
post
Post #12





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


DeyV: możesz to pokazać na jakimś prostym przykładzie bo próbuję, ale nie mogę skumać smile.gif Tzn mniej więcej kumam ale jakoś nie mogę wpaść jak to elegancko rozwiązać - same badziewiacke rozwiązania przychodzą na myśl... za dużo tej marychy... smile.gif
Go to the top of the page
+Quote Post
splatch
post
Post #13





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Pozwolę sobie przedstawić moje rozwiązanie.
Moja koncepcja była bardzo prosta, mianowicie są elementy strony, które mogą się zmieniać (np. pojawiające się menu dostępne tylko dla zalogowanych osób ). Jako, że korzystam jak narazie tyko ze zwykłego widoku html obsługiwanego przez smarty dodałem tablicę zawierającą pliki do wywołania pod koniec tworzenia strony.
Przykładowy blok:
  1. <?php
  2. class LoginForm
  3. {
  4. function LoginForm( ) { }
  5. function run( ) {
  6. $reg = &Registry::instance( );
  7. $view = &$reg->load( 'view' );
  8. $io = &IO::instance( );
  9. if( $io->getSession( 'user_id' ) > 0 ) { //zalogowany
  10. $model = Init::model( 'user_model' );
  11. $data = $model->getUserById( $io->getSession( 'user_id' ) );
  12. $view->assign( 'username', $data['login'] );
  13. $view->assign( 'login_form', $view->fetch( 'logined.tpl' ) );
  14. } else { //gość
  15. $view->assign( 'login_form', $view->fetch( 'login_form.tpl' ) );
  16. }
  17.  
  18. }
  19.  
  20. }
  21.  
  22. ?>

Oczywiście można łatwo dodać kolejne elementy do szablonu i jeśli użytkownik jesst zalogowany wyświetlać.
Klasa widoku:
  1. <?php
  2. class SmartyView {
  3. var $smarty;
  4. var $autoLoadBlocks = array( );
  5.  
  6. function SmartyView( ) {
  7. $reg = &Registry::instance( );
  8. $config = $reg->load( 'viewconfig' ); // ładuję ustawienia z rejestru
  9.  
  10. $this->autoLoadBlocks = $config['autoload']; // domyślne bloki
  11. unset( $config['name'], $config['autoload'] );
  12.  
  13. include_once DOCUMENT_ROOT .'libs/smarty/Smarty.class.php';
  14. $this->smarty = new Smarty; //tworze obiekt
  15.  
  16. foreach( $config as $key => $value ) { // ustawienia konfiguracyjne
  17. $this->smarty->$key = $value;
  18. }
  19. $reg->save( 'view', $this ); //zapisuje widok w rejestrze
  20. }
  21.  
  22. function autoLoad( ) {
  23. foreach( $this->autoLoadBlocks as $id => $name ){
  24. $block = Init::block( $name );
  25. if( $action !== false ){
  26. $block->run( );
  27. }
  28. }
  29. }
  30.  
  31. #inne metody
  32.  
  33. function assign( $key, $value ) {
  34. $this->smarty->assign( $key, $value );
  35. }
  36.  
  37. function fetch( $tpl ) {
  38. return $this->smarty->fetch( $tpl );
  39. }
  40.  
  41. function display( $tpl = null ) {
  42. if( $tpl === null ) {
  43. $this->autoLoad( );
  44. $this->smarty->display( 'home.tpl' );
  45. } else {
  46. if( sizeof( $this->autoLoadBlocks ) > 0 ) { // są jakieś bloki
  47. $this->autoLoad( );
  48. }
  49. $this->smarty->display( $tpl );
  50. }
  51. }
  52. }
  53.  
  54. ?>

Wycinek z pliku config.php
  1. <?php
  2. $viewconfig['smarty']['name'] = &#092;"smarty\";
  3. $viewconfig['smarty']['template_dir'] = &#092;"templates/\";
  4. $viewconfig['smarty']['compile_dir'] = &#092;"compiled/\";
  5. $viewconfig['smarty']['config_dir'] = &#092;"tpl/config\";
  6. $viewconfig['smarty']['debugging'] = false;
  7. $viewconfig['smarty']['compile_check'] = true;
  8.  
  9. //bloki ktore beda automatycznie ladowane
  10. $viewconfig['smarty']['autoload'] = 
  11. 'Menu', 'News', 'Hello', 'auction_box', 'login_form'
  12. );
  13. ?>

W zależności od potrzeb akcja może usuwać lub dodawać nowe elementy blokowe. Jeśli serwis jest pod sporym obciążeniem to wtedy można włączyć buforowanie. Myślę, że takie rozwiązanie jest bardzo elastyczne i umożliwia tworzenie nawet bardzo złożonych bloków.


--------------------
Łukasz Dywicki
Independent Java and open source software consultant.
Blog - Java, OSGi, integracja oprogramowania..
Go to the top of the page
+Quote Post
aleksander
post
Post #14





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


buuuu ;( glowie sie i glowie i nie wiem jak wyglowic.
chce, zeby ustawienia jaki akcje uruchamiac przed i po właściwej akcja byly zapisane w konfiguracji frameworka (czyli plik xml). Chcialbym, zeby to bylo w miare elastycznie, wymyslilem takie sposoby:
  1. <action type="alwaysPre" showId="1"> <!-- showId ustala kolejnosc wyswietlania. wszystko musi byc elastyczne! -->
  2.      <name>main</name>
  3.      <requiredRoles></requireRoles>
  4.      <type>view</type>
  5.      <matches>main</matches>
  6.    </action>
  7.  
  8. <action>
  9.      <name>main</name>
  10.      <requiredRoles></requireRoles>
  11.      <type>view</type>
  12.      <matches>_alwaysPre1</matches> <!-- cyferka oznalcza kolejnosc wyswietlania -->
  13.    </action>
  14.  
  15. <action>
  16.      <name>main</name>
  17.      <requiredRoles></requireRoles>
  18.      <type>view</type>
  19.      <always where="pre" showId="1" />
  20.    </action>
Jednak te wszystkie pomysły wydają się jakieś nie tego teges smile.gif Any suggestions?
Go to the top of the page
+Quote Post
bela
post
Post #15


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


może wzorzec Intercepting Filter biggrin.gif


--------------------
Go to the top of the page
+Quote Post
aleksander
post
Post #16





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


taa juz bo mi to cos mowi biggrin.gif

swoja droga przed chwila zdalem sobie sprawe ze popelniam blad. W koncu za wyglad odpowiada warstwa widoku, a ja probuje to rozwiazac w warstwie kontrolera.

Ok zrobilem cos takiego:
  1. <?php
  2. abstract class StronaGlowna
  3. {
  4. protected function runPreActions()
  5. {
  6. //tutaj odpalamy akcje, ktore powinny byc wyswietlone przed wlasciwa akcja (np header, menu, sonda)
  7. }
  8.  
  9. abstract protected function Action(); // akzja bazowa czyli to co wywolujemy
  10.  
  11. protected function runPostActions()
  12. {
  13. // tutaj odpalamy akcje, ktore powinny byc wyswietlone po wlasciwej akcji (typu stopki albo menu z prawej)
  14. }
  15.  
  16. public function Run() // metoda wywolywana przez kontroler
  17. {
  18. $this->runPreActions();
  19. $this->Action();
  20. $this->runPostActions();
  21. }
  22. }
  23.  
  24. class someView extends StronaGlowna implements Action
  25. {
  26. protected function Action()
  27. {
  28. // tutaj zapisujemy wlasciwa akcje
  29. }
  30. }
  31.  
  32. // dorzucam jeszcze interfejs Action (b. prosty)
  33. interface Action
  34. {
  35. public function Run();
  36. }
  37.  
  38. // akcje wywolujemy poprzez
  39. $objAction = new someView();
  40. $objAction->Run();
  41. ?>
DeyVowi chyba o to chodzilo nie?

Ten post edytował olo 3.01.2005, 16:00:27
Go to the top of the page
+Quote Post
hawk
post
Post #17





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

Ostrzeżenie: (0%)
-----


Uhm, IMHO nie. DeyV mówił o dziedziczeniu z akcji bazowych, które zawierają kod wyświetlający np. menu. Nie o dziedziczeniu z akcji, które wywołują inne akcje.

Chociaż to drugie też jest możliwe i sensowne. Trzeba jakoś zapanować nad tym, które akcje wymagają wywołania przed/po jakiś innych akcji. To można zrealizować właśnie przez dziedziczenie ze wspólnej akcji bazowej, która zawiera implementację runPreActions i runPostActions.

Oczywiście, to wszystko ma sens przy założeniu, że widok jest typem akcji, i że możemy wywoływać kilka akcji jedna po drugiej. A obie te rzeczy nie są standardowe i nie każdy framework musi to umożliwiać. No ale jak widać są przydatne... tylko w tym momencie to co nazywamy "akcją" staje się coraz mniej akcją w sensie MVC, a raczej, hmm, jednostką kodu/pracy. No problem, tylko można się zakręcić w dyskusji z ortodoksyjnymi znawcami MVC.

PS Ja miałem kiedyś inny sposób, chyba lepszy niż dziedziczenie, bo elastyczny, ale nie pasujący do starej wersji phienda:
W konfiguracji akcji przydałby się dodatkowa informacja: "layout". Taki layout to byłaby klasa, która wyświetlałaby wszystkie stałe elementy, a w środku wynik działania akcji-widoku.
  1. <?php
  2. class View {
  3. public function run() {
  4. //pobierz layout z konfiguracji
  5. $layout->run($this);
  6. }
  7.  
  8. public function display() {
  9. //tutaj wyświetlamy zawartość
  10. }
  11. }
  12.  
  13. class Layout {
  14. public function run($view) {
  15. //wyświetl header
  16. $view->display();
  17. //wyświetl footer
  18. }
  19. }?>

Layouty można zmieniać, można dziedziczyć, itd.
Go to the top of the page
+Quote Post
aleksander
post
Post #18





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


no jasne, na pewno te sztuczki z MVC zgodne nie są, tyle że moim TODO jest zrobienie frameworka, który będzie podwalinami do dowolnego portalu.

BTW w tym co mowil DeyV trzeba zauwarzyć, że to menu w akcji bazowej jest po prostu kodem html a u mnie to miejsce ma zająć kolejna akcja.
Go to the top of the page
+Quote Post
DeyV
post
Post #19





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Z tym ostatnim stwierdzeniem nie mogę się zgodzić.
To "menu" to jakiś dowolnie generowany fragment kodu strony.
W takiej sytuacji potrzebny jest jakiś kod, który pozwoli na pobranie tych danych i przesłanie ich do szablonu.
I tu pojawia się konieczność wydzielenia samodzielnego działu w kodzie - zestawu klas o podobnych możliwościach jak akcje (np. korzystanie z modelu) jednak nie odpalane przez router, a przez zainteresowane nimi konkretne akcje.
Pozwala to na uproszczenie kodu tej akcji bazowej, a zarazem na prostą, modularna obsługe pozostałych elementów.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
Jarod
post
Post #20





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(anas @ 29.12.2004, 16:40:07 ) *
@DeyV:
Tak tez to rozwiazuje - wlasnie sie tym zajalem i all dziala jak nalezy - jak dla mnie najbardziej przejrzysty i sprawdzony sposob smile.gif


Możecie wyjaśnić o co chodzi z tą akcją bazową?

Czy to coś w tylu: tworzę sobie akcje BaseAction, która np. zawiera metodę compose(). Metoda compose() odpowiedzialna jest za wygenerowanie nagłówka, menu i stopki. A pozostałe akcje generujące zawartość contentu (środka) dziedziczą po BaseAction?

Jeśli tak to jak rozwiązać problem kolejności ładowania poszczególnych sekcji: nagłówek, menu, stopka? A co jeśli zawartość menu zależy od uprawnień które posiada zalogowany użytkownik? Nie mogę sobie jakoś tego wyobrazić? Może jakiś kodzik?


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 16:25