Makale Özeti

ASP.NET 2.0 ile birlikte gelen Master Pages kavramına detaylı bir bakış...

Makale

ASP.NET 2.0 Master Pages

Gelişmiş bir web portalı ya da herhangi bir web uygulaması geliştirdiğimizi düşünelim. Hazırladığımız ekranlar genellikle bir ana tasarım şablonu ve bu şablonun belli kısımları içerisinde değişen içerik bölümleriden oluşacaktır.  Bu noktada en önce yapmamız gereken;  ana şablonumuzun tasarımını yapmak ve daha sonrada içeriğin geleceği kısımları ASP.NET kodlarımızla programlamak. Bu şekilde hazırladığımız ekranlar eğer büyük bir web projesinden bahsediyorsak belki yüzlerce alt ekrandan oluşacaktır. İşte tam bu esnada önemli bir problemle yüzyüze geldiğimizin farkına varırız. Eğer ana şablonumuzda sonradan bir değişiklik yapmamız gerkirse ne olacak??? Bu değişikliği tüm alt ekranlara yansıtmak için yapmamız gereken, tabiki tek tek yüzlerce ekranı açarak aynı değişikliği hepsinde yapmak ve bu ekranları kaydederek kapatmak olmayacaktır.

ASP.NET 2.0 getirdiği master sayfalar kavramı ile, bu konuda çok daha az kod yazarak çok daha hızlı uygulama geliştirmek konusunda en büyük yardımcımız halini alıyor. Gelin şimdi hepbirlikte bu problemle başa çıkabilmek için elimize daha önce ne gibi silahlar bulunduğunu inceleyelim ve ASP.NET 2.0’ın nasıl yepyeni bir modelle karşımıza çıktığını görelim.

ASP.NET 1.x Kullanıcı Kontrolleri

ASP.NET 1.0 ve 1.1 sürümlerinde uygulama kodunu tek bir noktadan yönetebilmemiz için user control adı verilen bir yapıya sahipdik.  Bu yapı ile, tüm sayfalarda kullanılacak ortak şablon bir kere hazırlıyor ve tüm sayfalara sadece bu kulalnıcıkontrol eklenerek altsayfalar oluşturuluyor. Fakat bu yapı ile ana tasarım şablonunu oluşturarak tüm alt ekranların aynı şablondan çoğaltılması gibi birşey mümkün değil malesef. Ana şablon salt HTML ile yazılıp sayfada kullanılacak yatay – dikey menüler, sabit ya da değişken veriler ve ya logo, banner gibi grafiksel görüntüler user control haline getirilip her bir alt ekrana eklenerek içerik sayfaları oluşturulabiliyor. Fakat bu yapının tam olarak işimize yaraması, çözmeye çalştığımız probleme çare olması mümkün değil. Çünkü user control içerisinde tutulan ana tasarım şablonu değil sadece tüm ekranlarda kullanılacak statik yada dinamik veri gruplarıdır.

Her ne kadar işimizi tam olarak görmese de ASP.NET 1.x ile uygulama geliştirirken, hepimiz bu kullanıcı kontrolü yönetimden sıkca faydalandık.

Klasik ASP Include Dosyaları

Biraz da nostalji yaparak şöyle biraz gerilere gidelim J ASP.NET duyurulmadan önce Microsoft dilleri ile uygulama geliştirenler web programlama için ASP (Active Server Pages) dilini kllanıyorlardı. Büyük web portalları tasarlamak ve kodu tek bir yerden yönetebilmek için burada da çeşitli çözümler mevcut. Burada uygulama kodumuzu farklı dosyalara bölüyor yani ana şablonumuzu oluşturacak olan asıl kodları başka bir dosyada tutuyoruz. Daha sonra da bu dosyayı içerik sayfalarımıza <#include> yönergesi ile dahil ederek, kodumuzun derlenirken include edilen dosyalarında hesaba katılarak derlenmesini sağlıyoruz. Bu sayade içerik kodlarımız ayrı bir dosyada, ana şablon kodlarımız ayrı bir dosyada tutulmuş oluyor. Ve daha sonra bir değişiklik yapmamız gerektiğinde, sadece şablon bilgisini içeren include dosyasında değişiklik yapmamız yeterli oluyor.

Eski ama kullanışlı olan bu yapı, ASP.NET 2.0 ile birlikte gelen master pages yapısına, 1.1 versiyonunda bulunan kullanıcı kontrollerinden çok daha yakın bir yapı aslında. Fakat bunun da birtakım problemleri yok değil. En önemlisi kodlar diğer dosyalarda yalın text dosyaları halinde tutuluyor ve sayfa her çağrıldığında tekrar tekrar derlenerek HTML çıktısı oluşturuluyor. Bu da tabiki ciddi performans prolemlerine yol açıyor, yani bir bellekleme yapısı master sayfaların aksine bu eski yöntemde yok.

Bir diğer önemli problem ise, include dosyaları içerisinde de HTMLkodlarının kullanılması fakat kod yapısını bozmamk için bazı HTML eikentlerinin kapatılmadan bırakılması. Daha önce kullanmış olanlar bilirlerki, include dosyaları içerisinde bazen <TABLE><TR><TD> açılır fakat kapatma işlemi yapılmazdı. Bu etiketin kapandığı kod bir başka include dosyası içerisinde tutulurdu. Sayfa sonuç çıktısı oluşturulurken bu bir sorun yaratmıyor, çıktı başarıyla üretilebiliyor, fakat geliştirme esnasında kullanılan araç (örneğin visual interdev) için pek de user friendly bir kullanım ortaya çıkarmıyor. Uygulamayı geliştirirken kullandığımız araç, include dosyaları sebebiyle bize güzel bir geliştirme ortamı sunamıyordu, bu da işimizi zorlaştıran diğer bir problem olarak karşımızdaydı.

Fakat ASP.NET 2.0 ile birlikte bu iş artık çok kolay. Biraz tarih bilgisinden sonra artık bu yeni teknolojinin nasıl işlediğini kavramaya başlayabiliriz. J

Yeni Trend Master Pages

Bu yeni modelde önce ana tasarım şablonumuz olacak dosyayı hazırlıyoruz. Bu dosyanın adına da master page adı veriliyor. Diğer asp.net dosya tipinden farkını uzantısının .master oluşu ve ilk satırının <%@ Page%> yerine <%@ Master %> direktifiyle başlıyor olduğunu söyleyebiliriz.  Master uzantılı bu dosyamızın içine ContentPlaceHolder adı verilen parçacıklar ekliyoruz. Bu parçacıkları içerik kısımlarımızın geleceği yerler ya da içerik sayfalarında değişecek dinamik kısımlar olarak belirtebiliriz.

Yani özet olarak ana şablonun yani ana tasarımi menüler, alt ve üst başlık, site navigasyon kısımlar, reklam banner’ları gibi kısımların bulunduğu kısım master page oluyor. Master page içerisinde içerik eklenecek kısımlar ContentPlaceHolder olarak tanımlanıyor. Son olarak da bu master sayfa üzerinden içerik sayfaları, yani bu master sayfayı referans alan aspx webformları türetiliyor.

Aşağıdaki şekilde bu modelin genel olarak nasıl çalıştığını görebilirsiniz.

Şekil – 1 Master Page Sayfa Modeli

Önemli!!!

Tüm proje için global bir bildirim yaparak, projedeki tüm web formlarının otomatik olarak aynı master page üzerinden türetilmesini sağlamak için, web.config dosyamızda aşağıdaki gibi bi değişiklik yapmamız yeterli olacaktır.

<configuration>
  <
system.web>
    <
pages masterpagefile="DemoMaster.master"></pages>
  </system.web>
</
configuration>

Eğer istersek <%@ Page %> direktifi içerisinde aşağıdaki gibi bir bildirim yaparak farklı istemci cihazlar için farklı master page üzerinden sayfanın türetilmesini sağlayabiliriz. 

<%@ Page ie:masterpagefile="ieBase.master"        netscape:masterpagefile="nsBase.master"
masterpagefile="Base.master" %>

İçiçe (Nested) Master Pages

Eğer istersek aşağıdaki şekilde de görülebildiği şekliyle içiçcemaster sayfalar kullanmak da mümkün olabilecektir.

Şekil – 1 İçiçe Master Sayfalar

Bu şekilde içiçe master sayfa kullanımı ile ilgili herhangi bir kısıtlama bulunmamakta.Yani isediğiniz kadar master sayfa oluşturup birbirlerine bağlayarak, bunlar üzerinden güvenle sınırsız sayıda içerik sayfaları türetebilirsiniz.

Bu kadar teorik bilginin ardından, öğrendiklerimizi bir gerçek hayat uygulaması ile pekiştirmenin zamanı gelmiştir diye düşünüyorum.

Gerçek Bir ASP.NET 2.0 Master Page Web Uygulaması

Bir web portal projesi hazırladığımızı düşünüyoru. Tasarımını önceden yaptık, sol da içeriğimiz ile ilgili bir kategori menüsü (bu kısım kolaylıkla bir veri kaynağından gelen verilerle yüklenecek şekilde de hazırlanabilir.) , sayfanın üstünde de (header kısmı) tüm içerik sayfalarımızda görünecek standart bir yatay menü bulunmakta.

Şimdi bunlar için master sayfamızı hazırlayalım ve ekran görüntüsünün nasıl çıktığına bir göz atalım.

<%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <LINK href="style.css" type=text/css rel=stylesheet />
</head>
<
BODY background=images/bg_main.gif topMargin=0 leftmargin=0>
    <form id="form1" runat="server">
<TABLE cellSpacing=0 cellPadding=0 width=781 border=0 height="53">
  <TR>
    <TD noWrap width="227" bgcolor="#F5F5F5" height="53" align="left">
    <p align="center">
    <font face="Fixedsys"><b><font color="#FF6600" size="5">&nbsp;</font></b></font>
        &nbsp;</TD>
    <TD noWrap width="554" bgcolor="#F5F5F5" height="53" valign=bottom align="right">
     <table border="1" cellspacing="0" bordercolor="gray" style="border-collapse: collapse" cellpadding="0" height="22" width="554">
      <tr>
        <td bgColor="#F5F5F5" onMouseOver="bgColor='#D4D4D4'"
onMouseOut="bgColor='#F5F5F5'" width="84" align="center" height="22">
        <a href="#" class=ust_menu>Hakkımızda</a></td>
        <td bgColor="#F5F5F5" onMouseOver="bgColor='#D4D4D4'" onMouseOut="bgColor='#F5F5F5'" width="143" align="center" height="22">
        <a href="#" class=ust_menu>En Çok Satanlar</a></td>
        <td bgColor="#F5F5F5" onMouseOver="bgColor='#D4D4D4'"
onMouseOut="bgColor='#F5F5F5'" width="150" align="center" height="22">
        <a href="#" class=ust_menu>En Çok Ziyaret Edilenler</a></td>
        <td bgColor="#F5F5F5" onMouseOver="bgColor='#D4D4D4'" onMouseOut="bgColor='#F5F5F5'" width="130" align="center" height="22">
        <a href="#" class=ust_menu>Bize Ulaşın</a></td>
        </tr>
    </table>
    </TD></TR></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=779 border=0>
  <TR>
    <TD width=779 background=images/sub_top_dots.gif>
    <IMG height=20 alt="" src="images/bg_trans.gif" width=779
    border=0></TD></TR></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=779 border=0 height="20" bgcolor="#000000" style="border-collapse: collapse" bordercolor="#111111">
   <TR>
    <TD noWrap bgcolor="#000000" height="15" align="right" colspan="5">&nbsp;</TD>
  </TR></TABLE>
          <TABLE cellSpacing=0 cellPadding=0 width=780 style="border-collapse: collapse" bordercolor="#111111">
  <TR>
    <TD vAlign=top width=149 bgcolor="d6d6d6">
    <table border="1" bordercolor="#000000" width="149" cellspacing="0" style="border-collapse: collapse; border-style: solid; padding: 0" cellpadding="0">
        <tr>
          <td width="9" height="20" bgcolor="#FF6600">&nbsp;</td>
          <td width="140" height="20" bgcolor="#003366">
          <font color="#FFFFFF" size="1" face="Verdana"><b>
          &nbsp; PC Ürün Kategorileri</b></font></td>
        </tr>
        <tr>
          <td width="9" height="17">&nbsp;</td>
          <td width="140" height="17" onMouseOver="bgColor='#f5f5f5'" onMouseOut="bgColor='#d6d6d6'">&nbsp;
           <a href="#" class=sol_menu>İşlemci</a></td>
        </tr>
        <tr>
          <td width="9" height="17">&nbsp;</td>
          <td width="140" height="17" onMouseOver="bgColor='#f5f5f5'" onMouseOut="bgColor='#d6d6d6'">&nbsp;
           <a href="#" class=sol_menu>Anakart</a></td>
        </tr>
        <tr>
          <td width="9" height="17">&nbsp;</td>
          <td width="140" height="17" onMouseOver="bgColor='#f5f5f5'" onMouseOut="bgColor='#d6d6d6'">&nbsp;
           <a href="#" class=sol_menu>Ekran Kartı</a></td>
        </tr>
        <tr>
          <td width="9" height="20" bgcolor="#FF6600">&nbsp;</td>
          <td width="140" height="20" bgcolor="#003366">
          <font color="#FFFFFF" size="1" face="Verdana"><b>
          &nbsp; Network Ürünleri</b></font></td>
        </tr>
        <tr>
          <td width="9" height="17">&nbsp;</td>
          <td width="140" height="17" onMouseOver="bgColor='#f5f5f5'" onMouseOut="bgColor='#d6d6d6'">&nbsp;
           <a href="#" class=sol_menu>Ethernet</a></td>
        </tr>
        <tr>
          <td width="9" height="17">&nbsp;</td>
          <td width="140" height="17" onMouseOver="bgColor='#f5f5f5'" onMouseOut="bgColor='#d6d6d6'">&nbsp;
           <a href="#" class=sol_menu>Wireless Adapter</a></td>
        </tr>
        </table>
    </TD>
    <TD width=5><IMG height=1 alt="" src="images/bg_trans.gif"
      width=10 border=0></TD>
    <TD vAlign=top width=701 height=600>
      <TABLE width="100%" border=0 height="100%">
        <TR height="100%">
          <TD height="100%" valign=top style="padding:5 5 5 5">
            <asp:contentplaceholder id="AnaIcerik" runat="server">
        </asp:contentplaceholder>
           </TD></TR>
        </TABLE>
      </TD>
    <TD vAlign=top width=20 align="center">
      <br>  
     </TD></TR></TABLE>    
    <table border="1" width="779" height="13" background="images/alt_bg.gif"
        cellspacing="0" cellpadding="0" style="border-collapse: collapse" bordercolor="#111111">
        <tr>
          <td height="9">
          &nbsp;
          </td>
        </tr>
      </table>
      <p align="center">&nbsp;</p>
    </form>
</body>
</
html> 

 

Şekil – 3 Tasarım Zamanında Master Page Görüntüsü

Kodlarını görmüş oldğunuz master sayfanın tasarım zamanındaki görüntüsü yukarıdaki gibi olacaktır. Burada dikkat edilmesi gereken bir diğer kısımda detay sayfalarda içerik kısmının geleceği yerin görüntüsüdür. ContentPlaceHolder – AnaIcerik şeklinde gri bir satır içerisinde gösterilen kısım, aspx detay sayfalarımızda içerikle doldurulacak olan kısımdır.

Şimdi de aspx içerik sayfalarımızın bu master sayfa üzerinden nasıl türetildiğini ve kodlandığını inceleyelim.

Şekil – 4 İçerik Sayfasının Türetilmesi

Yukarıdaki şekilde de görüldüğü gibi solution explorer üzerindeki master sayfamıza sağ tıklayarak Add Content Page bağlantısı ile yeni bir içerik sayfasını kolaylıkla oluşturabiliyoruz.

Oluşturduğumuz içerik sayfasının da aşağıdaki gibi kodlarsak eğer sonuçtaki ekran görüntüsüne ulaşabileceğiz.

Şekil – 5 Tasarım Zamanında İçerik Sayfası Görüntüsü

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="Demo.aspx.vb" Inherits="Demo" title="Master & Content Pages Demo Sayfası" %>
<asp:Content ID="Content1" ContentPlaceHolderID="AnaIcerik" Runat="Server">
    <br /><br />
    <center><asp:Label ID="lblDemo" runat="server" Font-Bold=true
        Font-Names="verdana" Font-Size=X-Small ForeColor=red ></asp:Label>
     </center>
</asp:Content>
  

Partial Class Demo
    Inherits System.Web.UI.Page 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        lblDemo.Text = "İlk içerik sayfamız artık hazır!..."
    End Sub

End Class

Sonuç olarak tüm web projemizi derleyip çalıştırdığımızda karşımıza çıkacak olan ekran görüntüsü de aşağıdaki gibi olacaktır.

Şekil – 6 Son Haliyle Demo.aspx Ekran Görüntüsü

Özet

Bu makalede ASP.NET 2.0 ile birlikte gelen master sayfalar kavramına değinerek daha başarılı uygulamalar geliştirebilmemiz için Visual Studio 2005’in bizlere sunduğu bu yeni ortamı inceledik. Artık ASP.NET 1.1 deki gibi kullanıcı tanımlı kontrol ya da klasik ASP deki gibi include dosyaları kullanmak zorunda değiliz. Artık elimizde son derece başarılı ve ölçeklenebilir bir yapı olan master sayfalar var.

Okuyan herkes için faydalı olduğunu umuyorum. Her türlü soru ve öneriniz için bana mail adresimden ulaşabilirsiniz.

Yarını yakalamak dileğiyle... 

Kaan TEZGEL
kaan@kaantezgel.com