Chuyển đến nội dung
Tài liệu

Hướng dẫn cho nhà phát triển

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ô-đunmodules/{module}/skins/{skin}/skin.xmlInstance (mid) của mô-đun đó
Layoutlayouts/{layout}/conf/info.xmlWebsite (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>

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.js

Khung 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-theme hoặc prefers-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.