мені вдалося перестворити щоденник: тепер він генерується за допомогою hugo замість jekyll, і хоститься на codeberg pages замість у мене на сервері; обслуговування й налаштування значно спростилися. але оформлення страшне — потрібно модифікувати тему, щоби щоденник виглядав принаймні читабельно; в ідеалі — якомога подібніше до попередньої версії (на ілюстрації). я дуже погано знаю html і css, доведеться експериментувати.
тема як субмодуль?
більшість підказок в тенетах радять додавати тему як субмодуль (git submodule); мені це не підходить. в попередньому дописі я забув згадати, що мені довелося позбутися субмодуля:
- видалити теку
./themes/hugo-xmin
; - закомітити шаблон без неї;
- окремо клонувати тему в тимчасову теку;
- прибрати звідки
.git
; - копіювати чи перемістити до
./themes/hugo-xmin
; - знову закомітити й перевиштовхнути до свого репозиторію.
це не найправильніший спосіб, але він простий. тепер можна скільки завгодно модифікувати тему в окремій гілці й випробовувати зміни локально.
перший експеримент
трохи потицькав css та шаблони горища (header), підвалу (footer) й допису; приблизно зрозумів, яке оформлення хочу (третє зображення на ілюстрації), і як його зробити. зрозумів також, що якщо не всю тему, то принаймні css доведеться повністю перероблювати: не зроблене воно по-людському.
для простоти й швидкості локальні blog.hugo та blog.content змонтовано (mount --bind
) до blog.test, hugo перебудовує все повністю за найменшої зміни:
hugo server --forceSyncStatic --disableFastRender --source blog.test
деякий час не міг зрозуміти, як зручно відкрити інструменти відладки в qutebrowserʼі під сторінкою: :devtools bottom
.
побудова сторінки
далі все буде дуже примітивно і нудно, але я вже визнав, що погано знаю html та css; мені потрібні нотатки, щоби скласти в голові цей пазл.
tree ~/blog/blog.hugo/themes/hugo-xmin -I 'exampleSite|archetypes|*.Rproj|*.md|images'
themes/hugo-xmin
├── layouts
│ ├── 404.html
│ ├── _default
│ │ ├── list.html
│ │ ├── single.html
│ │ └── terms.html
│ └── partials
│ ├── foot_custom.html
│ ├── footer.html
│ ├── head_custom.html
│ └── header.html
├── static
│ └── css
│ ├── fonts.css
│ └── style.css
└── theme.toml
сторінка зі звичайним дописом в hugo-xmin складається з трьох частин:
- горище (
layouts/partials/header.html
); - основа (
layouts/_default/single.html
, для інших типів сторінок — інші шаблони); - підвал (
layouts/partials/footer.html
).
поки що майже нічого не модифікую, але виправляю побудову, бо те, що є в hugo-xmin, не дозволяє мені зробити деякі покращення.
горище
після переструктурування того, що було в темі:
┌─body─────────────────────────────────────────────────────┐
│┌─header─────────────────────────────────────────────────┐│
││ ┌─nav.header───────────────────────────────────┐ ││
││ │ ┌─a.logo──────┐ ┌─ul.menu──────────┐ │ ││
││ │ │ .Site.Title │ │ .Site.Menus.menu │ │ ││
││ │ └─────────────┘ └──────────────────┘ │ ││
││ └──────────────────────────────────────────────┘ ││
│└────────────────────────────────────────────────────────┘│
┊ ┊
фрагмент header.html:
<html>
...
<body>
<header>
<nav class="header">
<a class="logo" href={{ .Site.BaseURL }}>{{ .Site.Title }}</a>
<ul class="menu">
{{ range .Site.Menus.main }}
<li><a href="{{ .URL | relURL }}" class="menu">{{ .Name }}</a></li>
{{ end }}
</ul>
</nav>
</header>
основа
коробочки:
┊ ┊
│┌─main───────────────────────────────────────────────────┐│
││ ┌─article──────────────────────────────────────┐ ││
││ │ ┌─div.article-meta─────────────────────────┐ │ ││
││ │ │ h1.title │ │ ││
││ │ │ span.date | span.author │ │ ││
││ │ └──────────────────────────────────────────┘ │ ││
││ │ .Content │ ││
││ └──────────────────────────────────────────────┘ ││
│└────────────────────────────────────────────────────────┘│
┊ ┊
файл single.html:
{{ partial "header.html" . }}
<main>
<article>
<div class="article-meta">
<h1 class="title">{{ .Title | markdownify }}</h1>
{{ if (gt .Params.date 0) }}<span class="date">{{ .Date.Format "2006-01-02, 15:04" }}</span>{{ end }}
{{ with .Params.author }}<span class="date"> | {{ . }}</span>{{ end }}
</div>
{{ .Content }}
</article>
</main>
{{ partial "footer.html" . }}
підвал
коробочки:
┊ ┊
│┌─footer─────────────────────────────────────────────────┐│
││ ┌─div.footer───────────────────────────────────┐ ││
││ │ .Site.Params.footer │ ││
││ └──────────────────────────────────────────────┘ ││
│└────────────────────────────────────────────────────────┘│
└─body─────────────────────────────────────────────────────┘
файл footer.html:
<footer>
<div class="footer">
{{ partial "foot_custom.html" . }}
{{ with .Site.Params.footer }}
{{ replace . "{Year}" now.Year | markdownify}}
{{ end }}
</div>
</footer>
</body>
</html>
геометрія і позиціонування
не знаю, наскільки страшно виглядала би сторінка, складена лише з цих «коробочок», але ще без стилювання геометрії та позиціонування в style.css, — бо я вже там потицькав трохи. по-перше, параметризація (за похардкоджені кольори й розміри відривав би рученята):
:root {
/* основні розміри */
--main_width: 800px; /* ширина основної колонки */
--main_padding: 1em; /* внутрінші відступи праворуч, ліворуч в оновній колонці */
--main_spacing: 3em; /* інтервал між основною частиною і горищем, підвалом */
--meta_spacing: 2em; /* відступ у статті між заголовком і текстом */
--head_size: 4em; /* висота горища */
--foot_size: 3em; /* висота підвалу */
--decoration_size: 3px; /* товщина різних декорацій, акцентованих елементів */
--text_padding: 1em; /* внутрішні відступи для різних текстових полів */
позиціонування:
body {
margin: 0;
padding: 0;
}
/* горище */
header {
width: 100%;
height: var(--head_size);
margin: 0;
padding: 0;
position: sticky;
top: 0;
z-index: 999;
}
nav.header {
max-width: var(--main_width);
margin: 0 auto;
height: 100%;
padding: 0 var(--main_padding);
display: flex;
justify-content: space-between;
align-items: center;
}
a.logo {
display: inline-block;
}
.menu ul { display: inline-block; }
.menu li { display: inline-block; }
...
/* підвал */
footer {
width: 100%;
height: var(--foot_size);
background-color: var(--color_plates);
}
div.footer {
max-width: var(--main_width);
height: 100%;
display: flex;
margin: auto;
padding-left: var(--main_padding);
padding-right: var(--main_padding);
align-items: center;
}
/* основна частина */
main {
width: 100%;
margin: 0;
padding: var(--main_spacing) 0;
}
article {
max-width: var(--main_width);
margin: auto;
padding-left: var(--main_padding);
padding-right: var(--main_padding);
}
.article-meta {
margin-bottom: var(--meta_spacing);
}
.article-meta h1 {
margin: 0;
}
оформлення
шрифти
раніше пробував завантажувати веб-шрифти… але навіщо? не все, що має сенс в поліграфії, чи для великих комерційних проєктів, так само потрібно в малому вебі. цього разу все буде якомога простіше (файл fonts.css):
body {
font-family: sans-serif;
}
main {
font-family: serif;
}
.meta, table, h1, h2, h3, h4 {
font-family: sans-serif;
}
code {
font-family: monospace;
}
стилі css
залишилося «застилювати» оформлення, і базова сторінка з дописом готова. звісно, доведеться модифікувати й інші шаблони — переліки дописів тощо. враховуючи кількість змін відносно hugo-xmin, можна вже й тему якось інакше.
:root {
/* основні розміри */
--main_width: 800px; /* ширина основної колонки */
--main_padding: 1em; /* внутрінші відступи праворуч, ліворуч в оновній колонці */
--main_spacing: 3em; /* інтервал між основною частиною і горищем, підвалом */
--meta_spacing: 2em; /* відступ у статті між заголовком і текстом */
--header_size: 4em; /* висота горища */
--footer_size: 3em; /* висота підвалу */
--decoration_size: 3px; /* товщина різних декорацій, акцентованих елементів */
--text_padding: 1em; /* внутрішні відступи для різних текстових полів */
/* колірна палітра */
--color_background: white; /* колір тла */
--color_text: black; /* основний колір, найконтрастніший відтінок: текст. тонкі лінії */
--color_plates: gainsboro; /* світлий відтінок основного: плашки */
--color_shaded: dimgrey; /* темний відтінок основного: неосновний текст, додаткові елементи */
--color_accent: orange; /* додатковий колірний акцент */
}
body {
/* геометрія */
margin: 0;
padding: 0;
/* оформлення */
background: var(--color_background);
}
/* горище */
header {
/* геометрія */
width: 100%;
height: var(--header_size);
margin: 0;
padding: 0;
position: sticky;
top: 0;
z-index: 999;
/* оформлення */
background-color: var(--color_plates);
border-bottom: var(--decoration_size) solid var(--color_accent);
}
nav.header {
/* геометрія */
max-width: var(--main_width);
margin: 0 auto;
height: 100%;
padding: 0 var(--main_padding);
display: flex;
justify-content: space-between;
align-items: center;
/* оформлення */
}
a.logo {
/* геометрія */
display: inline-block;
/* оформлення */
font-weight: bold;
font-size: 1.1em;
color: var(--color_text);
text-decoration: none;
}
.menu ul { display: inline-block; }
.menu li { display: inline-block; }
.menu a {
color: var(--color_text);
padding: 0 0.3em;
}
.menu a:link { text-decoration: none; }
.menu a:hover { text-decoration: underline; }
.menu a:active { text-decoration: underline; color: var(--color_accent); }
.menu a:visited { text-decoration: none }
/* підвал */
footer {
/* геометрія */
width: 100%;
height: var(--footer_size);
background-color: var(--color_plates);
/* оформлення */
border-top: 1px solid var(--color_shaded);
}
div.footer {
/* геометрія */
max-width: var(--main_width);
height: 100%;
display: flex;
margin: auto;
padding-left: var(--main_padding);
padding-right: var(--main_padding);
align-items: center;
}
footer a { color: var(--color_text); }
footer a:link { text-decoration: none; }
footer a:hover { text-decoration: underline; }
footer a:active { text-decoration: underline; color: var(--color_accent); }
footer a:visited { text-decoration: none }
/* основна частина */
main {
/* геометрія */
width: 100%;
margin: 0;
padding: var(--main_spacing) 0;
}
article {
/* геометрія */
max-width: var(--main_width);
margin: auto;
padding-left: var(--main_padding);
padding-right: var(--main_padding);
/* оформлення */
line-height: 1.5;
}
.article-meta {
/* геометрія */
margin-bottom: var(--meta_spacing);
/* оформлення */
text-decoration: none;
}
.article-meta h1 {
/* геометрія */
margin: 0;
/* оформлення */
font-size: 2em;
text-align: left;
}
span.meta {
/* оформлення */
color: var(--color_shaded);
}
article a { color: var(--color_text); }
article a:link { color: var(--color_text); }
article a:hover { text-decoration: underline; }
article a:active { text-decoration: underline; color: var(--color_accent); }
article a:visited { text-decoration: none }
hr {
border-style: solid;
color: var(--color_shaded);
}
article h1, h2, h3, h4, h5 {
text-align: left;
}
article p {
hyphens: auto;
text-align: justify;
}
article li {
text-align: left;
margin-right: var(--text_padding);
}
/* code */
pre {
/* геометрія */
border-left: var(--decoration_size) solid var(--color_accent);
border-top: 1px solid var(--color_plates);
box-shadow: var(--decoration_size) var(--decoration_size) var(--decoration_size) var(--color_plates);
padding: var(--text_padding);
overflow-x: auto;
/* оформлення */
line-height: 1.1;
}
/* цитати */
blockquote {
background: var(--color_plates);
border-left: var(--decoration_size) solid var(--color_accent);
padding: var(--text_padding);
}
/* таблиці */
table {
margin: auto;
border-top: 1px solid var(--color_plates);
border-bottom: 1px solid var(--color_plates);
}
table thead th { border-bottom: 1px solid var(--color_plates); }
th, td { padding: var(--decoration_size); }
thead, tfoot, tr:nth-child(even) { background: var(--color_plates); }
/* misc elements */
img, iframe, video { max-width: 100%; }
структура сайту
не зовсім про оформлення: під час міграції я втратив організацію сторінок (обкладинка, архів, пошук тощо); зараз навігація сайтом… гхм, примітивна: hugo-xmin просто вивалює на обкладинку повний перелік усіх сторінок сайту (це 2 тисячі з гаком посилань). треба щось робити, і це буде наступний етап. чіткого плану немає, щось таке в голові:
- обкладинка — коротко про сайт, посилання на декілька найсвіжіших дописів у кожній категорії (щоденник, підказки, чернетки тощо) з короткими анотаціями;
- теми — перелік тем (міток), і повний перелік публікацій за кожною темою (як в попередній версії);
- про сайт;
- rss — посилання на видачу rss (як у попередній версії).