Artykuł

paź 21 2010
0

Szablony stron w ASP.NET i PHP (Smarty)

Każdy webmaster, który rozpoczyna swoją przygodę z tworzeniem stron od statycznego HTML, szybko przekonuje się, że nie jest to do końca, najlepsze wyjście. O ile w przypadku statycznych stron stworzonych na kształt wizytówek, albo stron stworzonych na specjalną okazję i nie wymagających późniejszej edycji może się sprawdzić (szybkie i tanie rozwiązanie), o tyle w przypadku stron wymagających zmienności w treści, czy też interakcji z użytkownikiem (Web 2.0 i te sprawy..) szybko okazuje się bezużyteczny. W takiej sytuacji z pomocą może przyjść kompilowany ASP.NET, lub skryptowy PHP, czyli języki które pozwolą na zapewnienie odpowiednich, wspomnianych wyżej funkcjonalności. Jednak i one nie mogą zostać pozostawione same sobie, gdyż przy ich standardowym użyciu możemy zyskać dynamikę i zmienność ale z pewnością może nam zabraknąć komfortu tworzenia elastycznych i rozszerzalnych stron.

Lekarstwem na całe zło, mogą być jednak szablony stron, które z powodzeniem można zaimplementować w obu językach. I o tym dzisiaj napiszę troszkę szerzej.

Idea wykorzystania szablonów stron

Spróbujmy teraz zobrazować sobie pewną sytuację. Wyobraźmy sobie, że mamy stronę pokroju Alt Control Delete o pewnej stałej budowie. Już na pierwszy rzut oka można wyróżnić kilka elementów, które się nie zmieniają, lub zmieniają się w niewielkim stopniu (zależnie od wybranej podstrony). Do takich elementów możemy zaliczyć:

  • Top (nagłówek strony)
  • Sidebar (pasek boczny)
  • Footer (stopka)

Zmiennym elementem jest centralna część witryny, w której wyświetlany jest np. dany wpis, czy lista wpisów. Są to niewątpliwie elementy, które na pewno będą wyglądać inaczej na każdej stronie. Co jednak zrobić z naszym nagłówkiem, paskiem bocznym i stopką?

Podejść tutaj jest wiele. Wykorzystując goły PHP czy ASP.NET moglibyśmy zapisać te elementy w plikach inc i potem dołączać na każdej z podstron w następujący sposób:

PHP:

<?php
      require_once('file.inc');
?>

ASP.NET

<!-- #include File="file.inc" -->

Takie rozwiązanie ma jednak wady. Nie możemy wykorzystać tutaj żadnych mechanizmów języka (w przypadku ASP.NET) no i sam kod co by tu nie mówić jest po prostu drętwy, bo nie można np. przekazać żadnych parametrów do wskazanych elementów.

Lekiem na całe zło mogą się okazać szablony stron, które w wymierny sposób pozwalają rozwiązywać takie problemy. W języku PHP, aby skorzystać z szablonów, należy skorzystać z biblioteki Smarty, która w chwili obecnej dobija do wersji 3.

W ASP.NET sprawa jest jeszcze prostsza. Za szablony stron odpowiedzialna jest technologia Master Pages, która nie wymaga instalacji żadnych dodatkowych bibliotek (jest to po prostu element Frameworku).

Jakie zalety niesie ze sobą wykorzystanie szablonów? Osobiście wyszczególniłbym tutaj kilka punktów:

  • Łatwe zarządzanie wspólnymi elementami witryny
  • Możliwość rozdzielenia logiki biznesowej od warstwy prezentacji
  • Możliwość dowolnego parametryzowania poszczególnych elementów szablonu
  • Porządek w kodzie:)
  • Możliwość wykorzystania dodatkowych konstrukcji (np. w Smarty)

Podejście do tworzenia szablonów bywa jednak różne. A na czym dokładnie polegają różnice, dowiecie się po przeczytaniu dwóch kolejnych pod sekcji, w których zapoznamy się najpierw ze Smarty, a następnie Master Pages.

Szablony stron Smarty w PHP

Idea szablonów opartych o Smarty jest prosta - budujemy stronę z klocków. Tak więc mamy tutaj np. klocek header, klocek sidebar, klocek footer itp. Każdy taki klocek, jest plikiem z rozszerzeniem tpl. Wszystkie te elementy mogą być wykorzystywane w wielu różnych stronach i generalnie składają się one na finalny plik tpl reprezentujący określoną podstronę. Jak łatwo się domyślić, plik tpl określonej podstrony oprócz wspomnianych zlepków z innych tpli, posiada również pewną wartość dodaną charakterystyczną dla samego siebie.

To tyle ze wstępnej teorii. Spójrzmy jak sprawuje się to w praktyce.

Do wykonania poniższych kroków, potrzebować będziemy biblioteki Smarty, którą można pobrać stąd. Można też pobrać od razu gotowy projekt (włącznie z bibliotekami) z działu download niniejszej witryny.

Na początek kod PHP:

<?php
	require_once('smarty/Smarty.class.php');
	$oSmarty = new Smarty(); 
	$oSmarty->template_dir = 'templates';
	$oSmarty->compile_dir = 'templates_c';
	$oSmarty->assign('sHello', 'Witaj świecie!');
	$oSmarty->display('index.tpl');
?>

I tyle. To jest cały kod PHP, jaki musimy napisać by wyświetlić szablon. Można oczywiście pominąć linijkę, w której ustawiamy dodatkową zmienną sHello, ale o tym później. Prześledźmy kod linia po linii.

W linii 2, podpinamy główną klasę biblioteki Smarty po to, by w linii 3 utworzyć stosowny obiekt klasy Smarty. W liniach 4 i 5 ustawiamy właściwości tego obiektu. Pierwsza z nich: template_dir przechowuje informacje na temat katalogu w którym znajdują się szablony, druga zaś, informuje obiekt dokąd mają trafiać gotowe skompilowane szablony. W linii 6, deklarujemy przykładową zmienną sHello, zawierającą najpopularniejszy w programowaniu string, czyli Witaj świecie. Całość kończymy w linii 7, wyświetlając stosowny szablon. Jak widać ze strony PHP nie jest to nic złożonego:)

Spójrzmy teraz na plik index.tpl, będący tak na dobrą sprawę dokumentem HTML z paroma bajerami (Niniejszy przykład został napisany w HTML5):

<!DOCTYPE html>
<html lang="pl">
	{include file="head.tpl" sTitle="Strona główna"}
	<body>
		{include file="header.tpl"}
		<div id="main">
			{include file="aside.tpl"}
			<section>
				<p>Centralna sekcja zmienna</p>
				<p>{$sHello}</p>
			</section>
		</div>
		{include file="footer.tpl"}
	</body>
</html>

Jak widać kod nie jest przesadnie skomplikowany, głównie widać tutaj HTML5 oraz dwie powtarzalne konstrukcje szablonów Smarty. Wszystkie elementy szablonów, zawieramy w nawiasy klamrowe. Funkcja include pozwala na (jak nie trudno się domyślić) na dołączanie kolejnych plików tpl. W linii 10, wykorzystujemy również zmienną, którą wcześniej zadeklarowaliśmy w pliku PHP. Ciekawym aspektem jest również przekazanie zmiennej sTitle do pliku head.tpl. Plik ten prezentuje się następująco:

<head>
	<meta charset="utf-8" />
	<title>{$sTitle}</title>
	<style type="text/css">
	<!--
	aside, footer, header, section {
		display: block;
	} 
	#main{
		overflow: hidden;
	}
	aside{
		float: left;
	}
	section{
		float: right;
	}
	-->
	</style>
</head>

Naszą zmienną sTitle podstawiamy do znacznika head. Opis pozostałych plików już odpuszczę, ponieważ jest to czysty HTML.

Szablony stron z Master Pages w ASP.NET

Inne podejście do szablonów zastosowano w ASP.NET. W tym przypadku, wykorzystano tzw. Master Pages, które w Visual Studio 2010, są domyślnie dodawane do każdej z tworzonych witryn. Idea Master Pages jest prosta. Posiadamy jeden dokument główny (Master) będący plikiem z rozszerzeniem Master. Ten plik, to tak naprawdę szablon z wyznaczonymi elementami, które mogą zostać zmienione. Co ważne, wyznaczone miejsca do podstawienia mogą być przez określone podstrony (implementujące ten szablon) zmieniane, lub też nie. Spójrzmy na przykładowy plik Site.Master, który Visual Studio 2010 wygenerował dla nas (Cały projekt, podobnie jak w przypadku PHP, dostępny w dziale Download, lub po prostu po wygenerowaniu nowej aplikacji ASP.NET w Visual Studio 2010).

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="MasterPages.SiteMaster" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
    <title></title>
    <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form runat="server">
    <div class="page">
        <div class="header">
            <div class="title">
                <h1>
                    My ASP.NET Application
                </h1>
            </div>
            <div class="loginDisplay">
                <asp:LoginView ID="HeadLoginView" runat="server" EnableViewState="false">
                    <AnonymousTemplate>
                        [ <a href="~/Account/Login.aspx" ID="HeadLoginStatus" runat="server">Log In</a> ]
                    </AnonymousTemplate>
                    <LoggedInTemplate>
                        Welcome <span class="bold"><asp:LoginName ID="HeadLoginName" runat="server" /></span>!
                        [ <asp:LoginStatus ID="HeadLoginStatus" runat="server" LogoutAction="Redirect" LogoutText="Log Out" LogoutPageUrl="~/"/> ]
                    </LoggedInTemplate>
                </asp:LoginView>
            </div>
            <div class="clear hideSkiplink">
                <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
                    <Items>
                        <asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
                        <asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
                    </Items>
                </asp:Menu>
            </div>
        </div>
        <div class="main">
            <asp:ContentPlaceHolder ID="MainContent" runat="server"/>
        </div>
        <div class="clear">
        </div>
    </div>
    <div class="footer">
        
    </div>
    </form>
</body>
</html>

Tym co powinno przykuć naszą szczególną uwagę, są niewątpliwie wszystkie elementy asp:ContentPlaceHolder będące kontenerami, które mogą zostać zmienione przez poszczególne podstrony. Każdy taki kontener, powinien zostać oznaczony unikalnym id, dzięki któremu łatwo będzie się do niego odwołać w konkretnej podstronie.

A jak to wygląda w implementacji konkretnej podstrony? Bardzo prosto:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="MasterPages._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Welcome to ASP.NET!
    </h2>
    <p>
        To learn more about ASP.NET visit <a href="http://www.asp.net" title="ASP.NET Website">www.asp.net</a>.
    </p>
    <p>
        You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&amp;clcid=0x409"
            title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
    </p>
</asp:Content>

Pierwszą rzeczą na którą powinniśmy zwrócić uwagę w tym listingu, to dyrektywa Page znajdująca się na samym początku dokumentu. Wewnątrz tej dyrektywy, została użyta właściwość MasterPageFile, która wskazuje na plik szablonu, który przed chwilą omówiliśmy.

Drugim ważnym aspektem tego dokumentu, są kontrolki asp:content identyfikujące się swoim własnym unikalnym identyfikatorem i odwołujące się do kontrolek asp:ContentPlaceHolder z pliku Master (właściwość ContentPlaceHolderID. W tworzonej stronie, nie musimy przykrywać wszystkich utworzonych kontenerów. Jeśli domyślna treść jest odpowiednia dla danej podstrony, to w takim przypadku, nie dodajemy po prostu kontrolki asp:content, która nadpisałaby domyślny kontener. Możemy również dodać pustą kontrolkę asp:content, która po prostu wyczyści daną sekcję z domyślnego kodu:)

Podsumowanie

Celem niniejszego wpisu, było zaprezentowanie dwóch alternatywnych podejść do tworzenia szablonów na stronach WWW. Osobiście preferuje rozwiązanie zaserwowane przez Microsoft czyli tzw. Master Pages. Dużo łatwiej jest stworzyć jeden elastyczny szablon, w którym później można wymieniać tylko poszczególne elementy i nie martwić się o to, czy na pewno dodaliśmy wszystkie elementy układanki tak jak ma to miejsce w przypadku szablonów tworzonych w Smarty i PHP.

Warto również wspomnieć, że niniejszy wpis prezentuje tylko minimalny zarys obu technologii, dlatego zachęcam do własnego eksperymentowania no i do czytania dokumentacji technicznej:)

Data ostatniej modyfikacji: 05.06.2011, 17:21.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus