wtorek, 20 sierpnia 2013

Misja S2 - magia w służbie szablonów

Skoro już w miarę twardo stąpamy po świecie szablonów, czas wspiąć się jeszcze wyżej. Tym razem, do naszej pracy wykorzystamy mechanizmy MediaWiki, które sprawią, że szablon zaczną zachowywać się bardziej inteligentnie i lepiej dostosowywać się do woli wstawiającego. Posłużą nam do tego specjalne zaklęcia - tzw. słowa magiczne. Poczujmy się zatem przez chwilę jak Twalot :)

O słowach magicznych. Przełączniki zachowań

Słowa magiczne (ang. magic words) są to pewne wyrażenia, które są w specyficzny sposób przetwarzane przez parser artykułów MediaWiki. Grupą słów magicznych, dość prostą w budowie i stosowaniu, są przełączniki zachowań
Jak nazwa wskazuje, zmieniają one sposób zachowania parsera. Te słowa magiczne są wyrażeniami złożonymi z dużych liter, otoczonych z obu stron znakami podkreśleń. Ja wymagam od was znajomości raptem czterech z nich:
  • __NOTOC__ - powoduje, że spis treści nie jest wyświetlany. Słowo umieszcza się na początku artykułu
  • __FORCETOC__ - wymusza pokazanie spisu treści. Słowo umieszcza się na początku artykułu
  • __TOC__ - parser wstawia w miejsce słowa spis treści (dzięki temu można umieścić go w dowolnym miejscu)
  • __HIDDENCAT__ - powoduje, że kategoria jest ukryta. Słowo musi pojawić się w opisie kategorii
Ale to nam się zbytnio nie przyda przy tworzeniu szablonów. Na nieodzowny zestaw narzędzi, wykorzystywanych przez twórców skomplikowanych systemów szablonowych, składają się trzy rodzaje słów:
  • Kontrolery transkluzji - wskazują one parserowi, które elementy artykułów mają być transkludowane, które nie, a które mają być dołączane wyłącznie podczas wklejania. Już poznaliśmy je w misji S1.
  • Referencje zmiennych - są to wyrażenia, w których miejsce parser MediaWiki dostarcza przeróżne wartości, na przykład nazwa artykułu, data i godzina, statystyki Wiki, numer i stempel czasowy bieżącej wersji. Można się od nich odwoływać podobnie jak podczas transkluzji. Nazwę zmiennej, złożoną z dużych liter, należy otoczyć podwójnymi klamrami. W procesie przetwarzania, wyrażenia te zostaną zastąpione przez wartości zmiennych (można stosować przedrostek msg:, aby te wartości wkleić na stałe). Wzorzec:
    {{FOO}}
    Czasami referencje przyjmują dodatkowy parametr, wówczas podaje się go po nazwie zmiennej i dwukropku.
  • Funkcje parsera - jak nazwa wskazuje, są to funkcje dostarczane przez parser, umożliwiające dynamiczne przetwarzanie danych w trakcie interpretacji kodu szablonu. Mają podobną budowę do wyrażeń transkluzyjnych, z jedną tylko różnicą - pomiędzy nazwą funkcji a pierwszym parametrem występuje nie pionowa kreska, ale dwukropek. Nazwy niektórych funkcji parsera są poprzedzone znakiem hash #. Wzorce:
    {{foo:parametr 1|parametr 2|..|parametr n}}
    {{#foo:parametr 1|parametr 2|..|parametr n}}

Referencje zmiennych

Zacznijmy od zmiennych. Wyobraźmy sobie, że chcemy uzyskać dostęp do nazwy artykułu, który obecnie piszemy. Tak się składa, że parser udostępnia zmienną o nazwie PAGENAME, zawierającą nazwę strony (bez przestrzeni nazw), zatem zmienna użyta na stronie Pomoc:Ala/Ma/Kotazwróci Ala/Ma/Kota. Aby uzyskać do niej dostęp, korzystamy z {{PAGENAME}}. W jej miejsce, parser wstawia wartość zmiennej.

Potęga mechanizmu zmiennych objawia się szczególnie w transkluzji, gdyż podczas wstawiania fragmentów obcych artykułów, zmienne przejmują wartości artykułu bazowego. Objaśnię to na prostym przykładzie. Utwórzmy szablon {{Powitanie}} o następującej zawartości:

Witaj na stronie {{PAGENAME}}!
Gdy wejdziemy na stronę szablonu, zobaczymy:
Witaj na stronie Powitanie!
Zastanówmy się jednak, co się stanie, gdy wstawimy szablon na jakąś stronę? Jaką wartość zwróci zmienna? Okaże się, że szablon wstawiony np. do strony Rainbow Dash, będzie wyglądał następująco:

Witaj na stronie Rainbow Dash!
Viola! Nasz szablonik sam wywnioskował, jak nazywa się strona, na której został osadzony! Czyż to nie cudowne? Teraz jakiś bardziej użyteczny przykład. Chcielibyśmy utworzyć szablon z komunikatem informującym o tym, że treść artykułu jest sporna, i umieścić w nim link do strony dyskusji. Tu z pomocą przychodzi zmienna {{TALKPAGENAME}}. Zwraca ona pełen tytuł strony dyskusji, odpowiadającej artykułowi. Wystarczy zatem bardzo trywialny w budowie szablonik, nie przyjmujący nawet żadnych parametrów, wszystko bowiem co potrzebuje, czerpie ze zmiennych:
Niniejszy artykuł zawiera treści uznane za kontrowersyjne. Aby poznać przedmiot sporu, 
zajrzyj do [[{{TALKPAGENAME}}|strony dyskusji]].

Trudno wyznaczyć listę zmiennych, które są najbardziej przydatne. Trzeba po prostu biegle poruszać się po ich dokumentacji. Mimo wszystko, poniżej kilka najczęściej stosowanych:

  • {{CURRENTDAY}}, {{CURRENTMONTH}}, {{CURRENTYEAR}} - bieżący dzień, miesiąc, rok
  • {{CURRENTDOW}} - dzień tygodnia (od 0 dla niedzieli do 6 dla soboty)
  • {{CURRENTTIMESTAMP}} - sygnatura bieżącego dnia w formie RRRRMMDDGGmmss
  • {{SITENAME}} - nazwa wiki
  • {{CONTENTLANG}} - kod języka wiki
  • {{PAGEID}} - identyfikator bieżącego artykułu w bazie danych
  • {{REVISIONID}} - identyfikator bieżącej wersji w bazie danych
  • {{REVISIONDAY}}, {{REVISIONMONTH}}, {{REVISIONYEAR}}, {{REVISIONTIMESTAMP}} - dzień, miesiąc, rok, sygnatura czasowa ostatniej wersji bieżącego artykułu
  • {{REVISIONUSER}} - autor ostatniej edycji (jeżeli jest wywołany podgląd - nazwa użytkownika podglądająca edycję)
  • {{NUMBEROFPAGES}} - łączna ilość wszystkich stron na wiki
  • {{NUMBEROFARTICLES}} - liczba artykułów w głównej przestrzeni nazw
  • {{NUMBEROFUSERS}}, {{NUMBEROFACTIVEUSERS}}, {{NUMBEROFADMINS}} - liczba użytkowników, aktywnych użytkowników i administratorów
  • {{FULLPAGENAME}} - pełna, zupełna nazwa bieżącego artykułu, razem z przestrzenią nazw
  • {{PAGENAME}} - nazwa bieżącego artykułu bez przestrzeni nazw
  • {{BASEPAGENAME}} - tylko główna nazwa artykułu, bez przestrzeni nazw i ostatniego podpoziomu, np. dla artykułu Szablon:Foo/Bar/Dokumentacja będzie to Foo/Bar
  • {{SUBPAGENAME}} - tylko ostatni podpoziom nazwy bieżącego artykułu, np. dla artykułu Szablon:Foo/Bar/Dokumentacja będzie to Dokumentacja
  • {{TALKPAGENAME}} - nazwa strony dyskusji dla bieżącego artykułu
  • {{FULLPAGENAMEE}}, {{PAGENAMEE}}... - wersje nazw bieżącego artykułu, przystosowane do utworzenia adresów URL (potem więcej o tym powiemy)
  • {{NAMESPACE}} - przestrzeń nazw bieżącego artykułu
  • {{NAMESPACENUMBER}} - numer identyfikacyjny przestrzeni nazw bieżącego artykułu
  • {{canonicalurl:nazwa}} - zwraca pełny adres URL do strony o nazwie nazwa
  • {{gender:użytkownik|a|b|c}} - w zależności do płci użytkownika użytkownik, zwraca a gdy jest mężczyzną, b gdy jest kobietą i c gdy nie ma określonej płci w swoich preferencjach
  • {{plural:x|jest|są}} - jeżeli x jest liczbą równą 1, zwróci tekst jest, a jeżeli wynosi więcej, zwróci tekst
Pełny wykaz zmiennych: Magic words - variables

Wstęp do funkcji parsera

Funkcje parsera to bardzo rozległy dział. Umiejętnie stosowane, stają się wręcz drugim językiem programowania. Aby jednak zbytnio wam nie mieszać, zaczniemy od czterech prostych słów magicznych z tej kategorii, które każdy powinien znać, nie wymagających wielkiej wiedzy na temat składni czy logiki.

Pierwszym z nich, jest słowo #if. Wykonuje ono prosty test logiczny. Jeżeli dany wyraz jest niepusty (tj. nie zawiera samych spacji, znaków, nowej linii, tabulacji etc.) to zwraca jeden tekst. W przeciwnym wypadku, zwraca inny. Wzór składni:

{{#if: testowany wyraz | tekst dla niepustego wyrazu | test dla pustego wyrazu }}
Chyba najprostszym jego zastosowaniem jest zaprogramowanie odpowiedniej reakcji na pustość/niepustość parametrów wywołania szablonu. Weźmy na przykład taki szablon:
{{#if: {{{1}}} | pierwszy parametr ma wartość: {{{1}}} | pierwszy parametr jest pusty}}}
Wówczas dla takich wywołań:
{{Szablon|Luna}}; {{Szablon|}}
parser zwróci:
pierwszy parametr ma wartość: Luna; pierwszy parametr jest pusty
No dobra, a co, jeżeli chcemy zaprojektować szablon tak, by radził sobie z brakiem wywołania jakiegoś parametru? Nic prostszego. Pamiętacie wartości domyślne parametrów? Jeżeli napiszemy tak: {{{1|}}}, to wówczas, jeżeli nie wywołamy pierwszego parametru wcale, w miejscu wyrażenia parametrycznego pojawi się... No właśnie, co się stanie? Wtedy na jego miejscu nie pojawi się nic! Przecież za kreską i przed klamrami nic nie ma, nieprawdaż? Mam nadzieję, że to zrozumieliście :) Zatem, poprzedni przykład, przepisany tak, by radzić sobie z nie wywołaniem parametru, będzie wyglądał tak:
{{#if: {{{1|}}} | pierwszy parametr ma wartość: {{{1}}} | pierwszy parametr jest pusty lub nie istnieje}}
Te słowo ma kluczowe znaczenie, gdyż pozwala bardzo elastycznie zmieniać rodzaje wywołania. Można wynaczyć np. kilka zestawów parametrów, i w zależności od nich, szablon będzie wyglądać inaczej.

Kolejne przydatne słowo to #ifeq. Działa ono bardzo podobnie do poprzedniego, z tą różnicą, że sprawdza, czy dwa dane wyrazy są takie same:

{{#ifeq: wyraz 1 | wyraz 2 | wynik dla identycznych wyrazów | wynik dla różnych wyrazów }}

Następne słowo magiczne z rodziny funkcji parsera to #switch. Testuje ono słowo, które mu podamy, a następnie zwraca pasujący do niego wynik. Ogólny wzór:

{{#switch: testowane słowo
 | słowo 1 = wynik dla słowa 1
 | słowo 2 = wynik dla słowa 2
 ..
 | słowo n = wynik dla słowa n
 | wynik, jeżeli żadne poprzednie słowo nie pasowało }}
I prosty przykład, aby wszystko było jasne. Kod szablonu, reagującego różnie na zadaną rasę kuca:
{{#switch: {{{1}}}
 | jednorożec = {{{2}}} umie czarować
 | ziemniak = {{{2}}} nic szczególnego nie umie
 | pegaz = {{{2}}} umie latać
 | alikorn = {{{2}}} jest księżniczką
 | {{{2}}} coś pewnie umie, ale nie wiem zbytnio co}}
I przykładowe wywołania tego szablonu:
{{Szablon|jednorożec|Rarity}}
{{Szablon|pegaz|Rainbow Dash}}
{{Szablon|ziemniak|Applejack}}
{{Szablon|seapony|Dark Momentum}}
Które dadzą w wyniku:
Rarity umie czarować
Rainbow Dash umie latać
Applejack nic szczególnego nie umie
Dark Momentum coś pewnie umie, ale nie wiem zbytnio co

Ostatnim, dość przydatnym słowem, będzie #ifexist. Sprawdza ono, czy artykuł o zadanej nazwie istnieje na naszej wiki. Wzorzec:

{{#ifexist: nazwa artykułu | wynik, jeżeli artykuł istnieje | wynik, jeżeli artykuł nie istnieje }}

Zadania

Mam tylko nadzieję, że wszystko było zrozumiałe, i przejdziecie to wykonywania zadań :)

  1. Wyobraź sobie, że na Wiki została wprowadzona akcja Kuc dnia. Polega ona na tym, że do każdego dnia tygodnia przypisany jest kucyk, którego artykuł powinien być rozbudowywany. Napisz prosty szablon, wklejający ilustrację odpowiedniej postaci, link do jej artykułu i oznajmiający: Dzisiaj jest dzień..., wstawiający odpowiednią postać, w zależności od dnia tygodnia. Wyliczając od poniedziałku do niedzieli: dzień Applejack, Rainbow Dash, Fluttershy, Rarity, Pinkie Pie, Księżniczki Luny, Księżniczki Celestii. Szablon nie powinien pobierać parametrów. (4p)
  2. Napisz szablon z zakładką użytkownika Członek Tajnej Loży Wiki, wyświetlającą się tylko po wstawieniu na stronach profilowych użytkowników: Sudovia, Wacom, Rani19xx, MatriX5b, Pepe bez fetory. Szablon nie powinien pobierać parametrów. (4p)
  3. Napisz własną wersję szablonu {{WEdycji}}, krzyczącą, jeżeli ostatnia edycja (lub podgląd) artykułu została dokonana nie przez tego użytkownika, co trzeba ^^ Szablon powinien pobierać dokładnie jeden parametr - nazwa użytkownika upoważnionego do edytowania artykułu (4p)
  4. Napisz szablon, zwracający trzy różne komunikaty: jeden, jeżeli jest jeszcze przed premierą 4 sezonu, drugi w dniu premiery 4 sezonu, i trzeci, po premierze 4 sezonu. Nie powinien pobierać parametrów. (4p)
  5. Napisz szablon życzeń urodzinowych, zmieniających końcówki gramatyczne w zależności od płci solenizanta oraz wymieniających jego wiek. Wywołanie szablonu powinno przewidywać dokładnie dwa parametry: nazwę użytkownika-solenizanta oraz rok, w którym się urodził. Zakłada się, że solenizant będzie miał od 13 do 25 lat. (4p)
Kod szablonów należy przesłać na maila. Wystarczy surowy kod, dokumentacja ani kontrolery wywołania nie będą dodatkowo premiowane. Termin wykonywania zadań: 27 sierpnia 2013 r.

4 komentarze:

  1. {{plural:}} może mieć jeszcze jeden parametr. Czyli {{plural:x|wynik1|wynik2|wynik3}}

    Pozwólcie, że dam takie zadanko dodatkowe: jaki warunek musi spełnić liczba x, by szablon zwrócił wynik3 oraz podaj przykład wykorzystania na naszej wiki (tak, jest w jednym miejscu).

    OdpowiedzUsuń
    Odpowiedzi
    1. Toć nie będę wymieniał wszystkich zmiennych, modyfikatorów itd., podałem te najistotniejsze, które mogą się pojawić w zadaniach w tej i przy następnych misjach.

      Usuń
    2. Spoko, ale istotnie znam tylko jeden konkretny przypadek użycia i wymaga to podania dodatkowego parametru.

      Usuń
  2. Na naszej wiki nie działa {{REVISIONUSER}} podczas podglądu. Konieczne jest pierw zapisanie edycji.

    OdpowiedzUsuń