[ASP.NET CORE] 무료 템플릿으로 만드는 ASP.NET Core MVC WebSite #5: Layout

이번 글에서는 “Medcare” HTML 무료 Template 기반의 MVC Web Application에서 WebSite의 공통 Layout 요소인 _Layout.cshtml 파일을 제작하는 방법을 통해 코드의 효율성과 유지보수성을 높이는 과정을 자세히 설명합니다.

“Medcare” template을 이용한 MVC Web Application 구축, 다섯 번째 입니다. 지난 4편에서는 각 메뉴의 기본적인 뼈대인 Controller와 해당 controller 의 index ActionMethod 에 대응하는index.cshtml View 파일을 만드는 과정을 살펴봤습니다. 이제 웹사이트의 기본적인 구조를 갖추었으니, 이번 편에서는 모든 페이지에 공통으로 적용될 Layout 을 template 에서 어떻게 가져와서 _Layout.cshtml 파일을 구성하는지 살펴보겠습니다.

1. 공통 부분 :

MVC Web Application에서는 일반적으로 _Layout.cshtml이라는 파일을 사용하여 웹사이트의 공통 Layout 을 정의합니다. 이 파일은 Web page의 전체적인 구조를 담고 있으며, 각 페이지의 내용이 삽입될 영역을 지정하는 역할을 합니다. 필요에 따라서 여러 Layout page 를 만들어 놓고 각 View 마다 다르게 설정할 수도 있습니다.

  • Views 폴더 아래 Shared 폴더를 확인하거나 없다면 생성합니다.
  • Shared 폴더에 Razor View Page (_Layout.cshtml)를 확인합니다. 없으면 생성합니다.

제가 생성한 Project 에는 이미 Shared 폴더에 _Layout.cshtml 파일이 있으므로 더블클릭으로 파일을 엽니다.Source 가 길어 복잡해 보이지만 Editor 화면의 Line Number 우측의 화살표를 클릭하면 축소되어 내용을 감출 수가 있습니다. 그럼 아래와 같이 간략하게 보기 쉽게 됩니다.

크게 head tag 와 body tag 로 나뉘고, 다시 body tag 내에는 header, div, footer 이렇게 세부분으로 나뉩니다. 이 부분이 핵심입니다.

잘 기억해 두세요.

이 번에는 “Medcare” 의 HTML Source 를 살펴보겠습니다.

Source 를 편하게 보기 위해서 Visual Studio Code 로 열어서 보겠습니다. Download 받아 압축을 푼 폴더를 마우스 오른쪽 클릭을 하면 나타나는 Context menu 에서 “Code(으)로 열기” 메뉴를 클릭합니다.

아래와 같이 VS Code 가 열리고 해당 폴더 내의 파일 구조가 표시됩니다.

index.html  이 첫 페이지지만 너무 길어서 보기가 어려울 수 있으니 about-us.html 파일을 열어보겠습니다. menu 의 about 에 해당하는 페이지 입니다.

페이지 내용은 아래와 같습니다.

보기 편하도록  Visual Studio 2022 에서와 같이 Line Number 오론쪽의 화살표를 클릭하여 내용을 축소해 봅니다.

어떻습니까? 구조가 익숙하죠?

다시 Visual Studio 2022 의 모습을 보죠.

Header 와 Footer 그리고 그 사이에 내용이 배치되어 유사한 구조라는 걸 알 수 있습니다. 다른 메뉴의 화면들은 어떤지 살펴볼까요?

Department.html
Docters.htmlContact.html

모두 같은 구조를 가지고 있습니다.

사각형의 내의 Source 내용을 제외한 부분들이 거의 대부분 동일하다는 말은 WebSite 에서 공통적으로 사용할 _Layout.cshtml 에 넣으면 모든 Page 에서 재 사용할 수 있다는 의미입니다. 그리고 Source 적용 후에 header 와 footer 를 별도의 코드로 분리하여 관리할 수 있습니다.

2. 각 화면의 영역 :

이제 공통 부분을 찾았으니 차이가 나는 각 화면의 부분을 어떻게 적용하는지에 대해서 살펴보겠습니다.

html source 에서 사각형의 내용들을 어떻게 처리하느냐를 이야기하는 건데요. Rendering  된다라고 이야기합니다.

_Layout.cshtml 파일에서 각 페이지의 내용이 Rendering될 위치를 지정해야 합니다. 이는 @RenderBody() 라는 Helper Method를 사용하여 간단하게 처리할 수 있습니다. 이 Method는 각 View page의 HTML 콘텐츠를 해당 위치에 삽입해 줍니다.

아래 처럼 _Layout.cshtml 파일을 보면 사각형 내의 @RenderBody() 를 보실 수 있습니다.

<div> tag 내에 다시 <main> tag 가 있지만 “Medcare” Source  에는 <main> tag 가 없으므로 아래와 같이 간단히 구성하도록 하겠습니다.

<body>
    <header>
    </header>

    <div class="container">
        @RenderBody()
    </div>

    <footer>
    </footer>
</body>

3. _Layout.cshtml(공통 레이아웃) 파일:

위 내용을 바탕으로 _Layout.cshtml 파일을 수정해 보도록 하겠습니다. 여러 html page 중에서 어떤 파일을 선택해도 좋지만 제일 간단하다고 생각되는 about-us.html 파일을 가지고 진행하겠습니다.

사각형 내의 내용을 제외한 내용을 _Layout.cshtml 에 복사해 넣고 사각형 부분의 내용은 아래 코드로 대치하겠습니다.

    <div class="container">
        @RenderBody()
    </div>

그럼 아래와 같습니다.

Code Snippet
  1. <!doctype html>
  2. <html lang=”en”>
  3. <head>
  4.     <!– Required meta tags –>
  5.     <meta charset=”utf-8″>
  6.     <meta name=”viewport” content=”width=device-width, initial-scale=1, shrink-to-fit=no”>
  7.     <link rel=”icon” href=”img/favicon.png” type=”image/png”>
  8.     <title>Medcare Medical</title>
  9.     <!– Bootstrap CSS –>
  10.     <link rel=”stylesheet” href=”css/bootstrap.css”>
  11.     <link rel=”stylesheet” href=”css/themify-icons.css”>
  12.     <link rel=”stylesheet” href=”css/flaticon.css”>
  13.     <link rel=”stylesheet” href=”vendors/fontawesome/css/all.min.css”>
  14.     <link rel=”stylesheet” href=”vendors/owl-carousel/owl.carousel.min.css”>
  15.     <link rel=”stylesheet” href=”vendors/animate-css/animate.css”>
  16.     <!– main css –>
  17.     <link rel=”stylesheet” href=”css/style.css”>
  18.     <link rel=”stylesheet” href=”css/responsive.css”>
  19. </head>
  20. <body>
  21.  
  22.     <!–================Header Menu Area =================–>
  23.     <header class=”header_area”>
  24.         <div class=”top_menu row m0″>
  25.             <div class=”container”>
  26.                 <div class=”float-left”>
  27.                     <a class=”dn_btn” href=”mailto:medical@example.com”><i class=”ti-email”></i>medical@example.com</a>
  28.                     <span class=”dn_btn”> <i class=”ti-location-pin”></i>Find our Location</span>
  29.                 </div>
  30.                 <div class=”float-right”>
  31.                     <ul class=”list header_social”>
  32.                         <li><a href=”#”><i class=”ti-facebook”></i></a></li>
  33.                         <li><a href=”#”><i class=”ti-twitter-alt”></i></a></li>
  34.                         <li><a href=”#”><i class=”ti-linkedin”></i></a></li>
  35.                         <li><a href=”#”><i class=”ti-skype”></i></a></li>
  36.                         <li><a href=”#”><i class=”ti-vimeo-alt”></i></a></li>
  37.                     </ul>
  38.                 </div>
  39.             </div>
  40.         </div>
  41.         <div class=”main_menu”>
  42.             <nav class=”navbar navbar-expand-lg navbar-light”>
  43.                 <div class=”container”>
  44.                     <!– Brand and toggle get grouped for better mobile display –>
  45.                     <a class=”navbar-brand logo_h” href=”index.html”><img src=”img/logo.png” alt=””></a>
  46.                     <button class=”navbar-toggler” type=”button” data-toggle=”collapsedata-target=”#navbarSupportedContentaria-controls=”navbarSupportedContent” aria-expanded=”false” aria-label=”Toggle navigation”>
  47.                         <span class=”icon-bar”></span>
  48.                         <span class=”icon-bar”></span>
  49.                         <span class=”icon-bar”></span>
  50.                     </button>
  51.                     <!– Collect the nav links, forms, and other content for toggling –>
  52.                     <div class=”collapse navbar-collapse offset” id=”navbarSupportedContent”>
  53.                         <ul class=”nav navbar-nav menu_nav ml-auto”>
  54.                             <li class=”nav-item”><a class=”nav-link” href=”index.html”>Home</a></li>
  55.                             <li class=”nav-item”><a class=”nav-link” href=”about-us.html”>About</a></li>
  56.                             <li class=”nav-item”><a class=”nav-link” href=”department.html”>Department</a></li>
  57.                             <li class=”nav-item”><a class=”nav-link” href=”doctors.html”>Doctors</a></li>
  58.                             <li class=”nav-item submenu dropdown”>
  59.                                 <a href=”#” class=”nav-link dropdown-toggle” data-toggle=”dropdownrole=”button” aria-haspopup=”true” aria-expanded=”false”>Blog</a>
  60.                                 <ul class=”dropdown-menu”>
  61.                                     <li class=”nav-item”><a class=”nav-link” href=”blog.html”>Blog</a></li>
  62.                                     <li class=”nav-item”><a class=”nav-link” href=”single-blog.html”>Blog Details</a></li>
  63.                                     <li class=”nav-item”><a class=”nav-link” href=”element.html”>element</a></li>
  64.                                 </ul>
  65.                             </li>
  66.                             <li class=”nav-item”><a class=”nav-link” href=”contact.html”>Contact</a></li>
  67.                         </ul>
  68.                     </div>
  69.                 </div>
  70.             </nav>
  71.         </div>
  72.     </header>
  73.     <!–================Header Menu Area =================–>
  74.  
  75.  
  76.     <div class=”container”>
  77.         @RenderBody()
  78.     </div>
  79.  
  80.     <!– start footer Area –>
  81.     <footer class=”footer-area area-padding-top”>
  82.         <div class=”container”>
  83.             <div class=”row”>
  84.                 <div class=”col-lg-2 col-sm-6 single-footer-widget”>
  85.                     <h4>Top Products</h4>
  86.                     <ul>
  87.                         <li><a href=”#”>Managed Website</a></li>
  88.                         <li><a href=”#”>Manage Reputation</a></li>
  89.                         <li><a href=”#”>Power Tools</a></li>
  90.                         <li><a href=”#”>Marketing Service</a></li>
  91.                     </ul>
  92.                 </div>
  93.                 <div class=”col-lg-2 col-sm-6 single-footer-widget”>
  94.                     <h4>Quick Links</h4>
  95.                     <ul>
  96.                         <li><a href=”#”>Jobs</a></li>
  97.                         <li><a href=”#”>Brand Assets</a></li>
  98.                         <li><a href=”#”>Investor Relations</a></li>
  99.                         <li><a href=”#”>Terms of Service</a></li>
  100.                     </ul>
  101.                 </div>
  102.                 <div class=”col-lg-2 col-sm-6 single-footer-widget”>
  103.                     <h4>Features</h4>
  104.                     <ul>
  105.                         <li><a href=”#”>Jobs</a></li>
  106.                         <li><a href=”#”>Brand Assets</a></li>
  107.                         <li><a href=”#”>Investor Relations</a></li>
  108.                         <li><a href=”#”>Terms of Service</a></li>
  109.                     </ul>
  110.                 </div>
  111.                 <div class=”col-lg-2 col-sm-6 single-footer-widget”>
  112.                     <h4>Resources</h4>
  113.                     <ul>
  114.                         <li><a href=”#”>Guides</a></li>
  115.                         <li><a href=”#”>Research</a></li>
  116.                         <li><a href=”#”>Experts</a></li>
  117.                         <li><a href=”#”>Agencies</a></li>
  118.                     </ul>
  119.                 </div>
  120.                 <div class=”col-lg-4 col-md-6 single-footer-widget”>
  121.                     <h4>Newsletter</h4>
  122.                     <p>You can trust us. we only send promo offers,</p>
  123.                     <div class=”form-wrap” id=”mc_embed_signup”>
  124.                         <form target=”_blank” action=”https://spondonit.us12.list-manage.com/subscribe/post?u=1462626880ade1ac87bd9c93a&amp;id=92a4423d01″
  125.                               method=”get” class=”form-inline”>
  126.                             <input class=”form-control” name=”EMAIL” placeholder=”Your Email Address” onfocus=”this.placeholder = ”” onblur=”this.placeholder = ‘Your Email Address'”
  127.                                    required=”” type=”email” />
  128.                             <button class=”click-btn btn btn-default”>
  129.                                 <i class=”ti-arrow-right”></i>
  130.                             </button>
  131.                             <div style=”position: absolute; left: -5000px;”>
  132.                                 <input name=”b_36c4fd991d266f23781ded980_aefe40901a” tabindex=”-1″ value=”” type=”text” />
  133.                             </div>
  134.  
  135.                             <div class=”info”></div>
  136.                         </form>
  137.                     </div>
  138.                 </div>
  139.             </div>
  140.             <div class=”row footer-bottom d-flex justify-content-between”>
  141.                 <p class=”col-lg-8 col-sm-12 footer-text m-0″>
  142.                     <!– Link back to Colorlib can’t be removed. Template is licensed under CC BY 3.0. –>
  143.                     Copyright &copy;<script>document.write(new Date().getFullYear());</script> All rights reserved | This template is made with <i class=”fa fa-heart” aria-hidden=”true”></i> by <a href=”https://colorlib.com” target=”_blank”>Colorlib</a>
  144.                     <!– Link back to Colorlib can’t be removed. Template is licensed under CC BY 3.0. –>
  145.                 </p>
  146.                 <div class=”col-lg-4 col-sm-12 footer-social”>
  147.                     <a href=”#”><i class=”fab fa-facebook-f”></i></a>
  148.                     <a href=”#”><i class=”fab fa-twitter”></i></a>
  149.                     <a href=”#”><i class=”fab fa-dribbble”></i></a>
  150.                     <a href=”#”><i class=”fab fa-linkedin”></i></a>
  151.                 </div>
  152.             </div>
  153.         </div>
  154.     </footer>
  155.     <!– End footer Area –>
  156.  
  157.     <!– Optional JavaScript –>
  158.     <!– jQuery first, then Popper.js, then Bootstrap JS –>
  159.     <script src=”js/jquery-2.2.4.min.js”></script>
  160.     <script src=”js/popper.js”></script>
  161.     <script src=”js/bootstrap.min.js”></script>
  162.     <script src=”js/stellar.js”></script>
  163.     <script src=”vendors/owl-carousel/owl.carousel.min.js”></script>
  164.     <script src=”js/jquery.ajaxchimp.min.js”></script>
  165.     <script src=”js/waypoints.min.js”></script>
  166.     <script src=”js/mail-script.js”></script>
  167.     <script src=”js/contact.js”></script>
  168.     <script src=”js/jquery.form.js”></script>
  169.     <script src=”js/jquery.validate.min.js”></script>
  170.     <script src=”js/mail-script.js”></script>
  171.     <script src=”js/theme.js”></script>
  172. </body>
  173. </html>

_Layout.cshtml 파일을 수정했지만 WebSite 에서 사용하는 javascript, StyleSheet, Image 파일들을 복사하고 경로를 잡아주는 과정이 진행되어야 합니다.

4. Image, Javascript, StyleSheet :

“Medcare” Template Source 에서 아래 그림과 같이 “css, fonts, img, js, vendors” 폴더를 복사합니다.

그리고 Visual Studio 2022 의 Solution Explorer (솔루션 탐색기)에서 wwwroot를  오른쪽 click  하여  “Open  Folder  in  File  Explorer(파일탐색기에서  폴더열기)” 를 cliek  합니다.File Explorer (파일탐색기)가 열리면  wwwroot 폴더에 복사한 파일을 붙여 넣습니다.결과는 다음과 같습니다.

5. 실행 :

지금까지 작업이 잘 되었는지 확인해 보겠습니다. 

Debugging Button 을 Click 하거나 F5 Button 을 눌러 실행시켜 봅니다.

잘 실행되십니까? index page 도 잘 표시되고 favicon 도 표시되네요. 메뉴를 Click 하시고 싶겠지만 메뉴의 link 를 수정하지 않아 표시할 수 없다는 오류가 나올겁니다. 지난 시간에 확인했던 것 처럼 주소창에 “https://localhost:7154/About” 를 입력하시면 해당 메뉴로 이동할 겁니다.

마무리

이번 편에서는 “Medcare” template 기반의 MVC Web Application에 공통 Layout인 _Layout.cshtml 파일을 수정하여 Layout 을 적용하는 과정을 살펴봤습니다. 깊이 살펴보아야 할 기본 내용은 많습니만 진행과정을 단순하게 하여 WebSite 제작에 쉽게 접근하도록 구성해 봤습니다. 내용이 길어 Header와 Footer를 적용하고, CSS와 JavaScript 파일을 분리하는 과정은 다음 편에서 살펴보겠습니다. 

Happy GoSu ~

WooGong ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

[ASP.NET CORE] 무료 템플릿으로 만드는 ASP.NET Core MVC WebSite #3: HTML 구조 분석과 MVC 디자인 준비

Themewagon의 Medcare Template 의 HTML 구조를 분석하여 메뉴 구성, 화면 영역(Header, Body, Footer)별 특징을 설명하고, 이를 ASP.NET Core MVC의 View와 Controller로 구성하기 위한 준비 단계를 소개합니다.

무료 템플릿으로 만드는 ASP.NET Core MVC WebSite #3: HTML 구조 분석과 MVC 디자인 준비

지난 2편에서는 ASP.NET Core MVC Web Application의 핵심인 Program.cs 파일을 살펴보았습니다. 지난 글은 아래 에서 확인해 주세요.

.NET 8 웹 개발 시작하기: Visual Studio 2022 & VS Code로 MVC 프로젝트 만들기
.NET 8 ASP.NET Core MVC 시작점, Program.cs 완벽 해부: 서비스 등록부터 요청 파이프라인 구성까지!

이번 3편에서는 본격적으로 Website의 뼈대가 될 HTML 파일의 구조를 파악하는 시간을 가져보려 합니다. 우리가 사용할 Template은 Themewagon.com에서 제공하는 “Medcare”라는 Medical Website 무료 Template입니다. Download는 여기에서 받으실 수 있습니다.

medcare html template download
medcare html template download

e-commerce website 를 사용할까도 생각해 보았지만 Healthcare 에 관심도 있고 가장 유사하지 않나 하는 생각에 선택하게 되었습니다. e-commerce 만큼 적용할 수 있는 재미는 적을 수 있지만 일단 무엇이든 시작해 보려고 합니다.

Medcare Template, 어떤 모습일까?

압축을 풀고 폴더를 살펴보면, 우리 눈에 익숙한 css, fonts, img, js, scss 폴더와 함께 index.html, about.html, department.html, doctors.html, blog.html, contact.html과 같은 메뉴별 HTML 파일들을 확인할 수 있습니다. 특히, CSS를 동적으로 관리할 수 있도록 scss 폴더가 제공되는 점과,Template적용에 유용한 document 파일이 포함된 점이 좋네요.

먼저 index.html 을  열어 첫 화면을 살펴보겠습니다. index.html 을 double click 합니다.

index.html

Website의 전체적인 메뉴 구성은 Home, About, Department, Doctors, Blog, Contact 총 6개의 주요 메뉴로 이루어져 있습니다.

각 페이지는 공통적으로 Header, Body, Footer의 세 가지 영역으로 나뉩니다.

1. Header (머리말)

Header 영역은 Website의 얼굴이라고 할 수 있습니다. Medcare Template의 Header는 다음과 같은 요소들로 구성되어 있습니다.

  • 메뉴 (Navigation Bar): Website 의 주요 Page로 이동할 수 있는 link들을 제공합니다. 사용자가 원하는 정보를 쉽게 찾도록 돕는 중요한 역할을 합니다.
  • SNS 이모티콘 목록: 다양한 Social Media Platform 으로 연결되는 icon들이 배치되어 있습니다. 기관의 Social 활동을 홍보하고 사용자들과의 소통 채널을 제공합니다.
  • 메뉴별 대표 image및 text: Header 아래에는 각 메뉴 Page의 특징을 시각적으로 보여주는 image와 간략한 설명 text가 함께 나타납니다. 현재 어떤 Page를 보고 있는지 직관적으로 알 수 있도록 디자인되어 있습니다.

2. 본문 (Body): 핵심 contents 를 담는 공간

Body 영역은 각 Menu Page의 실제 내용을 담는 곳입니다. 예를 들어, “About” Page에서는 기관의 소개, 역사, 비전 등의 정보가 표시될 것이고, “Doctors” Page에서는 의료진의 정보와 전문 분야 등이 소개될 것입니다. Themewagon Template은 각 Page의 목적에 맞게 깔끔하고 정돈된 Layout을 제공합니다.

3. 꼬리말 (Footer): Website의 마침표

Footer 영역은 Website의 하단에 위치하며, 일반적으로 다음과 같은 정보들을 포함합니다.

  • Top Products, Quick Links, Resources, NewsLetter: 유용한 정보나 자주 찾는 Link, News Letter 구독 등의 기능을 제공하여 사용자 편의성을 높입니다. Healthcare 기관의 경우, 주요 서비스나 관련 정보 Link 등이 포함될 수 있습니다.
  • Copy Right: Website의 저작권 정보를 명시하여 지적 재산권을 보호합니다.
  • SNS 이모티콘 목록: Header와 마찬가지로 Social Media 채널로의 접근성을 제공합니다.

MVC 구조 설계를 위한 첫걸음: View와 Controller

이제  Download 한 HTML 파일들을 ASP.NET Core MVC Web Application의 View와 Controller로 어떻게 구성할지 고민해 볼 차례입니다.

  • View: 각 HTML 파일(.html)은 사용자에게 보여지는 화면, 즉 View의 역할을 하게 됩니다. 예를 들어, index.html은 Home Page View가 되고, about.html은 About Page View가 되는 식입니다.
  • Controller: 사용자의 Request을 처리하고, Model에서 데이터를 가져와 View에 전달하는 역할을 합니다. 각 메뉴에 대응하는 Controller를 만들고, 해당 Controller의 Action Method에서 적절한 View를 반환하도록 구현해야 합니다.

마무리

다음 편에서는 Medcare Template의 HTML 파일들을 분석한 내용을 바탕으로, ASP.NET Core MVC Project에서 View를 생성하고 Controller를 연결하는 과정을 자세히 다루어 보겠습니다. Themewagon Templage 을 Website로 구성하는 방법을 살펴보면서 실제 업무에서 디자이너가 작업한 Website HTML Source 를 어떻게 다루는지에 대한 감을 갖게 되리라 생각됩니다.

Happy GoSu ~

WooGong ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\