반응형

웹 사이트를 개발하다 보면 모든 페이지에 공통적으로 포함되는 부분이 있기 마련이다.
일단 간단히 생각해 보면 아래와 같은 공통 요소가 떠오른다.
1. 페이지 상단 : 회사 로고나 대표 이미지 및 주 메뉴
2. 페이지 하단 : Copyright 정보나 바로가기 등
 
일반적인 웹 사이트의 모든 페이지는 위의 2가지 요소를 공통적으로 포함하게 된다.
 
아래 그림을 보자.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
이 처럼 모든 페이지에 공통적으로 포함되는 부분을 위해 예로부터(?) 다양한 방법들이 동원되었었다.
 
그간 사용되어진 방법들을 몇 가지만 살펴 보자.
 
1. Include 방식
 - ASP 시절부터 많이 사용되어진 방법이다. (물론 아직까지 많은 사이트가 Include 방식을 이용하고 있다)
   공통부분을 별도의 파일로 생성한 후 이 파일을 모든 페이지에 인클루딩 시키는 방법이다.
   다음 샘플코드는 top.inc , copyright.inc 라는 Include 용 파일을 생성한 후 일반 페이지에서 인클루딩 하는 코드이다.
  

= Include 파일 =

top.inc

<table width=100% ID="Table1" height="100%">

        <tr>

               <td>회사로고</td>

        </tr>

</table>

copyright.inc

<table width=100% ID="Table1" height="100%">

        <tr>

               <td>Copyright</td>

        </tr>

</table>

 

= 일반 페이지 =

<table border=1 width = 80% height=90%>

             <tr>

                          <td>

                                        <!-- #include file = "./Include/top.inc" -->

                          </td>

             </tr>

             <tr height=80%>

                          <td>페이지별 내용(Inlude 페이지)</td>

             </tr>

             <tr>

                          <td>

                                        <!-- #include file = "./Include/copyright.inc" -->

                          </td>

             </tr>

</table>

 

 
2. 웹 UserControl 방식
 - .NET 은 웹사이트의 이러한 요구사항을 위한 해결책으로 UserControl 이라는 걸 지원하게 되었다.
    큰 흐름은 Include 방식과 유사하나 .NET 의 특성을 그대로 계승한 형태로 진화 되었다.
    공통부분을 별도의 UserControl로 생성한 후 이 컨트롤을 모든 페이지에 Register(등록) 시키는 방법이다
    다음 샘플코드는 top.ascx, copyright.ascx 라는 UserControl파일을 생성한 후 일반 페이지에서 등록 하는 코드이다.
  

= UserControl 파일 =

top.ascx

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="top.ascx.cs" Inherits="WebApplication1.UserControl.top" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>

<table width=100% ID="Table1" height="100%">

        <tr>

               <td>회사로고</td>

        </tr>

</table>

copyright.inc

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="copyright.ascx.cs" Inherits="WebApplication1.UserControl.copyright" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>

<table width=100% ID="Table1" height="100%">

             <tr>

                           <td>Copyright</td>

             </tr>

</table>

 

 

= 일반 페이지 =

<%@ Register TagPrefix="uc1" TagName="top" Src="UserControl/top.ascx" %>

<%@ Register TagPrefix="uc1" TagName="copyright" Src="UserControl/copyright.ascx" %>

<table border="1" width="80%" height="90%">

             <tr>

                          <td>

                                        <uc1:top id="Top1" runat="server"></uc1:top>

                          </td>

             </tr>

             <tr height="80%">

                          <td>페이지별 내용(UserControl 페이지)</td>

             </tr>

             <tr>

                          <td>

                                        <uc1:copyright id="Copyright1" runat="server"></uc1:copyright>

                          </td>

             </tr>

</table>

 
  
3. HttpModule 방식
 - 조금은 생소할 수도 있으나 닷넷의 요청과 응답사이에 ISAPI 필터처럼 동작하는 HttpModule 로도 이와 같은 공통처리를 할 수도 있다.
   물론 HttpModule 가 UI 의 공통요소를 처리하기 위한 메터니즘과는 어울리지 않는다(일종의 필터라고 생각하면 된다)
   그러나 이번 글에서는 이러한 방식도 있다는 차원에서 언급하도록 한다.
   동작방식을 간략히 설명하자면,
   요청의 처음과 끝에 개입하여 특정 로직을 수행하도록 하는데 이 부분에 공통 UI 를 기술하게 된다.
   다음 샘플코드는 IHttpModule 를 구현하는 CustomHttpModule 클래스를 만들고 이 모듈이 모든 페이지 요청에 개입하도록 하는 코드이다.
   
 

= CustomerHttpModule 클래스 =

public class CustomHttpModule : IHttpModule

{

        public CustomHttpModule(){}

        public void Init(HttpApplication context)

        {

               context.BeginRequest += (new EventHandler(this.Application_BeginRequest));

               context.EndRequest += (new EventHandler(this.Application_EndRequest));   

        }

        public void Application_BeginRequest(object sender,EventArgs e)

        {

               HttpApplication application = (HttpApplication)sender;

               HttpContext context = application.Context;

               context.Response.Write("<table width=80% border=1><tr><td>회사로고</td></tr></table>");               

        }

        public void Application_EndRequest(object sender,EventArgs e)

        {

               HttpApplication application = (HttpApplication)sender;

                       HttpContext context = application.Context;

                       context.Response.Write("<table width=80% border=1><tr><td>Copyright</td></tr></table>");                    

        }              

}

 

 

= Web.Config 설정=

<httpModules>

        <add name="CustomHttpModule"  type="WebApplication1.CustomHttpModule, WebApplication1" />    

</httpModules>

 

이렇게 Web.Config 에 설정하면 모든 요청은 CustomHttpModule 모듈에 의해 필터링 된다.

 

 
4. MasterPage 방식(닷넷 2.0 에 새로 추가된 기능)
 - 드디어 주인공이 등장한다. 이전까지의 액스터라들은 MasterPage 를 위한 들러리(?)일 뿐이었다 --;
   닷넷 2.0 에서는 보다 근본적인 해결책과 다른 접근 방법으로 이와 같은 요구사항을 충족시키는 매커니즘을 새로 내놓았다.
   이것이 바로 Master Page 라는 것이다.
   Master Page 는 이전 방법들과는 다른 접근 방법을 채택하고 있따.
   이전 방식에서는 공통되는 부분을 별도로 분리하여 모든 페이지에 명시적으로 포함하도록 코딩했었다.
   그러나 Master Page 에서는 주/객이 바뀌었다고 보면 된다.
   Master Page 가 전체 골격을 유지하며 공통요소를 포함하게 되며 일반페이지들은 이 Master Page 를 Content 페이지로써 동작하도록 한다.
   다음 샘플코드는 MasterPage.master 이라는 마스터 페이지를 정의하고 Content 로 생성되는 일반페이지에 대한 코드 이다.

 

= Master 페이지 =

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>

<table border="1" width="80%" height="90%">

        <tr>

                <td>

                       <table width="100%" height="100%">

                               <tr>

                                      <td>회사로고</td>

                               </tr>

                       </table>                                            

                </td>

        </tr>

        <tr height="300">

                <td >

                    <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">

                     </asp:contentplaceholder>

                </td>

        </tr>

        <tr>

                <td>

                       <table width="100%" height="100%">

                               <tr>

                                      <td>Copyright</td>

                               </tr>

                       </table>

                </td>

        </tr>

</table>

 

 

= 일반 페이지 =

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

페이지별 내용(일반 페이지)

</asp:Content>

 

마스터 페이지를 이용하는 Content 페이지는 VS IDE의 디자인모드에서 다음처럼 표시된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MasterPage 에서 정의한 상,하단의 내용(회사로고 및 Copyright) 는 비활성화 된 모습이다.

그리고 실제 페이지의 Content 를 위한 영역에 각 페이지별 내용이 기술되도록 한다.

 

 

이로써 페이지 공통요소를 효율적으로 처리하는 몇가지 방법들에 대해서 살펴 보았다.

물론 이 글에서 소개하지 않은 또 다른 방식도 존재하리라 본다.

개인적인 생각으로는 닷넷 2.0에서 제공하는 Master Page 가 다른 모든 방법들 보다 장점을 많이 지닌 듯 하다

(예를 들면 일반페이지들은 공통부분에 대한 어떠한 처리에도 신경쓰지 않아도 된다는 점 등...)

 

Master Page  에 대해서는 기회가 되면 다시 정리하도록 하겠다.

 

 

첨부파일에 이 글에서 사용된 샘플코드가 포함되어 있다.

반응형

+ Recent posts