スキン・レイアウト制作
スキンはモジュールの見た目、レイアウトはサイト全体の枠組みです。作り方はほぼ同じで、置く場所と宣言ファイルが異なります。
| 場所 | 宣言ファイル | 適用対象 | |
|---|---|---|---|
| モジュールスキン | modules/{module}/skins/{skin}/ | skin.xml | そのモジュールのインスタンス(mid) |
| レイアウト | layouts/{layout}/ | conf/info.xml | サイト(または mid ごとに指定) |
モジュールスキンを作る
既存のモジュールに新しい見た目を与えるなら、そのモジュールの skins/default/ を丸ごとコピーして名前を変えるところから始めてください。どのテンプレートファイルが必要で、どの変数が渡されるかは、既定のスキンが模範解答です。
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>は、このスキンが狭い画面まで対応することを示します。レスポンシブビューとレスポンシブ表示 を参照。<extra_vars>で宣言したスキン設定は、テンプレートで$module_info->{variable}として読み取ります。
守るべきこと
- スキンは画面だけを変えます。サーバーが渡す変数とフォームの規約は、既定のスキンと同じに保つ必要があります。フォームの hidden フィールド(module、act、mid など)が抜けると保存できません。
- 掲示板の一覧カラムのように管理設定と連動する部分(
$list_configなど)はハードコーディングせず、設定値に従ってください。 - アイコンは画像ファイルではなくインライン SVG をおすすめします。
レイアウトを作る
layouts/mylayout/
├── layout.html ← 뼈대. {!! $content !!} 자리에 본문이 들어감
├── conf/info.xml
├── css/layout.css
└── js/layout.jslayout.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>- 本文は
{!! $content !!}で出力します。エスケープしてはいけません。 - メニューは info.xml の
<menus>宣言に従って$gnb->listなどで渡されます。各項目はtext(名前)href(アドレス)selected/open(現在位置)list(下位メニュー)を持ちます。
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>- extra_vars の
<var>は必ず<group>の中に置いてください。レイアウトの詳細設定はグループをタブとして描画するため、グループ外の変数は画面に表示されません。 - 設定値はテンプレートで
$layout_info->{variable}として読み取ります。 - スライダーやバナーのように繰り返される項目は、繰り返しフィールドで宣言してください。
レイアウト CSS で守ること
html, body { margin: 0; background: ... }を必ずあわせて宣言してください。最上位の div にだけ背景を塗ると、body の既定の余白とスクロールガターが白いまま残り、ダークモードで画面の四方に白い枠があるように見えます。- ダークモードに対応するなら、色を CSS 変数にまとめ、
data-theme属性またはprefers-color-schemeで切り替えてください。 - ポイントカラーの設定を受け付けるなら、
style="--brand: {{ $layout_info->point_color }}"のように変数として渡し、CSS 全体が追従するようにすると管理しやすくなります。
配布
スキン・レイアウトはフォルダごと圧縮してストアに登録するか、直接インストール(該当パスにアップロード)します。レイアウトとモジュールスキンをセットで配布するなら、テーマパッケージにまとめてください。