Xây dựng skin và layout
Skin là diện mạo của mô-đun, còn layout là khung của toàn bộ website. Cách tạo gần như giống nhau, chỉ khác vị trí đặt và tệp khai báo.
| Vị trí | Tệp khai báo | Đối tượng áp dụng | |
|---|---|---|---|
| Skin mô-đun | modules/{module}/skins/{skin}/ | skin.xml | Instance (mid) của mô-đun đó |
| Layout | layouts/{layout}/ | conf/info.xml | Website (hoặc chỉ định theo từng mid) |
Tạo skin mô-đun
Để khoác diện mạo mới cho một mô-đun có sẵn, hãy bắt đầu bằng cách sao chép nguyên thư mục skins/default/ của mô-đun đó rồi đổi tên. Skin mặc định chính là đáp án cho việc cần những tệp template nào và những biến nào được truyền xuống.
modules/board/skins/myskin/
├── skin.xml
├── list.html ← 목록 (+ 상세는 _read.html 포함 방식)
├── _read.html
├── _comment.html
├── write_form.html
├── css/skin.css
└── ...skin.xml
<?xml version="1.0" encoding="UTF-8"?>
<skin version="0.2">
<responsive>true</responsive>
<title xml:lang="ko">내 스킨</title>
<description xml:lang="ko">설명</description>
<version>1.0.0</version>
<date>2026-08-05</date>
<author email_address="you@example.com" link="https://example.com">
<name xml:lang="ko">제작자</name>
</author>
<extra_vars>
<var name="list_style" type="select" default="list">
<title xml:lang="ko">목록 형태</title>
<options value="list"><title xml:lang="ko">목록형</title></options>
<options value="card"><title xml:lang="ko">카드형</title></options>
</var>
</extra_vars>
</skin><responsive>true</responsive>cho biết skin này xử lý được cả màn hình hẹp. Tham khảo Chế độ xem đáp ứng và hiển thị đáp ứng.- Cài đặt skin khai báo bằng
<extra_vars>được đọc trong template bằng$module_info->{variable}.
Những điều phải tuân thủ
- Skin chỉ thay đổi giao diện hiển thị. Biến do máy chủ truyền xuống và quy ước biểu mẫu phải giữ giống skin mặc định. Nếu bỏ sót trường hidden của biểu mẫu (module, act, mid, v.v.) thì sẽ không lưu được.
- Những phần liên kết với cài đặt quản trị như cột danh sách bảng tin (
$list_config, v.v.) thì đừng gán cứng mà hãy theo giá trị cài đặt. - Với biểu tượng, nên dùng SVG nội tuyến thay cho tệp ảnh.
Tạo layout
layouts/mylayout/
├── layout.html ← 뼈대. {!! $content !!} 자리에 본문이 들어감
├── conf/info.xml
├── css/layout.css
└── js/layout.jsKhung tối thiểu của layout.html
@version(2)
@load('css/layout.css')
@load('js/layout.js')
<div class="my-layout">
<header>
<a href="{{ getUrl('') }}">{{ $layout_info->logo_text ?: '사이트' }}</a>
<nav>
@foreach ($gnb->list ?? [] as $item)
<a href="{{ $item['href'] }}" @if (!empty($item['selected'])) class="on" @endif>{{ $item['text'] }}</a>
@endforeach
</nav>
</header>
<main>{!! $content !!}</main>
<footer>{{ $layout_info->copyright }}</footer>
</div>- Nội dung chính được xuất bằng
{!! $content !!}. Không được escape. - Menu được truyền xuống qua
$gnb->list, v.v. theo khai báo<menus>trong info.xml. Mỗi mục cótext(tên)href(địa chỉ)selected/open(vị trí hiện tại)list(menu con).
conf/info.xml
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.2">
<responsive>true</responsive>
<title xml:lang="ko">내 레이아웃</title>
<version>1.0.0</version>
<author email_address="you@example.com" link="https://example.com">
<name xml:lang="ko">제작자</name>
</author>
<menus>
<menu name="gnb" maxdepth="3" default="true">
<title xml:lang="ko">상단 메뉴</title>
</menu>
</menus>
<extra_vars>
<group>
<title xml:lang="ko">기본</title>
<var name="logo_text" type="text">
<title xml:lang="ko">로고 텍스트</title>
</var>
<var name="point_color" type="color" default="#2677e3">
<title xml:lang="ko">포인트 색상</title>
</var>
</group>
</extra_vars>
</layout><var>của extra_vars bắt buộc phải đặt trong<group>. Màn hình cài đặt chi tiết layout vẽ mỗi nhóm thành một tab, nên biến nằm ngoài nhóm sẽ không hiện trên màn hình.- Giá trị cài đặt được đọc trong template bằng
$layout_info->{variable}. - Các mục lặp lại như slider·banner hãy khai báo bằng Trường lặp của layout.
Những điều cần tuân thủ trong CSS layout
- Bắt buộc khai báo kèm
html, body { margin: 0; background: ... }. Nếu chỉ tô nền cho div ngoài cùng, lề mặc định của body và rãnh thanh cuộn sẽ còn màu trắng, trông như viền trắng bốn phía màn hình ở chế độ tối. - Nếu hỗ trợ chế độ tối, hãy gom màu vào biến CSS và chuyển đổi bằng thuộc tính
data-themehoặcprefers-color-scheme. - Nếu nhận cài đặt màu nhấn, cách dễ quản lý là truyền xuống thành biến như
style="--brand: {{ $layout_info->point_color }}"để toàn bộ CSS đi theo.
Phân phối
Skin·layout được nén nguyên thư mục để đăng lên cửa hàng hoặc cài trực tiếp (tải lên đường dẫn tương ứng). Để phân phối layout và skin mô-đun thành một bộ, hãy gói chúng thành gói giao diện.