뷰: 레이아웃
- 본 번역문서의 원문은 Layout docs.asp.net 입니다.
- 본 번역문서는 MVC : View - 레이아웃 www.taeyo.net 에서도 함께 제공됩니다.
뷰들 간에 시각적 요소나 프로그래밍적인 요소들이 공유되는 경우는 매우 흔합니다. 본문에서는 ASP.NET Core MVC 응용 프로그램에서 공통 레이아웃 및 공유 지시문을 사용하는 방법과, 뷰가 렌더되기 전에 공통 코드를 실행하는 방법을 살펴봅니다.
레이아웃
대부분의 웹 응용 프로그램들은 사용자가 한 페이지에서 다른 페이지로 이동할 때 일관된 경험을 제공해주기 위한 공통 레이아웃(Layout)을 갖고 있습니다. 레이아웃에는 일반적으로 응용 프로그램 헤더나 탐색 및 메뉴 요소, 푸터 같은 공통적인 사용자 인터페이스 요소들이 포함됩니다.
또한 스크립트나 스타일시트 같은 공통 HTML 구조들도 응용 프로그램 내부의 많은 페이지들에서 빈번하게 사용됩니다. 이런 공유되는 요소들 중 상당수는 레이아웃(Layout) 파일에 정의되어, 응용 프로그램에서 사용되는 모든 뷰에서 참조가 가능해집니다. 레이아웃은 뷰들 간의 코드 중복을 줄여주고, 중복배제(DRY, Don't Repeat Yourself)의 원칙을 준수할 있도록 도와줍니다.
규약에 따른 ASP.NET 응용 프로그램의 기본 레이아웃 파일 이름은 _Layout.cshtml
입니다.
가령, Visual Studio ASP.NET Core MVC 프로젝트 템플릿에도 Views/Shared
폴더에 이 레이아웃 파일이 포함되어 있습니다:
이 레이아웃은 응용 프로그램 내부의 뷰들에 대한 최상위 수준의 템플릿을 정의합니다. 응용 프로그램에는 레이아웃이 아예 없을 수도 있고, 하나 이상의 레이아웃을 정의해서 각각의 뷰마다 각기 다른 레이아웃을 지정할 수도 있습니다.
다음은 _Layout.cshtml
의 예제입니다:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebApplication1</title>
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">WebApplication1</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
@await Html.PartialAsync("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2016 - WebApplication1</p>
</footer>
</div>
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("scripts", required: false)
</body>
</html>
레이아웃 지정하기
Razor 뷰에서는 Layout
이라는 속성이 제공됩니다.
뷰마다 각각 이 속성을 설정해서 레이아웃을 지정할 수 있습니다:
@{
Layout = "_Layout";
}
레이아웃을 지정할 때는 전체 경로를 설정하거나(/Views/Shared/_Layout.cshtml
), 이름 부분만 설정할 수 있습니다(_Layout
).
이름 부분만 설정할 경우, Razor 뷰 엔진이 기본 검색 과정에 따라서 레이아웃 파일을 검색하게 됩니다.
먼저 컨트롤러 관련 뷰들을 검색한 다음, Shared
폴더를 검색합니다.
이 기본 검색 과정과 부분 뷰(Partial Views) 검색에 사용되는 과정은 동일합니다.
기본적으로 모든 레이아웃은 RenderBody
메서드를 호출해야만 하며,
RenderBody
메서드가 호출되는 바로 그 위치에 뷰의 콘텐츠가 렌더됩니다.
섹션
필요한 경우, 레이아웃 내에서 RenderSection
메서드를 호출하여 하나 이상의 섹션(Sections)을 참조할 수 있습니다.
섹션을 활용하면 특정 페이지 요소가 렌더될 위치를 자유롭게 구성할 수 있습니다.
RenderSection
메서드를 호출할 때, 해당 섹션이 필수적인지 선택적인지 여부를 지정할 수 있으며, 만약 필수로 지정된 섹션이 발견되지 않으면 예외가 발생하게 됩니다.
각 뷰에서는 @section
Razor 구문을 이용해서 섹션에 렌더될 콘텐츠를 지정해야 합니다.
만약 뷰에 섹션이 정의되어 있다면 반드시 렌더되야 합니다 (아니면 오류가 발생합니다).
다음은 뷰에 정의된 @section
의 예제입니다:
@section Scripts {
<script type="text/javascript" src="/scripts/main.js"></script>
}
이 코드는 폼이 존재하는 뷰의 scripts
섹션에 유효성 검사 스크립트를 추가한다고 가정하고 있습니다.
그러나 응용 프로그램의 다른 뷰들에는 이 스크립트가 불필요할 수도 있으며, 그런 경우에는 당연히 scripts 섹션을 정의하지 않으면 됩니다.
역주
예제에 사용된 JavaScript 파일의 이름이 main.js가 아닌 validation.js 등의 이름이었다면 더 그럴듯 했을 것 같습니다.
뷰에 정의된 섹션들은 해당 뷰와 직접 관련된 레이아웃 페이지에서만 사용할 수 있습니다. 부분 뷰나 뷰 구성 요소, 또는 뷰 시스템의 다른 부분들에서는 참조할 수 없습니다.
섹션 무시하기
기본적으로 콘텐츠 페이지에 존재하는 본문과 모든 섹션들은 레이아웃 페이지를 통해서 모두 렌더되어야 합니다. Razor 뷰 엔진은 본문 및 각 섹션들이 렌더됐는지 여부를 추적해서 이를 강제합니다.
뷰 엔진에게 본문이나 섹션을 무시하도록 지시하려면 IgnoreBody
메서드나 IgnoreSection
메서드를 호출하면 됩니다.
Razor 페이지의 본문과 모든 섹션들은 반드시 렌더되거나 무시돼야만 합니다.
뷰가 실행되기 전에 공통 코드 실행하기
모든 뷰가 실행되기 전에 먼저 실행돼야만 하는 코드가 존재한다면, _ViewStart.cshtml
파일에 해당 코드를 작성하면 됩니다.
규약에 따라서 _ViewStart.cshtml
파일은 Views
폴더에 위치하며, 이 파일에 작성된 구문들은 모든 뷰가 실행되기 전에 먼저 실행됩니다 (레이아웃과 부분 뷰는 이에 해당되지 않습니다).
_ViewImports.cshtml
파일처럼 _ViewStart.cshtml
파일도 계층적입니다.
컨트롤러 관련 뷰 폴더에 _ViewStart.cshtml
파일이 정의되었다면, 이 파일에 정의된 코드는 Views
폴더의 최상위에 정의된 _ViewStart.cshtml
파일에 정의된 코드가 (존재할 경우) 실행된 다음에 실행됩니다.
다음은 _ViewStart.cshtml
파일의 예제입니다:
@{
Layout = "_Layout";
}
이 예제 파일은 모든 뷰에서 _Layout.cshtml
레이아웃을 사용하도록 지정하고 있습니다.
노트
일반적으로 _ViewStart.cshtml
파일이나 _ViewImports.cshtml
파일은 /Views/Shared
폴더에 위치하지 않습니다.
이 파일들의 응용 프로그램 수준 버전은 /Views
폴더에 바로 위치해야 합니다.
- 뷰: 뷰 개요 2016-08-26 08:00
- 뷰: Razor 구문 참조 2016-08-31 08:00
- 뷰: 레이아웃 2016-09-05 08:00
- 뷰: 뷰에 서비스 주입하기 2016-09-09 08:00
- 뷰: 태그 헬퍼 소개 2016-09-20 08:00
- 뷰: 태그 헬퍼 구현하기 2016-09-26 08:00
- 뷰: 태그 헬퍼로 폼 관련 작업하기 2016-10-03 08:00
- 뷰: 부분 뷰 2016-10-10 08:00
- 뷰: 뷰 구성 요소 2016-10-17 08:00