Koniec z linkami, czyli kontroler i widok pod kontrolą

Dziś ostateczne podsumowanie prac nad linkami w “How to Java”. Rzecz malutka, prosta, ale dająca dość obszerny obraz możliwości Grailsów. Na zakończenie szybki rzut oka na kontroler i troszeczkę większy na widok z użyciem GSP.

Jak pisałem w pierwszych postach o “How to Java” – statyczną zawartość umieszczę w jednym kontrolerze – StaticController, dodając ładne mapowanie adresów. Przyszedł czas by spełnić te obietnice. Oto kod kontrolera:


class StaticController {def defaultAction = 'linki'def linki = {[ linki: Htj_Links.list( sort: 'category') ]

}

def strona = { }

}

Jak widać definiujemy dwie akcje – strona oraz linki. Ta druga akcja będzie typowo statyczna – po prostu zostanie zaserwowany statyczny plik GSP. Sama definicja nie jest w tym przypadku konieczna – do tego jednakże wątku powrócę za chwilkę. Zastanowić się wypada co się stanie, kiedy w aplikacji odwołamy się do samego kontrolera, bez podania akcji. Standardowe mapowanie adresów w Grailsach nie wymaga podania akcji, konwencja przejmie tutaj sterowanie:

  • jeżeli w kontrolerze znajduje się tylko jedna akcja, wówczas domyślnie staje się ona podstawową akcją wywoływaną przy podaniu tylko nazwy kontrolera.
  • jeśli z kolei w kontrolerze mamy kilka akcji, domyślnie podstawową staje się ta o nazwie index
  • ostatecznie można tę akcję określić jawnie poprzez taki oto kod:
    def defaultAction = 'nazwaAkcji'

Zatem w kontrolerze dopisałem pro forma taką linijkę, choć docelowo kontroler Static nie będzie widoczny w aplikacji – jego użycie zostanie zakryte przez mapowanie. Teraz może kilka słów o akcji strona. Ma ona służyć wyświetleniu statycznego dokumentu HTML, w którym napisane byłoby kilka słów o stronce “How to Java”. Tak jak napisałem – jeżeli chodzi o wyrenderowanie widoku, bez konieczności jakichkolwiek działań w kontrolerze można ten przypadek obsłużyć inaczej. Należy dobrać się do pliku UrlMappings.groovy i dopisać tam następującą regułę:

"/strona" (view: "strona", controller: "static" )

I od dzisiaj przy wpisaniu po adresie: “/strona” nasze żądanie po prostu wyrenderuje wskazany widok, bez konieczności deklarowania akcji w kontrolerze. Możemy zatem na spokojnie usunąć linijkę z kontrolera.

Na sam koniec zostawiłem linki, gdyż tutaj sprawa jest poważniejsza. O przygodach z klasami domenowymi, które służą do obsługi tychże linków pisałem w poprzednich postach. Teraz zaś weźmiemy się za temat na poważnie:

[ linki: Htj_Links.list( sort: 'category') ]

Linijka ta robi tak wiele. Innymi słowy – wywołuje statycznie metodę list, która listuje wszystkie rekordy z tabeli. Do tego dorzucamy sortowanie po kategorii, a następnie to wszystko jest pakowane do widoku ( nawiasy kwadratowe na końcu akcji to po prostu zbiór zmiennych, które są przypisywane do widoku). Całkiem nieźle jak na krótką linijkę kodu.

Z kolei widok to w połowie otoczka związana z renderowaniem layoutu, zaś nas interesuje samo sedno:


<body><g:if test="${linki.size() > 0}" >
<ul>
<g:each in="${linki}" var="link"><g:if test="${link.category.category_name != poprzedniaKategoria}">
</ul>
<h2>${link.category.category_name}</h2>
<ul>
</g:if><li><a href="${link.address}">${link.title}</a> - ${link.description}</li>
<g:set scope="page" var="poprzedniaKategoria" value="${link.category.category_name}" />
</g:each>
</ul>
</g:if>

</body>

Po kolei. Na samym początku wykorzystujemy znacznik instrukcji warunkowej <g:if>, który sprawdza rozmiar przekazanego zbioru danych. Zasadniczo czynię to tylko po to, aby w razie pojawienia się pustego zbioru nie został wyrenderowany znacznik UL, który nie może być pusty jeśli chcemy pozostać w zgodzie z walidatorami HTML. Tworzymy listę, po czym przechodzimy po przekazanym nam zbiorze danych. I tutaj mała kwestia – kolejna instukcja IF. Rzecz w tym, iż w linkach są kategorie, głupotą zatem byłoby wrzucać wszystkie linki bez składu i rozkładu. Stąd instrukcja warunkowa, która sprawdza, czy poprzednia kategoria linku (zapisywana za pomocą znacznika <g:set>) była inna od obecnej. Jeśli była inna, wówczas zamykamy sobie listę, wyświetlamy nagłówek i tworzymy nową listę. Może i rozwiązanie to nie poraża geniuszem, ale swoją funkcję pełni wyśmienicie. W rezultacie po wprowadzeniu tego kodu (do bazy dodałem trochę danych przez PMA) u mnie przeglądarka wyświetliła coś takiego:

listalinkow

Piękne prawda? I to wszystko osiągnąłem dzięki relatywnie bardzo małej ilości kodu. Jedyne co może denerwować to brak porządku w nazwach linków w konkretnej kategorii – segregowanie językowe powinno na górę wypchnąć linki do Grailsów, zaś do mojego bloga na końcu. Dodamy zatem jeszcze jeden warunek do kontrolera:

[ linki: Htj_Links.list( [sort: 'category', sort: 'title' ]) ]

i możemy cieszyć się z ładniutkiej listy linków. Czysto, schludnie i bezpiecznie. Na dziś to tyle – w następnych wpisach zajmiemy się czymś bardziej dynamicznym – rejestracją użytkowników oraz ich autoryzacją.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s