레이아웃 만들기¶
레이아웃이란?¶
레이아웃은 웹사이트의 전체적인 구조와 디자인을 담당하는 템플릿입니다. 모든 페이지에 공통으로 적용되는 헤더, 푸터, 사이드바 등을 포함합니다.
레이아웃 기본 구조¶
필수 파일¶
layouts/
└── my_layout/
├── conf/
│ └── info.xml # 레이아웃 정보
├── layout.html # 메인 레이아웃 파일
├── layout.css # 스타일시트
└── layout.js # 자바스크립트 (선택)
info.xml 작성¶
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.2">
<title xml:lang="ko">나의 레이아웃</title>
<description xml:lang="ko">커스텀 레이아웃입니다.</description>
<version>1.0</version>
<date>2024-01-01</date>
<author email="user@example.com" link="https://example.com">
<name xml:lang="ko">제작자명</name>
</author>
<license>MIT</license>
<!-- 레이아웃 설정 변수 -->
<extra_vars>
<var name="logo_image" type="image">
<title xml:lang="ko">로고 이미지</title>
<description xml:lang="ko">상단에 표시될 로고 이미지</description>
</var>
<var name="colorset" type="select">
<title xml:lang="ko">컬러셋</title>
<options value="default">
<title xml:lang="ko">기본</title>
</options>
<options value="dark">
<title xml:lang="ko">다크</title>
</options>
</var>
</extra_vars>
<!-- 메뉴 설정 -->
<menus>
<menu name="main_menu" maxdepth="3" default="true">
<title xml:lang="ko">메인 메뉴</title>
</menu>
<menu name="footer_menu" maxdepth="1">
<title xml:lang="ko">푸터 메뉴</title>
</menu>
</menus>
</layout>
layout.html 기본 구조¶
<!-- 레이아웃 설정 변수 초기화 -->
{@
// 레이아웃 정보를 짧은 변수로
$li = $layout_info;
// 메인 페이지 여부 체크
$is_index = ($mid == 'index' && !$act) || ($site_module_info->module_srl === $current_module_info->module_srl && !$act);
// 로그인 여부
$is_logged = $logged_info ? true : false;
}
<!-- CSS 로드 -->
<load target="layout.css" />
<load target="layout.js" />
<!-- 레이아웃 시작 -->
<div id="wrap" class="colorset-{$li->colorset ?: 'default'}">
<!-- 헤더 -->
<header id="header">
<div class="container">
<!-- 로고 -->
<h1 class="logo">
<a href="{getUrl()}">
<!--@if($li->logo_image)-->
<img src="{$li->logo_image}" alt="{$layout_info->site_title}" />
<!--@else-->
{$layout_info->site_title}
<!--@endif-->
</a>
</h1>
<!-- 메인 메뉴 -->
<nav class="gnb">
<ul>
<li loop="$main_menu->list => $key1, $val1" class="active"|cond="$val1['selected']">
<a href="{$val1['href']}" target="_blank"|cond="$val1['open_window'] == 'Y'">
{$val1['link']}
</a>
<!-- 2차 메뉴 -->
<ul class="depth2" cond="$val1['list']">
<li loop="$val1['list'] => $key2, $val2" class="active"|cond="$val2['selected']">
<a href="{$val2['href']}">{$val2['link']}</a>
</li>
</ul>
</li>
</ul>
</nav>
<!-- 사용자 메뉴 -->
<div class="user-menu">
<!--@if(!$is_logged)-->
<a href="{getUrl('act', 'dispMemberLoginForm')}">로그인</a>
<a href="{getUrl('act', 'dispMemberSignUpForm')}">회원가입</a>
<!--@else-->
<a href="{getUrl('act', 'dispMemberInfo')}">{$logged_info->nick_name}</a>
<a href="{getUrl('act', 'dispMemberLogout')}">로그아웃</a>
<a href="{getUrl('', 'module', 'admin')}" cond="$logged_info->is_admin == 'Y'">관리</a>
<!--@endif-->
</div>
</div>
</header>
<!-- 콘텐츠 영역 -->
<main id="content">
<div class="container">
<!--@if($is_index)-->
<!-- 메인 페이지 콘텐츠 -->
<include target="index.html" />
<!--@else-->
<!-- 모듈 콘텐츠 -->
{$content}
<!--@endif-->
</div>
</main>
<!-- 푸터 -->
<footer id="footer">
<div class="container">
<!-- 푸터 메뉴 -->
<nav class="footer-menu" cond="$footer_menu">
<ul>
<li loop="$footer_menu->list => $key, $val">
<a href="{$val['href']}">{$val['link']}</a>
</li>
</ul>
</nav>
<!-- 저작권 -->
<p class="copyright">
Copyright © {date('Y')} {$layout_info->site_title}. All rights reserved.
</p>
</div>
</footer>
</div>
주요 변수들¶
시스템 변수¶
$content
: 각 모듈에서 생성된 콘텐츠$module_info
: 현재 모듈 정보$logged_info
: 로그인한 회원 정보$layout_info
: 레이아웃 설정 정보$lang
: 언어 변수
메뉴 변수¶
$main_menu->list
: 메인 메뉴 목록$main_menu->maxdepth
: 최대 깊이- 각 메뉴 항목의 속성:
href
: 링크 URLlink
: 메뉴 텍스트selected
: 선택 여부list
: 하위 메뉴open_window
: 새 창 열기 여부
반응형 레이아웃¶
뷰포트 설정¶
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
미디어 쿼리¶
/* layout.css */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 태블릿 */
@media (max-width: 768px) {
.gnb .depth2 {
position: static;
}
}
/* 모바일 */
@media (max-width: 480px) {
.gnb {
display: none;
}
.mobile-menu {
display: block;
}
}
모바일 체크¶
{@
// 모바일 여부 체크
$is_mobile = Mobile::isFromMobilePhone();
}
<!--@if($is_mobile)-->
<load target="mobile.css" />
<!--@endif-->
위젯 영역 추가¶
위젯 코드 생성기 사용¶
<!-- 위젯 영역 -->
<div class="widget-area">
<img class="zbxe_widget_output" widget="content" skin="default" colorset="white" content_type="document" module_srls="64" list_type="normal" tab_type="none" markup_type="list" list_count="5" cols_list_count="1" page_count="1" option_view="title,regdate,nickname" show_browser_title="Y" show_comment_count="Y" show_trackback_count="Y" show_category="Y" show_icon="Y" order_target="list_order" order_type="desc" />
</div>
위젯 캐시 설정¶
위젯 성능 향상을 위해 캐시 설정 가능:
<img class="zbxe_widget_output" widget="content" cache="300" ... />
고급 기능¶
사이트맵 자동 생성¶
<div class="sitemap">
<ul>
<li loop="$main_menu->list => $key1, $val1">
<h3><a href="{$val1['href']}">{$val1['link']}</a></h3>
<ul cond="$val1['list']">
<li loop="$val1['list'] => $key2, $val2">
<a href="{$val2['href']}">{$val2['link']}</a>
</li>
</ul>
</li>
</ul>
</div>
브레드크럼 (현재 위치)¶
<nav class="breadcrumb">
<a href="{getUrl()}">홈</a>
<block loop="$main_menu->list => $key1, $val1" cond="$val1['selected']">
<span>></span>
<a href="{$val1['href']}">{$val1['link']}</a>
<block loop="$val1['list'] => $key2, $val2" cond="$val2['selected']">
<span>></span>
<a href="{$val2['href']}">{$val2['link']}</a>
</block>
</block>
</nav>
디버깅 팁¶
- 레이아웃 변수 확인
<!--@if(__DEBUG__)-->
<pre>{var_dump($layout_info)}</pre>
<!--@endif-->
- 메뉴 구조 확인
<!--@if(__DEBUG__)-->
<pre>{print_r($main_menu->list, true)}</pre>
<!--@endif-->
- 캐시 문제 해결
-files/cache/
디렉토리 삭제
- 관리자 > 캐시 파일 재생성