템플릿¶
템플릿은 표현 방식을 정하며 본문을 복제하지 않습니다. Guidedog은 HTML에 Jinja를, PDF에 Typst를 사용합니다.
Guidedog 템플릿은 직접 보고 편집할 수 있는 일반 프로젝트 파일입니다. guidedog quickstart 를 실행하면 실제 사용할 템플릿이 프로젝트에 생성됩니다.
_templates/layout.html은 Jinja로 HTML 사이트의 구조를 정의합니다._templates/book.typ은 Typst로 PDF 책의 레이아웃, 타이포그래피, 표지를 정의합니다._static/guidedog.css와_static/guidedog.js는 기본 스타일과 브라우저 동작을 제공합니다.
템플릿은 외부 패키지나 바이너리 캐시에 숨겨지지 않고 프로젝트 안에 있습니다. 직접 편집한 뒤 guidedog build 로 빌드하고 guidedog serve 로 확인하세요.
HTML 템플릿¶
Guidedog은 내장 Jinja 엔진으로 루트 페이지 템플릿 layout.html 을 렌더링합니다. 하나의 큰 파일로 만들 필요 없이 부분 템플릿, 매크로 라이브러리, 다단계 상속 구조로 나눌 수 있습니다.
모듈형 템플릿 구조¶
templates_path 에 지정한 디렉터리 아래에서 템플릿을 여러 파일과 하위 디렉터리로 나눌 수 있습니다. 기본값은 ["_templates"] 입니다.
my-docs/
├── conf.toml
├── index.rst
└── _templates/
├── layout.html
├── base.html
├── partials/
│ ├── header.html
│ ├── navigation.html
│ ├── searchbox.html
│ └── footer.html
└── macros/
└── components.html
Guidedog은 templates_path 아래의 모든 파일과 하위 디렉터리를 검색합니다. 포함하거나 가져올 때는 이 디렉터리를 기준으로 한 상대 경로를 사용합니다.
{% extends "base.html" %}
{% block header %}
{% include "partials/header.html" %}
{% endblock %}
{% block footer %}
{% include "partials/footer.html" %}
{% endblock %}
Jinja 매크로도 별도 파일에 정의하고 필요한 곳에서 가져올 수 있습니다.
{% macro badge(label, type="info") %}
<span class="badge badge-{{ type }}">{{ label }}</span>
{% endmacro %}
{% import "macros/components.html" as ui %}
{{ ui.badge("New", type="success") }}
!layout.html 로 테마 상속¶
기본 테마의 일부만 바꾸려면 전체 페이지를 다시 작성할 필요가 없습니다. Sphinx의 느낌표 구문으로 내장 레이아웃을 상속할 수 있습니다.
{# Inherit Guidedog's built-in layout #}
{% extends "!layout.html" %}
{# Inject custom metadata or web fonts into the document head #}
{% block extrahead %}
{{ super() }}
<link rel="stylesheet" href="{{ pathto('_static/custom.css', 1) }}">
{% endblock %}
{# Replace or extend the footer with custom content #}
{% block footer %}
{% include "partials/footer.html" %}
{% endblock %}
{% extends "!layout.html" %} 또는 {% extends "basic/layout.html" %} 은 프로젝트의 _templates/layout.html 을 재귀적으로 읽지 않고 기본 테마의 템플릿을 불러옵니다.
재정의한 블록에서 {{ super() }} 를 호출하면 부모 내용을 유지하면서 앞뒤에 내용을 추가할 수 있습니다.
레이아웃 블록¶
내장 layout.html 은 Sphinx 관례에 대응하는 블록을 정의합니다.
| 블록 | 용도 |
|---|---|
doctype |
문서 형식 선언입니다. 기본값은 <!DOCTYPE html> 입니다. |
htmltitle |
<head> 안의 <title> 요소입니다. |
linktags |
탐색 및 메타 정보 링크입니다: favicon, index, search, prev, next. |
css |
스타일시트 링크와 인라인 CSS 루트 변수입니다. |
scripts |
검색 색인과 대화형 기능을 포함하는 JavaScript 태그입니다. |
extrahead |
글꼴, 분석 도구, 사용자 메타 태그를 위한 <head> 끝의 삽입 위치입니다. |
header |
주 탐색 표시줄 바로 앞의 헤더 영역입니다. |
relbar1 |
제품 이름, 버전, 검색, 테마 전환이 있는 상단 탐색 표시줄입니다. |
rootrellink |
관련 링크 앞의 탐색 삽입 위치입니다. |
relbaritems |
탐색 표시줄에 추가할 사용자 항목입니다. |
sidebar1 |
왼쪽 탐색 사이드바 컨테이너입니다. |
sidebartoc |
sidebar1 안의 목차 탐색 트리입니다. |
breadcrumbs |
본문 위에 표시하는 계층형 이동 경로입니다. |
document |
본문을 감싸는 컨테이너입니다. |
body |
현재 문서의 HTML 본문인 {{ body }} 입니다. |
relbar2 |
이전 장과 다음 장으로 이동하는 하단 탐색 영역입니다. |
footer |
저작권, 마지막 수정 시각, 소스 링크가 있는 페이지 하단입니다. |
sidebar2 |
현재 페이지의 목차를 표시하는 오른쪽 보조 영역입니다. |
템플릿 찾기¶
Guidedog은 conf.toml 의 templates_path 순서대로 검색한 뒤 내장 템플릿을 찾습니다. 템플릿 이름은 해당 디렉터리 기준의 상대 경로이며 .. 로 바깥에 접근할 수 없습니다.
templates_path 의 모든 파일과 하위 디렉터리는 빌드 의존성입니다. 템플릿을 추가, 수정, 삭제하면 guidedog build 와 guidedog serve 가 감지해 사이트를 다시 렌더링합니다.
페이지 변수¶
Sphinx에 변수 이름이 있으면 같은 이름을 사용하므로 Sphinx 테마 일부를 옮길 수 있습니다.
| 변수 | 값 |
|---|---|
body |
HTML 형식의 문서. |
title |
문서 제목. |
pagename, docname |
usage/install 같은 문서 이름이다. 문서가 아닌 페이지에서는 docname이 비고 pagename은 Sphinx처럼 genindex, py-modindex, search 또는 템플릿 페이지 이름이다. |
toc |
목차 트리에서 만든 HTML 탐색. |
outline |
문서 자체의 절을 HTML로 표시합니다. 절이 없으면 비어 있습니다. |
prev, next |
읽기 순서의 이전·다음 페이지로 url(link도 가능)과 title을 갖습니다. 양 끝에서는 해당 페이지가 없습니다. |
project, version, release, copyright, language |
같은 이름의 설정값. |
html_title, docstitle |
html_title이며 기본값은 “<project> <release> documentation”입니다. |
html_short_title, shorttitle |
html_short_title. |
root_doc, master_doc |
루트 문서 이름. |
pathto_root |
페이지에서 사이트 루트까지의 경로입니다. 예: ../. |
root_url, search_url, genindex_url |
루트 페이지, 검색 페이지, 전체 색인으로 가는 링크. |
css_files, js_files |
url이 있는 파일 목록입니다. Guidedog 파일 다음에 html_css_files와 html_js_files가 옵니다. |
logo_url, favicon_url |
_static의 html_logo와 html_favicon입니다. 설정하지 않으면 비어 있습니다. |
accent |
테마 색상 html_theme_options.accent. |
sourcelink_url |
소스를 표시할 때는 _sources 아래의 문서 소스이며, 아니면 비어 있습니다. |
last_updated |
html_last_updated_fmt를 설정하면 그 형식의 빌드 날짜이며, 아니면 비어 있습니다. |
show_copyright, show_sphinx, show_guidedog, has_source, show_source |
html_show_*와 html_copy_source 설정. |
builder, file_suffix |
html 같은 빌더 이름과 페이지 확장자. |
html_context의 모든 키 |
Sphinx가 Python 값을 넘기듯 타입을 유지한다. false는 {% if %}에서 거짓이고 숫자는 숫자, 배열은 목록, 테이블은 conf.toml 키 순서의 딕셔너리다. guidedog migrate는 conf.py의 html_context 리터럴 항목을 옮긴다. 계산 값은 미정의로 남아 템플릿에서 거짓으로 읽힌다. |
pathto는 Sphinx 템플릿 함수다. pathto("usage/install")은 문서 페이지, pathto("_static/logo.svg", 1)은 사이트 아래 파일의 URL이며 현재 페이지 기준 상대 경로다. singlehtml에서는 문서가 단일 페이지의 절이다. 앞의 호출은 그 페이지에서 #document-usage-install, 색인·검색에서는 index.html#document-usage-install이 된다. genindex나 템플릿 페이지 같은 비문서 이름은 모든 빌더에서 사이트 루트 페이지다.
템플릿으로 만드는 페이지¶
html_additional_pages는 Sphinx처럼 템플릿만으로 페이지를 만든다. 키는 페이지 이름, 값은 templates_path의 템플릿이다.
root_doc = "contents"
[html_additional_pages]
index = "indexcontent.html"
download = "download.html"
페이지 템플릿은 보통 layout.html을 상속하고 블록을 채워 다른 페이지와 같은 모습을 만든다.
{% extends "layout.html" %}
{% block htmltitle %}<title>{{ shorttitle }}</title>{% endblock %}
{% block body %}
<h1>{{ docstitle|e }}</h1>
<p><a href="{{ pathto("tutorial/index") }}">Tutorial</a></p>
{% endblock %}
비문서 페이지의 변수를 받는다. pagename은 페이지 이름(index), title과 body는 빈 값이다. pathto, toc, toctree(), html_context는 그대로 작동한다. html, dirhtml, singlehtml은 루트의 <name>.html(html_file_suffix)로 매번 쓴다. 템플릿이나 templates_path의 어떤 파일을 바꿔도 모든 페이지를 다시 만든다.
페이지 위치와 Sphinx와의 차이는 다음과 같습니다.
- 같은 이름의 문서 페이지를 대체하며 Sphinx가 마지막에 쓰는 것과 같다.
index = "landing.html"이면index.html이 소개 페이지가 되고 목차 항목은index.rst가 제공한다. singlehtml은 단일 페이지를 유지하고 템플릿 페이지를 쓰지 않으며 경고한다. dirhtml은genindex.html,search.html옆에download.html을 쓴다. Sphinx는download/index.html을 쓴다.pathto("download")는 그 파일을 반환한다.- 이름은 사이트 루트의 파일 이름이어야 한다. 링크가 루트 기준이므로
"sub/page"는 경고(build.additional_page)와 함께 거부한다.genindex처럼 이미 사용한 이름도 거부한다. Sphinx는 이 경우 한 페이지로 다른 페이지를 덮어쓴다. guidedog migrate는conf.py의html_additional_pages를 옮깁니다.
오류¶
템플릿 오류는 빌드를 멈추고 파일, 줄 번호, 해당 줄, 수정 제안을 표시합니다.
TEMPLATE ERROR template.error
_templates/base.html:1
No filter named 'defualt'.
Did you mean the filter 'default'?
정의하지 않은 변수는 Jinja처럼 아무것도 출력하지 않습니다.
과도한 템플릿도 충돌하지 않고 오류로 멈춘다. 구문(괄호, 태그, 연산자·필터·elif 사슬)이 100단계, 매크로·포함·재귀 루프가 200단계를 넘거나 재귀 스택이 512 KiB를 넘을 때다. 자신을 포함한 목록은 Python처럼 [...]로 표시한다.
PDF 템플릿¶
PDF 책은 Typst로 조판한다. _templates/book.typ는 book 함수를 정의하는 일반 Typst 파일이다. Guidedog은 책 소스를 다음과 같이 쓴다.
#import "/_templates/book.typ": book
#show: book.with(title: ..., author: ..., version: ..., date: ...,
lang: ..., paper: ..., numbering: ..., logo: ...)
// the chapters, one per document of the root toctree
책의 모양을 결정하는 모든 요소가 이 파일에 있습니다. 글꼴, 페이지 크기와 여백, 제목, 표제지, 머리말, 목차입니다.
매개변수¶
| 매개변수 | 값 |
|---|---|
title |
pdf_documents의 책 title이며, 없으면 project입니다. |
author |
책의 author이며, 없으면 설정의 author입니다. |
version |
release. |
date |
|today|는 설정한 today 값이며, 없으면 today_fmt 형식의 빌드 날짜입니다. |
lang |
language. |
paper |
"a4"이며 pdf_paper_size가 letter이면 "us-letter"입니다. |
numbering |
toctree에 numbered 옵션이 있으면 true입니다. |
logo |
pdf_logo의 경로입니다. 설정하지 않으면 생략합니다. |
copyright |
판권 페이지의 copyright이며, 이 매개변수를 받는 템플릿에만 전달합니다. |
body |
각 장의 내용. |
템플릿은 기본값이 있는 매개변수를 추가할 수 있다. quickstart 템플릿에는 accent, 글꼴 serif·sans·mono, 글자 size, page-ref가 있다. 마지막 값을 n => [p. #n] 같은 함수로 설정하면 다른 페이지 참조에 페이지 번호를 붙인다.
모듈형 Typst 템플릿¶
Typst 템플릿도 한 파일에 넣을 필요가 없습니다. 스타일, 매크로, 표지를 _templates/ 아래의 여러 .typ 파일로 나누고 #import 와 #include 로 조합할 수 있습니다.
#import "cover.typ": title-page
#import "typography.typ": apply-styles
#let book(
title: "",
author: "",
version: "",
date: "",
lang: "en",
paper: "a4",
numbering: false,
logo: none,
body,
) = {
apply-styles()
title-page(title: title, author: author, version: version, logo: logo)
body
}
템플릿에서 쓸 수 있는 것¶
- Typst 패키지
-
#import "@preview/cetz:0.4.2"등 패키지는 처음 사용할 때 다운로드된다.pdf_packages = "offline"이면 디스크에 있는 패키지만 사용한다. - 글꼴
-
typst명령처럼 시스템 글꼴을 쓸 수 있다.pdf_font_paths로 폴더를 추가한다.pdf_fonts = "embedded"는 Typst 내장 글꼴만 써서 바이트 단위로 재현 가능한 책을 만든다. - 프리앰블
-
pdf_preamble은#show: book다음에 넣을 Typst 파일을 지정합니다. 별도 템플릿 없이 몇 가지set·show규칙을 추가할 때 적합합니다. - 문서 안의 Typst
-
문서는 reStructuredText와 Markdown이며 Typst 파일은 문서가 아니다. 책에 Typst 마크업을 넣으려면 raw 블록을 쓴다. 웹 페이지에서는 생략된다.
.. raw:: typst #align(center)[#text(size: 14pt)[Only in the book]]
.. only:: pdf도 일반 콘텐츠를 책에만 남깁니다.
Typst 오류는 템플릿이나 생성된 책 어디서든 파일과 줄 번호를 밝힌다. PDF별 소스는 _build/pdf/sources/<pdf-filename>.typ에 있다. reference-en.pdf의 경우 sources/reference-en.pdf.typ이다. 한 권 빌드에는 _build/pdf/book-<language>.typ 확인용 사본도 남긴다. 실패하면 게시하지 않고 오류에 명시된 _build/.doctrees/failed 경로에 소스를 보관한다. 여러 책의 실패 소스는 구분한다.
새 템플릿 작성¶
각 부분의 사용법을 보여 주는 quickstart 템플릿부터 시작하세요.
- 기본 스타일시트가 기대하는
layout.html마크업을 유지하거나_static/guidedog.css도 함께 바꾸세요. - 반복 부분을 별도 파일로 옮겨
include하거나,base.html을 만들고layout.html에서extends하세요. - 책은
book함수의 규칙을 바꾸거나 같은 이름과 매개변수의 새 함수를 작성하세요.
편집 중에는 guidedog serve로 미리 보세요. 소스를 저장하고 브라우저를 새로 고치면 서버가 변경된 입력을 다시 빌드한 뒤 페이지를 제공합니다.