2
0

quickstart-create-layout.xml 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 20977 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="learning.quickstart.create-layout">
  5. <title>Utworzenie layoutu</title>
  6. <para>
  7. Jak nie trudno zauważyć, skrypty widoków z poprzedniej części zawierały jedynie fragmenty
  8. kodu HTML a nie całe strony. Jest to intencjonalne i ma na celu przygotowanie akcji tak aby
  9. zwracały jedynie zawartość związaną z samą akcją a nie aplikacją jako taką.
  10. </para>
  11. <para>
  12. Teraz należy umieścić generowaną treść w pełnoprawnej stronie HTML. Przydatne jest również
  13. nadanie całej aplikacji jednolitego, zwięzłego wyglądu. Aby to osiągnąć zostanie użyty
  14. globalny layout (wzór) strony.
  15. </para>
  16. <para>
  17. Zend Framework używa dwóch wzorów projektowych przy implementacji layoutów: <ulink
  18. url="http://martinfowler.com/eaaCatalog/twoStepView.html">Widok dwustopniowy
  19. (Two Step View)</ulink> oraz
  20. <ulink
  21. url="http://java.sun.com/blueprints/corej2eepatterns/Patterns/CompositeView.html">Widok
  22. złożony (Composite View)</ulink>.
  23. <emphasis>Widok dwustopniowy</emphasis> jest najczęściej powiązany z <ulink
  24. url="http://www.martinfowler.com/eaaCatalog/transformView.html">Widokiem przekształconym
  25. (Transform View)</ulink> - podstawową cechą jest założenie, że aplikacja tworzy widok
  26. podrzędny, który zostaje umieszczony w widoku głównym (layout) i dopiero taki - złożony
  27. widok jest przetwarzany do pokazania użytkownikowi.
  28. <emphasis>Widok złożony</emphasis> natomiast, zakłada tworzenie jednego bądź wielu
  29. autonomicznych widoków bez relacji rodzic-potomek.
  30. </para>
  31. <para>
  32. <link linkend="zend.layout">Zend_Layout</link> jest komponentem, który łączy te wzorce w
  33. aplikacji Zend Framework. Każdy skrypt widoku (view script) posiada własne elementy i
  34. nie musi zajmować się wyświetlaniem elementów wspólnych dla całej strony.
  35. </para>
  36. <para>
  37. Mogą powstać sytuacje, w których niezbędne okaże się umieszczenie globalnych elementów w
  38. pojedynczym widoku. W tym celu Zend Framework udostępnia szereg
  39. <emphasis>pojemników (placeholders)</emphasis>, które umożliwiają dostęp do takich
  40. elementów z poziomu lokalnego skryptu widoku.
  41. </para>
  42. <para>
  43. Aby rozpocząć korzystanie z <classname>Zend_Layout</classname> należy
  44. najpierw poinstruować bootstrap aby
  45. włączył zasób <classname>Layout</classname>. Można to osiągnąć za pomocą komendy
  46. <command>zf enable layout</command> (w katalogu tworzonego projektu):
  47. </para>
  48. <programlisting language="shell"><![CDATA[
  49. % zf enable layout
  50. Layouts have been enabled, and a default layout created at
  51. application/layouts/scripts/layout.phtml
  52. A layout entry has been added to the application config file.
  53. ]]></programlisting>
  54. <para>
  55. Tak jak jest to napisane w potwierdzeniu komendy, plik
  56. <filename>application/configs/application.ini</filename> został zaktualizowany i
  57. zawiera następujący wpis w sekcji <constant>production</constant>:
  58. </para>
  59. <programlisting language="ini"><![CDATA[
  60. ; application/configs/application.ini
  61. ; Dodane do sekcji [production]:
  62. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  63. ]]></programlisting>
  64. <para>
  65. W rezultacie plik INI powinien wyglądać następująco:
  66. </para>
  67. <programlisting language="ini"><![CDATA[
  68. ; application/configs/application.ini
  69. [production]
  70. phpSettings.display_startup_errors = 0
  71. phpSettings.display_errors = 0
  72. includePaths.library = APPLICATION_PATH "/../library"
  73. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  74. bootstrap.class = "Bootstrap"
  75. appnamespace = "Application"
  76. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  77. resources.frontController.params.displayExceptions = 0
  78. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  79. [staging : production]
  80. [testing : production]
  81. phpSettings.display_startup_errors = 1
  82. phpSettings.display_errors = 1
  83. [development : production]
  84. phpSettings.display_startup_errors = 1
  85. phpSettings.display_errors = 1
  86. ]]></programlisting>
  87. <para>
  88. Dodany zapis powoduje, że aplikacja szuka skryptów widoku w katalogu
  89. <filename>application/layouts/scripts</filename>.
  90. Należy zauważyć, iż taki katalog wraz z plikiem <filename>layout.phtml</filename>
  91. zostały utworzone w strukturze projektu przez narzędzie wiersza poleceń zf.
  92. </para>
  93. <para>
  94. Następną przydatną rzeczą będzie upewnienie się, że deklaracja XHTML DocType jest
  95. umieszczona i poprawnie sformułowana. Aby to osiągnąć należy dodać zasób do bootstrapa.
  96. </para>
  97. <para>
  98. Najprostszym sposobem na dodanie zasobu bootstrap jest utworzenie chronionej metody o
  99. nazwie zaczynającej się na <methodname>_init</methodname>. Celem jest zainicjalizowanie
  100. deklaracji DocType więc nowa metoda w klasie bootstrap może się nazywać
  101. <methodname>_initDoctype()</methodname>:
  102. </para>
  103. <programlisting language="php"><![CDATA[
  104. // application/Bootstrap.php
  105. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  106. {
  107. protected function _initDoctype()
  108. {
  109. }
  110. }
  111. ]]></programlisting>
  112. <para>
  113. W ciele metody należy powiadomić zasób widoku aby użył odpowiedni DocType. Tylko skąd
  114. wziąć obiekt widoku? Najłatwiejszym rozwiązaniem jest zainicjalizowanie zasobu
  115. <classname>View</classname>. Potem można pobrać obiekt i go użyć.
  116. </para>
  117. <para>
  118. Aby zainicjalizować zasób widoku należy dodać następującą linijkę do pliku
  119. <filename>application/configs/application.ini</filename> w sekcji
  120. <constant>production</constant>:
  121. </para>
  122. <programlisting language="ini"><![CDATA[
  123. ; application/configs/application.ini
  124. ; Dodanie do sekcji [production]:
  125. resources.view[] =
  126. ]]></programlisting>
  127. <para>
  128. Ten zapis inicjalizuje widok bez żadnych opcji (pisownia '[]' oznacza, że "view" jest
  129. tablicą bez żadnych kluczy ani wartości).
  130. </para>
  131. <para>
  132. Teraz, skoro widok jest skonfigurowany, można wrócić do metody
  133. <methodname>_initDoctype()</methodname>.
  134. W niej należy upewnić się, że zasób <classname>View</classname> został zainicjowany (na
  135. podstawie zapisów w pliku konfiguracyjnym), pobrać obiekt widoku i go skonfigurować:
  136. </para>
  137. <programlisting language="php"><![CDATA[
  138. // application/Bootstrap.php
  139. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  140. {
  141. protected function _initDoctype()
  142. {
  143. $this->bootstrap('view');
  144. $view = $this->getResource('view');
  145. $view->doctype('XHTML1_STRICT');
  146. }
  147. }
  148. ]]></programlisting>
  149. <para>
  150. Po zainicjalizowaniu <classname>Zend_Layout</classname> i ustawieniu deklaracji Doctype,
  151. należy utworzyć główny layout strony:
  152. </para>
  153. <programlisting language="php"><![CDATA[
  154. <!-- application/layouts/scripts/layout.phtml -->
  155. <?php echo $this->doctype() ?>
  156. <html xmlns="http://www.w3.org/1999/xhtml">
  157. <head>
  158. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  159. <title>Zend Framework Quickstart Application</title>
  160. <?php echo $this->headLink()->appendStylesheet('/css/global.css') ?>
  161. </head>
  162. <body>
  163. <div id="header" style="background-color: #EEEEEE; height: 30px;">
  164. <div id="header-logo" style="float: left">
  165. <b>ZF Quickstart Application</b>
  166. </div>
  167. <div id="header-navigation" style="float: right">
  168. <a href="<?php echo $this->url(
  169. array('controller'=>'guestbook'),
  170. 'default',
  171. true) ?>">Guestbook</a>
  172. </div>
  173. </div>
  174. <?php echo $this->layout()->content ?>
  175. </body>
  176. </html>
  177. ]]></programlisting>
  178. <para>
  179. Za pomocą view helpera <methodname>layout()</methodname> pobierana jest zawartość
  180. przeznaczona do wyświetlenia (znajduje się w zmiennej "content"). Można ją umieszczać w
  181. innych częściach layoutu ale w większości przypadków takie podejście wystarczy.
  182. </para>
  183. <para>
  184. Należy zwrócić uwagę na użycie view helpera <methodname>headLink()</methodname>. Jest to
  185. prosty sposób na zachowanie kontroli nad elementami &lt;link&gt; dodawanymi w
  186. różnych miejscach aplikacji oraz na wygenerowanie kodu HTML dla tych elementów
  187. w pliku layoutu bądź innego view scriptu.
  188. Jeśli zajdzie potrzeba dodania dodatkowego arkusza CSS w pojedynczej akcji to
  189. można to zrobić używając <methodname>headLink()</methodname>(na generowanej
  190. stronie pojawi się automatycznie).
  191. </para>
  192. <note>
  193. <title>Punkt kontrolny</title>
  194. <para>
  195. Teraz należy udać się pod adres "http://localhost" i sprawdzić efekty oraz
  196. wytworzony kod. Powinien pojawić się nagłówek XHTML, elementy head, title oraz body.
  197. </para>
  198. </note>
  199. </sect1>