Podczas projektowania strony często zdarza się tak, że niektóre jej fragmenty powtarzają się niezmiennie w paru dokumentach. Jeśli cenimy swój czas i przewidujemy możliwość edycji, nie chcemy kopiować HTML-a do każdego z nich. Najlepiej wtedy wczytać dane z pliku i wstawić je do poszczególnego dokumentu.
Można to zrobić korzystając z paru metod. Na początek warto rozgraniczyć dołączane dokumenty na dwa typy - pełne strony oraz ich wycinki. Zaletą pierwszych jest możliwość wyświetlenia poza dokumentem-matką - posiadają DOCTYPE, własne style, pliki JS i tak dalej. Zaletą drugich jest prostota w zainkludowaniu. Po prostu wklejamy zawartość pliku w jakimś miejscu.
Dokumenty pierwszego typu można dołączyć przez elementy iframe i object. Po prostym przekształceniu także przez Ajax i XInclude. Oczywiście na przekształcenia zezwalają także skrypty po stronie serwera, ale te postanowiłem wydzielić dla drugiego typu dokumentów.
W przykładach nie będę zagłębiał się w problem dostosowania wysokości dołączanego elementu dla iframe i object, istnieją do tego skrypty JS.
Iframe
Przestarzały element, obecny tylko w HTML 4.01 Transitional. Niezalecany, podobnie jak całe ramki. Chicałbym jednak opisać jak dołączamy stronę, aby wykazać jego minusy względem object.
Użycie to po prostu wstawienie <iframe src="strona.html"></iframe>. W CSS pozbędziemy się obramowania przez border: none. Jeśli chodzi o Internet Explorera należy na podlinkowanej stronie upewnić się, że zawartość nie będzie za szeroka, inaczej pojawi się brzydki poziomy scrollbar. Zrobiłem to tak:
html {overflow-x: hidden;padding-right: 5%;}
Jest to typowy hack i nie działa przewidywalnie. Wygląda jednak mniej więcej dobrze: demo.
Object
Przeznaczenie tego elementu to właśnie dołączanie do dokumentu wszelkich plików - głównie multimediów, ale możemy także wykorzystać go do wstawienia pliku HTML.
Użycie to wstawienie <object type="text/html" data="strona.html"></object>. Pomiędzy możemy wstawić content, który będzie wyświetlony, jeśli przeglądarka nie poradzi sobie z pokazaniem podlinkowanego pliku. O dziwo, takie rozwiązanie działa w IE. I to działa bez classid, podejrzewam że dzięki trybowi zgodności ze standardami: demo.
Należało tylko nadać wyświetlanie blokowe object, aby uciąć tą minimalną przestrzeń dolną (znaną z obrazków bez display: block), a w IE pozbyć obramowania dla body na dołączanej stronie.
Ajax
Możemy wreszcie skorzystać z zapytania asynchronicznego ściągającego plik. Jeśli na serwerze mamy możliwość umieszczać pliki XHTML, będące prawidłowym XML-em oraz korzystamy z gotowej biblioteki, dodanie dokumentu to kwestia paru linijek kodu.
Uwielbiam jQuery i tym razem z niego skorzystałem. Opis $.ajax znajduje się w dokumentacji jQuery - ja chciałbym tylko odnieść się do fragmentu wstawiającego dane do strony. Jak widać, response od serwera znajduje się w zmiennej msg. Jest to XML, dlatego aby dostać się do żądanego kawałka strony (znajdującego się w <div id="w"></div>) musiałem pobrać z tego obiektu XML responseXML, będącym w gruncie rzeczy drzewem DOM. Dlatego później użyłem tradycyjnej metody DOM - getElementsByTagName.
A co gdybyśmy nie mieli pliku XML? Możemy ściągnąć go jako text oraz skorzystać z responseText. Przy użyciu wyrażeń regularnych możemy wyciąć fragment strony i wstawić go przez innerHTML do jakiegoś elementu.
Demo. Należy zaznaczyć, że ograniczyłem wysokość tego kontenera, aby wyglądało tak samo jak poprzednie przykłady. Lecz główną zaletą wstawiania zawartości via Ajax jest po prostu dopasowanie się kontenera do tego co w środku - nie trzeba zgadywać wysokości w JS. Ajax pozwala też w razie błędu zadecydować co pokazać użytkownikowi. Ja dodałem info o błędzie i link do ściąganego dokumentu.
XInclude
Jest jeszcze jedna fajna metoda, ale na razie tylko na kartce papieru - żadna znana mi przeglądarka tego nie obsługuje. Mowa o XInclude czyli XML Inclusion - dołączaniu dokumentów XML przez odpowiednie elementy. Cel może być parsowany jako XML albo jako tekst, podobnie jak w przykładzie z Ajaksem.
Na podstawie specyfikacji stworzyłem dokument, który powinien chyba działać na przeglądarce umiejącej XInclude - demo. Zobaczycie oczywiście Error. Ale za parę lat, kto wie…
Ta metoda jest bardzo ciekawa, pozwala korzystać z XPointer - uproszczonej metody trawersowania drzewa XML (coś jak XPath, ale prostsze) - można wyciąć sobie kawałek strony. Ma też fallback działający podobnie jak zasada zagnieżdzania object.
Serwer
Na koniec najbardziej sprawdzona metoda (dla mnie najnudniejsza :P) - wykorzystanie skryptów po stronie serwera. Nie zajmuję się tym w pracy ani na blogu, ale warto wiedzieć, że <?php include('plik.html') ?> w PHP wstawi źródło w dane miejsce strony (wcześniej też z niego możemy coś wyciąć via regexp).
Można też skorzystać z mod_include - komentarzy w HTML, które są rozpoznawane przez Apache i wykonywane.
<!--#include file="strona.html" --><!--#include virtual="/strona.html" -->


