Automatyczne generowanie kodu
Poczynając od wersji 1.1.2, Yii wyposażone jest w opartym na przegląradkowym narzędziu do generowania kodu Gii. Zastępuje ona poprzednie narzędzie do generacji yiic shell
, które uruchamiane jest z linii poleceń. W tej części opiszemy jak używać Gii i jak rozszerzać Gii by zwiększyć produktywność dewelopmentu.
Używanie Gii
Gii zaimplementowane zostało w postaci modułu i musi być używane wewnątrz istniejącej aplikacji Yii. Aby używać Gii, najpierw modyfikujemy konfigurację aplikacji w następujący sposób:
W powyższym kodzie deklarujemy moduł nazwany gii
którego klasą jest GiiModule. Określamy również hasło dla modułu, które będzie rządane podczas uzyskiwania dostępu do Gii.
Domyślnie, z powodu bezpieczeństwa, Gii skonfigurowane jest jako dostępne na lokalnym komputerze. Jeśli chcemy udostępnić go dla innych zaufanych komputerów, możemy skonfigurować właściwość GiiModule::ipFilters w sposób pokazany w powyższym kodzie.
Ponieważ Gii może generować i zapisywać nowe pliki z kodem w istniejącej aplikacji, musimy się upewnić, że proces serwera ma odpowiednie uprawnienia do tego. Powyższe właściwości GiiModule::newFileMode oraz GiiModule::newDirMode kontrolują jak nowe pliki i katalogi powinny być wygenerowane.
Uwaga: Gii jest przewidziane jako narzędzie deweloperskie. Dlatego też, powinno być zainstalowane jedynie na maszynie deweloperskiej. Ponieważ może ono generować nowe skrypty PHP w aplikacji, powinniśmy zwracać dostateczną uwagę na środki bezpieczeństwa (np. hasła, filtry IP).
Możemy uzyskać dostęp do Gii poprzez adres URL http://hostname/sciezka/do/index.php?r=gii
. Zakładamy, że http://hostname/sciezka/do/index.php
to URL dostępu do istniejącej aplikacji Yii.
Jeśli istniejąca aplikacjia Yii używa formatu URL ścieżek
(zobacz zarządzanie URL-ami), możemy uzyskać dostęp do Gii poprzez adres URL http://hostname/sciezka/do/index.php/gii
. Możemy dodać następujący reguły URL na początej istniejących reguł URL:
Gii dostarczane jest z kilkoma domyślnymi generatorami kodu. Każdy generator kodu jest odpowiedzialny za generowanie określonego typu kodu. Na przykład, generator kontrolera generuje klasę kontrolera wraz z kilkoma skryptami widoków akcji; generator modelu generuje klasę rekordu aktywnego dla określonej tabeli bazy danych.
Kolejne kroki używane podczas generowania wyglądają następująco:
- Wejdź na stronę generatora;
- Uzupełnij pola, które określają parametry generacji kodu. Na przykład, aby używać generatora modułu do utworzenia nowego modułu, należy podać ID modułu.
- Naciśnij przyciśk podglądu kodu
Preview
, który zostanie wygenerowany. Pokaże się tabela przedstawiająca listę plików z kodem, które mają zostac wygenerowane. Możesz kliknąć na każdej z pozycji tej listy aby podejrzeć kod. - Naciśnij przycisk generuj
Generate
aby wygenerować pliki z kodem; - Przejrzyj log po generacji kodu.
Rozszerzanie Gii
Chociaż domyślne generatory kodu dostarczane z Gii mogą generować bardzo potężny kod, często chcemy dostosować go lub też utworzyć nowy zgodny z naszym gustem i potrzebami. Na przykład, możemy chcieć wygenerować kod, który będzie pisany w naszym ulubionym stylu kodowania lub też możemy chcieć dodać wsparcie dla wielu języków. Wszystko to może zostać zrobione przy użyciu Gii.
Gii może zostać rozszerzone na dwa sposoby: dostosowanie szablonów kodu istniejących generatorów kodu oraz napisanie nowych generatorów kodu.
Struktura generatora kodu
Generator kodu przechowywany jest w katalogu, którego nazwa jest traktowana jak nazwa generatora. Generator zazwyczaj zawieta następującą zawartość:
Ścieżka wyszukiwania generatorów
Gii szuka dostępnych generatorów w zestawie katalogów określonych przez właściwość GiiModule::generatorPaths. Jeśli potrzebne jest dostosowanie jej, możemy skonfigurować tą właściwość w konfiguracji aplikacji w następujący sposób:
Powyższa konfiguracja instruuje Gii aby szukać generatorów w katalogu o aliasie application.gii
, w odróżnieniu od domyślnej lokalizacji system.gii.generators
.
Możliwym jest posiadanie dwóch generatorów o tej samej nazwie ale pod różnymi ścieżakami wyszukiwania. W takim przypadku, generator znajdujący się w wyspecyfikowanej wcześnie właściwości GiiModule::generatorPaths ma pierwszeństwo.
Dostosowywanie szablonów kodu
Jest to najprostszy i najczęściej stosowany sposób rozszerzania Gii. Użyjemy przykładu w celu wyjaśnienia jak dostosować kod szablonu. Zakładamy, że chcemy dostoswać kod generowany przez generator modeli.
Najpierw tworzymy katalog o nazwie protected/gii/model/templates/compact
. Tutaj model
oznacza będziemy nadpisywać domyślny generator modelu. templates/compact
oznacza, że dodamy nowy zestaw szablonów kodu o nazwie compact
.
Następnie modyfikujemy naszą konfigurację aplikacji dodając application.gii
do GiiModule::generatorPaths jak pokazano w poprzednim akapicie.
Teraz otwórz stronę generowania modelu. Kliknij ma polu szablonu kodu Code Template
. Powinniśmy zobaczyć listę rozwijaną, zawierającą nasz nowo utworzony katalog szablonów compact
. Jednakże, jeśli wybierzemy ten szablon do generowania kodu, zobaczymy błąd. Dzieje się tak, pownieważ musimy jeszcze nie wstawiliśmy żadnego pliku szablonu kodu w nowym zestawie szablonów compact
.
Skopiuj plik framework/gii/generators/model/templates/default/model.php
do protected/gii/model/templates/compact
. Jeśli spróbujemy ponownie wygenerować szablon compact
zakończy się to sukcesem. Jednakże kod wygenerowany nie rózni się od tego generowanego przez domyślny
zestaw szablonów.
Nadszedł czas aby wykonać rzeczywista pracę dostosowywania. Otwórz plik protected/gii/model/templates/compact/model.php
w celu edytowania go. Pamiętaj, że plik ten będzie używane jako skrypt widoku, co oznacza, że może on zawierać deklaracje i wyrażenia PHP. Zmodyfikujmy szablon w taki sposób, że metoda attributeLabels()
w generowanym kodzie będzie używała Yii::t()
do tłumaczenia etykiet atrybutów:
W każdym szablonie kodu możemy uzyskać dostep do pewnych predefiniowanych zmiennych takich jak $labels
w powyższym przykładzie. Zmienne te są dostarczane przez odpowiednei generatory kodu. Różne generatory kodu mogą dostarczać różne zestawy zmiennych w swoich szablonach kodu. Prześledź uważnie opisy w domyślnym szablonie.
Tworzenie nowych generatorów
W tej części pokażemy jak utworzyć nowy generator, który może wygenerować nową klasę widżetu.
Najpierw utworzymy katalog o nazwie protected/gii/widget
. W katalogu tym utworzymy następujące pliki:
WidgetGenerator.php
: zawiera klasę kontroleraWidgetGenerator
. Jest to punkt startowy generatora widżetów.WidgetCode.php
: zawiera klasę modeluWidgetCode
. Klasa ta zawiera główną logikę generowania kodu.views/index.php
: skrypt widoku pokazujący formualrz z polami wejściowymi generatora kodu.templates/default/widget.php
: domyślny kod szablonu do generowania pliku klasy widżetu.
Tworzenie WidgetGenerator.php
Plik WidgetGenerator.php
jest maksymalnie prosty. Zwiera on tylko następujący kod:
W powyższym kodzie określamy jedynie to, iż generator będzie używał klasę modelu, której aliasem ścieżki jest application.gii.widget.WidgetCode
. Klasa WidgetGenerator
dziedziczy z klasy CCodeGenerator, która implementuje wiele funkcjonalności włączając w to akcje potrzebne do zarządzania procesem generowania kodu.
Tworznie WidgetCode.php
Plik WidgetCode.php
zawiera model klasy WidgetCode
, który zawiera główną logikę do generowania klasy widżetu opartej na danych wprowadzonych przez użytkownika. W przykładzie tym zakładamy, że jedyną daną jaką rządamy od użytkownika jest nazwa klady widżetu. Nasza klasa WidgetCode
wygląda następująco:
Klasa WidgetCode
dziedziczy z CCodeModel. Tak jak w zwykłej klasie modelu także w tej możemy zadeklarować reguły rules()
oraz etykiety atrybutów attributeLabels()
odpowiednio w celu sprawdzenia danych wprowadzanych przez użytkownika oraz dostarczenia etykiet atrybutów. Zauważ, że klasa bazowa CCodeModel definiuje już pewne reguły oraz etykiety atrybutów i powinniśmy połączyć je z naszymi nowymi regułami i etykietami w naszej klasie.
Metoda prepare()
przygptpwuje kod, kóry będzie generowany. Jej głównym zadaniem jest przygotować likse obiektów CCodeFile, z których każdy reprezentuje plik kodu, który zostanie wygenerowany. W naszym przykładzie musimy jedynie utworzyć obiekt CCodeFile, który reprezentuje plik klasy widżetu, który zostanie wygenerowany. Nowa klasa widżetu zostanie wygenerowana w katalogu protected/components
. Wywołujemy metodę CCodeFile::render w celu wygenerowania aktualnego kodu. Metoda ta dołącza kod szablonu jako skrypt PHP i zwraca jego zawartość jako wygenerowany kod za pomocą polecenia echo.
Tworznie views/index.php
Posiadając kontroler (WidgetGenerator
) i model (WidgetCode
) naszedł czas aby utworzyć widok views/index.php
.
W powyższym przykładzie wyświetlamy przede wszystkim formularz używając widżetu CCodeForm. W formularzu tym wyświetlamy pole zbierające dane wprowadzone dla atrybutu className
klasy WidgetCode`.
Podczas tworzenia formularza, możemy wykorzystać dwie fajne funkcjonalności dostarczone przez widżet CCodeForm. Pierwszą są podpowiedzi. Druga to przyklejone dane wejściowe (ang. sticky inputs).
Jeśli wypróbowałeś jakikolwiek z domyślnych generatorów kodu, zauważyłeś że podczas ustawiania fokusu na danym polu wejściowym, tuż obok pola wyświetli się ładna dla oka podpowiedź. Może to zostać uzystkane w bardzo prosty sposób poprzez napisanie za polem wejściowym tagu div
, którego klasą CSS jest tooltip
.
Dla pewnych pól wejściowych możemy chcieć zapamiętać ich ostatnią porpawną wartość tak aby uchronić użytkownika przed kłopotliwym powtarzaniem za każdym razem tych samych wartości podczas używania generatora. Przykładem jest pole odczytujące nazwę klasy bazowej domyślnego generatora kodu. Te przyklejone pola są początkowo wyświetlane jako podświetlony, statyczny tekst. Jeśli na nim klikniemy, zamieni się on na pole wejściowe pobierające daną wejściową od użytkownika.
W celu zdefiniowana pola wejściowego jako przyklejonego, potrzebujemy zrobić dwie rzeczy.
Najpierw potrzebujemy zadeklarować regułę sprawdzania poprawności sticky
do odpowiedniego atrybutu modelu. Na przykład, generator domyślnego kontolera posiada następujące reguły deklarujace atrybuty klasy bazowej baseClass
oraz akcji actions
jako przyklejone:
Po drugie, potrzebujemy dodać klasę CSS o nazwie sticky
do kontenera div
pola wejściowego w widoku w następujący sposób:
Tworzenie templates/default/widget.php
Na koniec tworzymy szablon kodu templates/default/widget.php
. Tak jak napisaliśmy już wcześniej, jest on używany jako skrypt widoku, który może zawierać wyrażenia i deklaracje PHP. W szablonie kodu mozemy zawsze mieć dostęp do zmiennej $this
, która odnosi się do obiektu modelu kodu. W naszym przykładzie $this
odnosi się do obiektu WidgetModel
. To pozwala uzyskać wprowadzoną przez użytkownika nazwę klasy poprzez $this->className
.
Na tym kończy się tworzenie nowego generatora kodu. Możemy uzyskać dostęp do tego generatora kodu bezpośrednio poprzez adres URL http://hostname/sciezka/do/index.php?r=gii/widget
.