Development

Documentation/pl_PL/04-Podstawy-tworzenia-stron/trunk

You must first sign up to be able to contribute.

Ciekawe, pierwszą rzeczą jaką robią programiści podczas nauki nowego języka albo frameworka jest wyświetlanie na ekranie napisu "Witaj świecie!". Dziwnie jest myśleć, że komputer jest czymś co może witać cały świat. Ale Symfony nie jest takie głupie jak inne programy i Ty masz dowód! Możesz stworzyć stronę z napisem "Witaj, <Twoje imię tutaj>"! Ten rozdział nauczy Cię jak stworzyć moduł, który jest strukturalnym elementem grupującym strony. Dowiesz się także jak stworzyć stronę, która dzieli się na akcję i szablon, czego wymaga wzorzec MVC. Linki i formularze to podstawowe formy interakcji na www. Zobaczysz jak umieścić je w szablonie i operować nimi w akcji.

Tworzenie szkieletu modułu Jak wyjaśnił rozdział nr 2, Symfony grupuje strony w moduły. Przed stworzeniem strony, musisz stworzyć moduł, który jest początkowo pustą skorupką ze strukturą plików. Linia komend Symfony automatyzuje tworzenie modułów. Musisz tylko wywołać zadanie inti-module z nazwą aplikacji i nazwą modułu jako argumentami. W poprzednim rozdziale stworzyłeś aplikację o nazwie myapp. Aby dodać moduł mymodule do aplikacji, wprowadź następujące komendy:

#!html <pre class="command-line">

> cd ~/myproject
> symfony init-module myapp mymodule

>> dir+      ~/myproject/apps/myapp/modules/mymodule
>> dir+      ~/myproject/apps/myapp/modules/mymodule/actions
>> file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/config
>> dir+      ~/myproject/apps/myapp/modules/mymodule/lib
>> dir+      ~/myproject/apps/myapp/modules/mymodule/templates
>> file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/validate
>> file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

#!html </pre>

To polecenie tworzy tylko trzy pliki. Jeden w folderze test/ jest związany z testami, nie musisz się nim przejmować przed rozdziałem nr 15. Plik actions.class.php (pokazany na listingu 4-1) wysyła do podstawowego modułu stronę gratulacyjną. Plik templates/indexSuccess.php jest na razie pusty. Listing 4-1 - Domyślna wygenerowana akcja, plik actions/actions.class.php

<?php
 
class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $this->forward('default', 'module');
  }
}

#!html <blockquote class="note"><p> Jeżeli patrzysz na aktualny plik actions.class.php, możesz znaleźć w nim kilka innych linii, zawierająch komentarze. Symfony zachęca używania komentarzy do dokumentowania Twoich projektów i przygotowywania każdego pliku z klasą do kompatybilności z narzędziem phpDocumentator (http://www.phpdoc.org/) #!html </p></blockquote>

Dla każdego nowego modułu, Symfony tworzy podstawową akcję - index. Jest ona wkomponowana jako metoda o nazwie executeIndex. Natomiast plik z szablonem nosi nazwę indexSuccess.php. Znaczenie prefixu execute i suffixu Success zostanie wytłumaczone w Rozdziałach nr 6 i 7. Teraz możesz zwrócić uwagę, że nazywanie jest pewną konwencją. Możesz zobaczyć tę stronę (pokazaną na obrazie 4-1) pod adresem URL:

http://localhost/myapp_dev.php/mymodule/index

Domyślna akcja index nie będzie używana w tym rozdziale, więc możesz usunąć metodę executeIndex() z pliku actions.class.php oraz usunąć plik indexSuccess.php z folderu templates/ #!html <blockquote class="note"><p> Symfony oferuje inne drogi do inicjacji modułów niż z lini poleceń. Jedna z nich to stworzenie folderów i plików samodzielnie. W wielu przypadkach, akcje i szablony modułu manipulują danymi z tabel. Konieczne jest tworzenie, odczytywanie, aktualizowanie i usuwanie rekordów z tabel, w większości przypadków operacje są takie same. Symfony dostarcza Ci mechanizm zwany scaffolding, który wygeneruje ten kod za Ciebie! Odsyłam do rozdziału nr 14 po więcej informacji o tej technologi. #!html </p></blockquote> Obraz 4-1 - Domyślna wygenerowana strona (index) #!html <p><img src="/images/book/trunk/F0401.jpg" alt="The default generated index page" title="The default generated index page" /></p>

Dodawanie strony W Symfony, logika strony jest umieszczona w akcjach, a warstwa prezentacyjna w szablonach. Strony bez logiki (wciąż) wymagają pustej akcji. Dodawanie akcji Strona typu "Witaj świecie!" będzie dostępna przez akcję myAction. Aby ją stworzyć, po prostu dodaj metodę executeMyAction w klasie mymoduleAction, tak jak pokazano na listingu 4-2. Listing 4-2 - Dodawanie akcji jest dodawaniem metody do klasy akcji

<?php
 
class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
  }
}

Nazwa akcji wygląda zawsze tak: executeXxx(), gdzie druga część nazwy jest nazwą akcji z pierwszą dużą literą. Teraz, jeżeli przejdziesz pod adres:

http://localhost/myapp_dev.php/mymodule/myAction

Symfony ostrzeże Cię, że brakuje szablonu myActionSuccess.php. To jest normalne, w Symfony strona jest zawsze tworzona z akcji i szablonu. #!html <blockquote class="note"><p> Uwaga! Adresy (nie nazwy domen) są bardzo wrażliwe na litery, więc Symfony też jest (nawet jeżeli nazwy metod są niewłaściwe w kodzie PHP). To oznacza, że jeśli dodasz metodę executemyaction(), albo executeMyaction(), i spróbujesz wywołać akcję myAction z przeglądarki, Symfony zwróci błąd 404 (brak strony). #!html </p></blockquote> #!html <blockquote class="sidebar"><p class="title">Adresy są częścią rządania</p> Symfony zawiera sytem routingu, który umożliwia separację pomiędzy aktualną nazwą akcji a formą adresu potrzebną do jej wywołania. Umożliwia to dowolne formatowanie adresu. Nie jesteś ograniczany przez strukturę plików czy parametrów. Adres URL może wyglądać tak jak Ty chcesz! Dla przkładu, wywołujesz akcję index z modułu zwanego article, może to wyglądać tak:

http://localhost/myapp_dev.php/article/index?id=123

URL wyszukuje artykuł z bazy danych. W tym przykładzie, wyszukuje on artykuł (z parametrem id=123) w sekcji Europejskiej, który jest specyficzny dla finansów we Francji. Ale adres URL może być zapisany zupełnie inaczej, dzięki małej zmianie w pliku konfiguracyjnym routing.yml:

http://localhost/articles/europe/france/finance.html

URL nie jest wtedy tylko przyjacielski dla wyszukiwarek, ale jest to też ułatwienie dla użytkownika, który może używać paska adresu jako pseudo linii komend do tworzenia zapytań, jak w następującym URL-u:

http://localhost/articles/tagged/finance+france+euro

Symfony wie jak parsować i generować URL-e dla użytkownika. System routingu automatycznie pobiera parametry z adresu i udostępnia je w akcji. Formatuje on również odnośniki zawarte w rządanium, dlatego wyglądają one elegancko. Dowiesz się o tym więcej w rozdziale nr 9. W sumie, oznacza to, że droga jaką nazwiesz akcje w swojej aplikacji nie powinna mieć wpływu na drogę URL-i używanych do wywoływania ich. Nazwy metod wyjaśniają co aktualnie robią i jest to najczęściej czasownik w bezokoliczniku. Nazwy akcji mogą być w ogóle nie widoczne dla użytkownika końcowego, więc nie wachaj się używania wyraźnych nazw (jak pokazPoNazwie albo pokazZKomentarzami). Zaoszczędzisz na komentarzach w kodzie, aby wyjaśnić co dana funkcja robi. Ponadto Twój kod będzie prostszy do zrozumienia. #!html </blockquote> Dodawanie szablonu Akcja wymaga szablonu aby się wyświetlić. Szablon jest plikiem ulokowanym w folderze templates/ w module. Nazwany jako akcja i terminator akcji. Domyślny terminator to success, więc szablon potrzebny akcji myAction nazywa się myActionSuccess.php. Szablony są potrzebny tylko do prezentacji danych więc umieszczaj w nich jak najmniej kodu PHP. Szablon strona wyświetlająca napis "Witaj świecie!" może wyglądać tak prosto jak to przedstawiono na listingu 4-3. Listing 4-3 - Szablon mymodule/templates/myActionSuccess.php

<p>Witaj świecie!</p>

Jeżeli musisz wykonać jakiś kod PHP w szablonie, powinieneś unikać zwykłej składni PHP (takiej jak pokazano na listingu 4-4), aby kod był zrozumiały dla programistów nie znających PHP. Niektóre funkcje sterujące mają alternatywną składnie, zaprezentowano ją na listingu 4-5. Listing 4-4 - Zwykła składnia PHP, dobra dla akcja, ale zła dla szablonów

<p>Witaj świecie!</p>
<?php
if ($test)
{
  echo "<p>".time()."</p>";
}
?>

Listing 4-5 - Alternatywna składnia PHP, dobra dla szablonów

<p>Witaj świecie!</p>
<?php if ($test): ?>
<p><?php echo time(); ?></p>
<?php endif; ?>

#!html <blockquote class="note"><p> Dobrym zwyczajem jest nie mieszanie kodu PHP z HTML. Nie powinieneś wyświetlać znaczników HTML w PHP. Jeżeli też otwierasz w jednej lini znacznik <?php, powinieneś w tej samiej lini zamknąć! #!html </p></blockquote> Przesyłanie informacji z akcji do szablonu Zadaniem akcji jest wykonywanie obliczeń, odzyskiwanie danych, test, ustawianie zmiennych do szablonów, aby były wyświetlone albo przetestowane. Symfony udostępnia właściwości klasy akcji (dostęp przez $this->nazwaZmiennej w akcji) w szablonie (dostępne przez $nazwaZmiennej). Listingi 4-6 i 4-7 pokazują jak przesłać dane z akcji do szablonu Listing 4-6 - Ustawienie właściwości akcji i uczynienie ich dostępnymi w szablonie

<?php
 
class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
    $dzisiaj = getdate();
    $this->godzina = $dzisiaj['hours'];
  }
}

Listing 4-7 - Szablon ma bezpośredni dostęp do właściwości akcji

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>

#!html <blockquote class="note"><p> Szablony od razu mają dostęp do kilku właściwości. W każdym szablonie można się odwoływać do następujących obiektów: [i]$sf_context/i, [i]$sf_request/i, [i]$sf_params/i i [i]$sf_user/i. Niedługo zobaczysz jak ich używać. #!html </p></blockquote> Gromadzenie informacji od użytkownika (formularze) Formularze są dobrym sposoben na uzyskanie danych od użytkownika. Pisanie formularzy w HTML może być czasem niewygodne. W Symfony możesz umieszczać formularze w tradycyjny sposób, albo użyć pomocnika dostarczanego przez Symfony. Dzięki niemu pisanie formularzy staje się prostsze. Na listingu 4-8 pokazano jak umieszczać formularze w tradycyjny sposob. Listing 4-8 - Szablony mogą zawierać zwykły kod HTML formularzy

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<form method="post" target="/myapp_dev.php/mymodule/anotherAction">
  <label for="name">What is your name?</label>
  <input type="text" name="name" id="name" value="" />
  <input type="submit" value="Ok" />
</form>

Pomocnik to funkcja napisana w PHP. Wyświetla ona kod HTML. Jest to szybsza metoda. Używając pomocników Symfony możesz uzyskać taki sam efekt jak na listingu 4-8. Sposób ten przedstawiony jest na listingu 4-9. Listing 4-9 - Używanie pomocników jest szybsze i prostsze, niż pisanie tagów HTML

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'Jak się nazywasz?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
</form>

#!html <blockquote class="sidebar"><p class="title">Szablony są po to aby Ci pomóc</p> Jeżeli przyglądając się przykładowi na listingu 4-9 nadal myślisz, że wersja zawierająca pomocniki nie jest naprawdę szybka to zobacz następny przykład:

<?php
	$card_list = array(
						'VISA' => 'Visa',
						'MAST' => 'MasterCard',
						'AMEX' => 'American Express',
						'DISC' => 'Discover');
	echo select_tag('cc_type', options_for_select($card_list, 'AMEX'));
?>

To samo, tyle, że w HTML:

<select name="cc_type" id="cc_type">
  <option value="VISA">Visa</option>
  <option value="MAST">MasterCard</option>
  <option value="AMEX" selected="selected">American Express</option>
  <option value="DISC">Discover</option>
</select>

Korzyści z używania pomocników w szablonach są następujące: szybkość kodowania, przejrzystość kodu. Jedyna cena jaką się płaci to czas poświęcony na nauczenie się ich. #!html </blockquote> Używanie skróconych tagów (<?, zamiast <?php) nie jest polecane. Nie działają ona na domyślnej konfiguracji PHP. Ponadto podczas deklaracj XML może wystąpić tak zwany parse error. Więcej o pomocnikach dowiesz się z rozdziału nr 10. Linki do innych akcji Już wiesz, że jest pewna różnica między nazwą akcji a URL-em do wywołania jej. Więc jeżeli stworzysz link do akcji anotherAction w szablonie tak jak pokazano na listingu 4-10, to zadziała on tylko na domyślnie ustawionym routingu. Jeżeli się później zdecydujesz na zmienę wyglądu URL-a, będziesz musiał przerobić wszystkie linki w szablonach. Listing 4-10 - Hiperłącza, zwykły HTML

<a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">
  Nigdy nie ujawniłem swojego imienia
</a>

Aby uniknąć tego typu sytuacji, powinieneś zawsze używać pomocnika link_to(), który sam stworzy hiperłącze do akcji. Listing 4-11 przedstawia użycie tego pomocnika. Listing 4-11 - Pomocnik link_to()

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'Jak się nazywasz?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
  <?php echo link_to('Nigdy nie ujawniłem swojego imienia','mymodule/anotherAction?name=anonymous') ?>
</form>

Rezultat HTML będzie taki sam jak poprzednio, z tą różnicą, że po zmianie reguł routingu nie będziesz musiał poprawiać URL-i. Pomocnik link_to(), jak i inne pomocniki, przyjmuje inne opcjonalne parametry. Listing 4-12 pokazuje przykład użycia opcjonalnych argumentów. Listing 4-12 - link_to() - opcjonalne argumenty

<?php 
// Opcje jako tablica asocjacyjna
echo link_to('Nigdy nie ujawniłem swojego imienia', 'mymodule/anotherAction?name=anonymous',
  array(
    'class'    => 'special_link',
    'confirm'  => 'Jesteś pewien?',
    'absolute' => true
)) ?>
 
// Argumenty jako string
<?php echo link_to('Nigdy nie ujawniłem swojego imienia', 'mymodule/anotherAction?name=anonymous',
  'class=special_link confirm=Jesteś pewien? absolute=true') ?>
 
// Obydwa rozwiązania zwrócą taki sam wynik
 => <a class="special_link" onclick="return confirm('Jesteś pewien?');"
    href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous">
    Nigdy nie ujawniłem swojego imienia</a>

Ilekroć użyjesz pomocnika Symfony generującego kod HTML, możesz zawsze dodać opcjonalne atrybuty (jak atrybut class w przykładzie na listingu 4-12). Pomocniki Symfony zawsze generują poprawny kod xHTML. #!html <blockquote class="note"><p> Ponieważ składnia string wymaga dodatkowego parsowania, jest ona trochę wolniejsza od składni tablicowej. #!html </p></blockquote> W rozdziale nr 9 poznasz dodatkowe opcje pomocników. Pobieranie informacji z rządań Jeżeli użytkownik przesłał jakieś informacje przez formularz (rządanie POST) czy przez adres URL (rządanie GET) zawsze możesz pobrać te informacje dzięki metodzie getRequestParameter() z obiektu klasy sfActions. Listing 4-13 pokazuje jak w akcji anotherAction pobrać wartość name. Listing 4-13 - Pobieranie danych z danych rządania

<?php
 
class mymoduleActions extends sfActions
{
  ...
 
  public function executeAnotherAction()
  {
    $this->name = $this->getRequestParameter('name');
  }
}

Jeżeli działania na danych z rządania są proste, nie musisz używać do tego akcji w kontrolerze. W szablonie masz dostęp do obiektu $sf_params, który oferuje metodę get() do pobierania danych rządania. Jeżeli akcja executeAnotherAction() jest pusta, listing 4-14 pokazuje jak w szablonie pobieramy te same parametry. Listing 4-14 - Pobieranie Danych bezpośrednio w szablonie

<p>Witaj, <?php echo $sf_params->get('name') ?>!</p>

#!html <blockquote class="note"><p> Dlaczego nie używać tablic $_POST, $_GET czy $_REQUEST ? Ponieważ, gdy URL przyjmuje inną postać niż oryginalna (np. http://localhost/articles/europe/france/finance.html) nie ma możliwości pobrania danych bezpośrednio, tylko system routingu może to zrobić. Ponadto jesteś automatycznie chroniony przed tzn. wstrzyknięciami kodu. #!html </p></blockquote> Obiekt $sf_params jest bardziej pomocny w pobieraniu danych niż metoda getRequestParameter(). Dla przykładu jeżeli chcesz sprawdzić istnienie parametru rządania, możesz w prosty sposób użyć metody $sf_params->has(), a później pobrać go za pomocą metody get(), tak jak pokazano na listingu 4-15. Listing 4-15 - Testowanie czy parametr rządania istnieje w szablonie

<?php if ($sf_params->has('name')): ?>
  <p>Witaj, <?php echo $sf_params->get('name') ?>!</p>
<?php else: ?>
  <p>Witaj, Janie Kowalski!</p>
<?php endif; ?>

Możesz zrobić to w prostszy sposób, podająć metodzie get() drugi parametr.

<p>Witaj, <?php echo $sf_params->get('name', 'Janie Kowalski') ?>!</p>

Podsumowanie W Symfony, strony są skomponowane jako akcje (metoda w pliku actions/actions.class.php z prefixem execute) i szablon (plik w folderze templates/, najczęściej zakończony Success.php). Są one pogrupowane w moduły, zależnie od ich funkcji w aplikacji. Pisanie szablonów ułatwiają pomocniki, które są funkcjami zwracającymi kod HTML. Możesz już napisać całą aplikację z Symfony. Ale zajmie Ci jednak to dużo czasu, nie poznałeś jeszcze wszystkich możliwości Symfony. Dlatego nie przestawaj czytać tej ksiązki.