Do tej pory byłem przekonany, że Google nie radzi sobie (albo po prostu nie robi tego z wyboru) z elementami Java Script na stronie. Jakież było dziś moje zdziwienie kiedy chciałem znaleźć coś u siebie na blogu za pomocą Google - oto co ujrzałem:

"Ale o co Ci chodzi" - mógłby zapytać ktoś, "przecież masz dokładnie* taki tytuł strony:"

No właśnie nie bardzo - w wynikach Google pojawiło się dodatkowe "null" w tytule. Dodatkowo, z uwagi na sposób, w jaki pociąłem sobie szablon Joggera, tytuł podstrony muszę generować w nieco inny sposób:

Czyli jak widać, strona ma zupełnie inny tytuł nadany w HTML, który następnie w głębi kodu zostaje zmodyfikowany przy pomocy Java Script.
Na początku uznałem, że może być to przyczyna odkrycia linków do strony prowadzących np. z głównej strony Joggera czy innych blogów. Nie może to być jednak wyjaśnienie sytuacji, ponieważ tytuły linków z Joggera wyglądają zgoła inaczej - nie ma w nich głównego sloganu witryny. RSS? Również ma inne tytuły artykułów ...
Zostaje mi tylko jeden wniosek - Google (w jakimś tam stopniu) jest w stanie wywołać skrypty JS i pobrać dane ze zmodyfikowanej strony. Czy ktoś spotkał się może już z tym zjawiskiem i może wskazać jakąś publikację mówiącą o tym w jakim stopniu Google bierze pod uwagę takie - wygenerowane przez JS - treści?
HTML5 w jednym ze swoich udogodnień wprowadza bardzo przyjazne rozwiązanie pozwalające na przechowywanie informacji o dowolnym tagu. W celu szybszego zrozumienia o co chodzi, posłużmy się przykładem kodu HTML formularza wraz z walidacją danych:
<input type="text" id="email" name="email" class="text required requiredEmail" />
Istnieje wiele bibliotek JavaScript, służących do walidacji formularza po stronie przeglądarki, które w ten właśnie sposób odnajdują pola, które powinny być wypełnione (posiadają klasę required) i sprawdzają, jaką zawartość powinny posiadać (requiredEmail). Rozwiązanie to oczywiście działało, ale powstawały zbędne, nic nie znaczące klasy CSS.
Jak już wspomniałem, HTML5 pomoże nam i w takim przypadku. A to dzięki możliwości stosowania własnych atrybutów z rodziny data-*. Zamysł jest prosty - autor strony może osadzić dowolną informację używając nowego atrybutu - dane te nie są nigdzie wyświetlane, są one dostępne dla JavaScript oraz CSS (za pomocą funkcji attr()).
Jako autorzy strony posiadamy praktycznie pełną dowolność w wyborze nazwy atrybutu - specyfikacja narzuca jedynie, by nie zawierał on dużych liter. Poprawny przykład:
<input type="text" id="email" name="email" data-validate="true" data-validate-type="email" />
Zgodnie ze specyfikacją, wartości powinny być teraz dostępne jako część zbioru dataset z użyciem notacji CamelCase (znanej także jako Notacja Wielbłądzia):
document.getElementById('email').dataset.validate;
document.getElementById('email').dataset.validateType;
Niestety, do czasu implementacji tego rozwiązania przez przeglądarki dane te nie są dostępne i musimy dostać się do nich w inny sposób:
document.getElementById('email').getAttribute('data-validate');
document.getElementById('email').getAttribute('data-validate-type');
Na szczęście powyższe "obejście" problemu działa bez problemu na wszystkich liczących się przeglądarkach.
Poza oczywistym przykładem przechowywania danych na potrzeby walidacji nowy atrybut umożliwia np. sortowanie zestawów danych (tabel) po danych nie widocznych, lub wyświetlanych dla użytkownika w sposób trudny do zrozumienia dla skryptów, np:
<li data-date="2010-07-07T07:58:12"><a href="#">Spis wydarzeń w dniu 7 lipca, roku 2010</a></li>
O zaletach dobrej dokumentacji nie trzeba się rozpisywać. Każdy z nas (programistów) zapewne nie raz musiał poprawiać kawałek kodu napisany przez kogoś innego lub też nawet przez siebie samego, jednak z czasem zapomnieliśmy już o co chodziło. Często wtedy patrzymy na kawałek kodu, który wygląda np. tak:
$z = hexdec(80000000);
if ($z & $a)
{
$a = ($a>>1);
$a &= (~$z);
$a |= 0x40000000;
$a = ($a>>($b-1));
}
else
{
$a = ($a>>b);
}
I zastanawiamy się co właściwie autor brał - powinien z tym skończyć.
Skoro wszyscy wiemy jak przydatna jest dokumentacja, zastanawia mnie czemu ani na Politechnice (w swoim krótkim czasie), ani na innej uczelni nie mieliśmy przedmiotów, albo chociażby kilku wykładów/ćwiczeń poświęconych na jej tworzenie? Zapewne dlatego teraz tak mało osób stosuje porządną dokumentację.
Swego czasu powstało doskonałe narzędzie/format dla programistów - Javadoc. Przy użyciu odpowiedniego formatowania komentarzy można było kilkoma kliknięciami wygenerować piękną dokumentację dla swojego projektu - mało tego, z czasem co raz więcej IDE zaczęło implementować ten format dokumentacji i używać dynamicznych podpowiedzi (np. Intelisense). Oczywiście powstawały kolejne klony i porty narzędzia - w tym port dla PHP - phpDocumentator. Jak wygląda wygenerowana dokumentacja można przekonać się np. ze samej strony projektu - oczywiście aplikacja umożliwia dowolne modyfikowanie szablonu dokumentu.
Ok, to tyle tytułem wstępu - tym razem nie będę się skupiał na obsłudze samego phpDocumentatora, ale na opisaniu formatu i podstawowych znaczników, na których operuje.
Podstawowe parametry
Javadoc (oraz pochodne) przeszukuje nasze pliki pod kątem formularzy zapisanych w konkretny sposób - mianowicie wyszukuje on wszystkie komentarze blokowe, dla przypomnienia chodzi o:
/**
*
*/
Bloki te mogą znajdować się przed klasami, funkcjami i zmiennymi (wtedy opisują te elementy) lub też na początku pliki (w takim wypadku zwane są "page-level"). Każdy z bloków może zawierać dowolny komentarz tekstowy, wyświetlany w wyjaśnieniu danego elementu - może także zawierać dowolną ilość oraz kombinację specjalnych parametrów pomagających w formatowaniu, osadzaniu dodatkowych treści oraz podpowiadaniu parametrów wejściowych i wyjściowych funkcji
Każdy parametr zapisuje się poprzedzając go znakiem @, np:
/**
* Poniższa funkcja robi ...
* @PARAMETR WARTOŚĆ PARAMETRU
*/
function foo() { (...) }
Poniżej wymienię najczęściej stosowane parametry, po pełny spis odsyłam do dokumentacji phpDocumentatora. Pragnę zwrócić także uwagę, że niektóre parametry (@abstract, @final) stały się zbędne, ponieważ z wprowadzeniem PHP5 można używać specjalnych słów kluczowych, które do tej pory zastępowały właśnie w/w parametry.
@author - parametr opisujący autora danego fragmentu kodu lub osobę, która ów kod modyfikowała, przyjmuje następującą postać:
* @author Bartosz Szczeciński <btm@anfo.pl>
@deprecated - opisuje element, który znajduje się w kodzie ze wzg. na kompatybilność wsteczną - zaleca się stosowanie nowszego odpowiednika:
* @deprecated Stara funkcja, sugeruję używać nowej wersji
@see - odniesienie do innego fragmentu kodu, np. w połączeniu z @depracated może wskazać funkcję, którą powinniśmy używać zamiast poprzedniej:
* @see innaKlasa::innaFunkcja
@example - po parametrze należy podać ścieżkę do pliku zawierającego przykład zastosowania danego kawałku kodu:
* @example przyklady/userApiTest.php
@link - podobnie jak @see, jednak odnosi nas do podanego adresu URL
* @link http://manual.phpdoc.org/HTMLframesConverter/default/
@param - jeden z najczęściej wykorzystywanych znaczników, określa typ i rolę parametru, jaki powinniśmy przekazać do funkcji. Ponieważ PHP nie posiada na razie obsługi deklaracji typów złożonych w funkcjach jako pierwszą wartość parametru podajemy jego typ
/**
* @param int $foo określa zasadę działania funkcji
* @param int|string $bar dodatkowy parametr, powinien to być int lub string
*/
function testFunction($foo, $bar) {(...)}
@return - kolejny z najczęściej wykorzystywanych parametrów - podobnie jak @param określa typ zwracanej przez funkcję wartości. Ponieważ funkcje zwracają tylko jedną (i to nie nazwaną) wartość, jego użycie jest dużo prostsze:
/**
* @return int zwraca losową wartość, uzyskaną przez rzut kostką 1K6
*/
function random() {
return 4;
}
@todo - parametr informujący nas, że podany fragment kodu jest niekompletny lub wymaga poprawek, niektóre programy IDE pozwalają nam na szybkie wyświetlenie wszystkich fragmentów kodu oznaczonych tym parametrem, więc od razu wiemy co jeszcze musimy poprawić
* @todo funckja random() powinna losować wartość za każdym razem
@var - tak, jak przy pomocy @param mogliśmy określić typ i zastosowanie parametru wejściowego wybranej funkcji, za pomocą @var możemy określić zmienne umieszczone w kodzie. Wszelkie zmienna nie opisane tym parametrem i nie posiadające odpowiedniej deklaracji zostaną opisane jako mixed
/**
* @var int totalnie losowa liczba, serio
*/
$random = 4;
Podsumowanie
Jak już wspomniałem na wstępie - standard phpDoc definiuje jeszcze wiele dodatkowych parametrów pozwalających na lepszą organizację naszego kodu, jednak poznanie i stosowanie chociażby tej garstki podstawowych z nich pozwali nam (i naszym współpracownikom) na dużo łatwiejsze i wygodniejsze poruszanie się po kodzie - a wygenerowana z naszego kodu dokumentacja zaoszczędzi nam wielu godzin spędzonych na szukaniu odpowiednich fragmentów kodu czy też tłumaczeniu i odgadywaniu zasad działania kawałku oprogramowania, za który właśnie staliśmy się odpowiedzialni.
Za jakiś czas postaram się opisać jak skonfigurować phpDocumentator w celu wygenerowania dokumentacji z naszego projektu.
Przy okazji porządków na serwerze znalazłem kolekcję swoich starych skryptów i innych dokumentów publikowanych jeszcze na starym blogu. Ponieważ wiem, że niektóre z nich jeszcze mogą się komuś przydać postanowiłem pomóc Google, które linkuje niemiłosiernie do nie istniejących już adresów i wrzucić skrypty do sieci.
Chciałbym przypomnieć, że skrypty te mogą być nie aktualne, mogą nie odzwierciedlać aktualnie stosowanych metod, nie działać czy też być proste do odtworzenia w totalnie lepszy sposób - jest to do przewidzenia, zważywszy, że większość z nich ma ponad dwa lata.
Poniżej lista z krótkimi opisami:
Jeszcze raz - to są stare skrypt, które mogą być już nie aktualne - proszę o nie wytykanie błędów ;-)