Бложим как фрики

от автора

Сидишь бывало, записываешь всякие штукуёвины, которые сам вечно забываешь и вдруг кааак захотелось начать наносить людям добро и причинять радость вопреки их желаниям, а тут ещё и народ периодически спрашивает, стало быть надо завести блох, но не в свитере, а который будет удобный, быстрый, защищённый, красивый и не будет зависеть от модных веяний на очередной платформе-однодневке, не будет обмазан странными всплывашками, баннерами, пропагандой…

Но писать с нуля новый движок или пользоваться вечно дырявыми php-бложиками не барское дело и вообще не хочется разбираться со всей этой кухней из протухших зависимостей.

Markdown

Писать будем простой удобочитаемый текст, из любого удобного места, практически с первого попавшегося холодильника, в любом первом попавшемся редакторе, хоть в vim, как деды верещали, не отвлекаясь в творческом угаре на проблемы софта, доступности облачков, новые свистоперделки облачков, обновления свистоперделок и прочие всплывашки и отвлекаторы. Чем проще — тем лучше. Надёжно как кирпич. Нам поможет в этом тёплый ламповый Markdown, который неплохо так везде поддержан оставаясь достаточно простым и умеет хорошо расширяться. Ну и вообще, все же знают и умеют в Markdown.

Hugo

Markdown будем раскатывать в статичный сайт, который по определению быстр, хорошо кэшируется, индексируется и не хакается, не говоря о том что зависимостей которые будут протухать и отваливаться просто нет из коробки. GitHub Pages проталкивает Jekyll, но ведь есть божественный и быстрый Hugo, с его сотнями шаблонов оптимизированных на любой вкус и цвет, от мобилок и Accessibility (который правильно сделанный помогает не только лишь людям с проблемами, но и для всяких удобных штук типа vimium очень полезен), до СЕО, комментариев и нормальной поддержки опций типа Reader View в Firefox. Hugo написан на Go, поэтому есть под все основные платформы и без приседаний с окружением и зависимостями — просто скачал и работай. Только нам, скорее всего, понадобится SCSS, поэтому из сборок качаем hugo extended. Теперь можно сходить почитать документацию.

Но мы ленивые, а Hugo достаточно взрослый, если его позапускать из консоли, он сам расскажет про hugo help new, ну а дальше по накатанной

> hugo new site my-blog Congratulations! Your new Hugo site was created in D:\Projects\my-blog. Just a few more steps... 1. Change the current directory to D:\Projects\my-blog. 2. Create or install a theme:      - Create a new theme with the command "hugo new theme <THEMENAME>"      - Or, install a theme from https://themes.gohugo.io/ 3. Edit hugo.toml, setting the "theme" property to the theme name. 4. Create new content with the command "hugo new content <SECTIONNAME>\<FILENAME>.<FORMAT>". 5. Start the embedded web server with the command "hugo server --buildDrafts". See documentation at https://gohugo.io/. 

И как бы можно с места в карьер, но…

Нужно сначала один раз нормально разобраться и настроить.

Тема по умолчанию — это черновик, который будет добавлять 3 тестовых поста из themes\default\content и в целом просит кирпича напильника.
Поэтому идём в репозиторий тем и выбираем что-нибудь покавайнее под наши нужды. Мне, например, понравилась m10c.

git clone https://github.com/vaga/hugo-theme-m10c.git themes/m10c echo "theme = 'm10c'" >> hugo.toml

Новые посты по умолчанию генерятся в директории content из шаблона сохранённого в archetypes, но не забывайте прописывать формат файла, иначе получите ошибку

> hugo new content posts\my-first-post Error: failed to resolve "posts\\my-first-post" to an archetype template  > hugo new content posts\my-first-post.md Content "my-blog\\content\\posts\\my-first-post.md" created

Пост не будет генериться в блог, пока в шапке с метаданными присутствует draft = true. Удаляем, дописываем что-нибудь весёленькое и дальше по вкусу: можно просто запустить hugo в директории с проектом и он сгенерит public со статичным сайтом, а можно запустить hugo server, кликнуть на предложенный урлик и сразу посмотреть в браузере результат.

Настраиваем параметры генератора и шаблона

Всё основное конфигурируется через config.toml и достаточно очевидно

baseURL = 'https://USERNAME.github.io/' title = "USERNAME blog"  languageCode = 'ru-ru' defaultContentLanguage = "ru" defaultContentLanguageInSubdir = true  theme = 'm10c'  # publishdir = '_site'  enableRobotsTXT = false  [params]   author = 'USERNAME'   description = 'Whatever Developer, full-stack. Interested in *nix, maker culture, home assistant, photo, nature, birdwatching'   avatar = 'https://avatars.githubusercontent.com/u/USERID'  [[params.social]]   icon = "github"   name = "My Github"   url = "https://github.com/USERNAME" [[params.social]]   icon = "linkedin"   name = "linkedin"   url = "https://www.linkedin.com/in/USERNAME" [[params.social]]   icon = "telegram"   name = "telegram"   url = "https://t.me/USERNAME"  [menu]   [[menu.main]]     identifier = "home"     name = "Home"     url = "/"     weight = 1   [[menu.main]]     identifier = "posts"     name = "Posts"     url = "/posts/"     weight = 2   [[menu.main]]     identifier = "tags"     name = "Tags"     url = "/tags/"     weight = 3   [[menu.main]]     identifier = "about"     name = "About"     url = "/about/"     weight = 4

Меняем под свои аккаунты.

Фото на аватарку можно либо залить сразу в репозиторий, либо сделать ссылку на фото из профиля гитхаба, либо ещё про какой gravatar подумать.

Немножко систематизируем

В директории у нас могут быть

  • _index.md — индексный файл который указывает что нам нужно сгенерировать список статей из того что лежит в текущей директории и поддиректориях. В принципе это поведение по умолчанию для директории, но возможно вы захотите задать заголовок для этой страницы, тогда минимальное содержимое будет примерно таким

    --- title: "My custom title for this category" ---
  • index.md — главный файл для данной директории (по аналогии с index.html), если он есть то для данного пути Hugo будет использовать именно его и на все остальные статьи вам где-то придётся самостоятельно прописывать ссылки

  • всякие прочие *.md — файлы из которых будут генериться статичные страницы с вашими статьями.

Статья my-blog\content\posts\article.md будет сгенерена в my-blog\public\posts\article\index.html

И раз у нас всё равно под каждую статью генерится директория, чтобы избегать путаницы, я предпочитаю сразу все посты именовать в формате content\posts\YYYYMMDD-article-name\index.md и всякие скрины и аттачи к ним складывать в директорию к статье.
Т.е. новая статья будет генериться как-то так

hugo new content posts\2024-08-24-blog-like-a-freak\index.md

Шапка статьи у меня выглядит примерно так

--- title: 'Бложим как фрики' description: О мой бложе, что я несу... date: 2024-08-28T11:46:29+03:00 categories: Blog tags: ['Blog', 'Hugo', 'Markdown'] layout: post ---

date влияет на порядок сортировки статей

Теги и категории используются для генерации /tags/ и /categories/ соответственно
layout переопределяет какой шаблон из выбранной темы используется

И отдельно стоит упомянуть лэндинг в корне сайта. По умолчанию конкретно эта тема создаёт список постов, а весь контент из content\_index.md игнорируется. Если нас такое поведение страниц со списками сайтов не устраивает, можно в m10c\layouts\_default\list.html добавить секцию {{ .Content }} после заголовка. Если же мы хотим ещё больше кастомизации, то создаём themes\m10c\layouts\_default\home.html с кастомизацией для корневой страницы. Для примера можно взять копию файла из дефолтной темы

{{ define "main" }}   {{ .Content }}   {{ range site.RegularPages }}     <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>     {{ .Summary }}   {{ end }} {{ end }}

Теперь на странице будет присутствовать вводный текст, а уже после него будут перечисляться посты блога с кратким содержимым. Но возможно удобнее будет, например, отображать основные секции

{{ range .Site.Sections }}   <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }}

Возможности кастомизировать шаблоны Hugo кажутся бескрайними, ярчайший пример тому — документация от Kubernetes

GitHub

Вообще хостить статичный примитив можно тоже на чём угодно, лишь бы места хватило, хоть на ESP32 с microSD или на флешке воткнутой в кинетик. Но уже есть доступный, надёжный, бесплатный и всем знакомый GitHub.

Исключаем в .gitignore всё лишнее

/.hugo_build.lock /public /resources/_gen

Инициализируем репозиторий, коммитаем наш нехилый супец

git init git add . git commit -m "Initial"

Создаём на GitHub публичный репозиторий и в него заливаемся

git remote add origin git@github.com:USERNAME/my-blog.git git push -u origin master

GitHub Actions

Ну тут всё просто, мы хотим чтобы на любой коммит в мастер Hugo собирал новую версию статики и публиковал её. Что мы и запишем в .github\workflows\hugo.yml

name: Deploy Hugo site to Pages  on:   # Runs on pushes targeting the default branch   push:     branches: ["master"]    # Allows you to run this workflow manually from the Actions tab   workflow_dispatch:  # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions:   contents: read   pages: write   id-token: write  # Allow one concurrent deployment concurrency:   group: "pages"   cancel-in-progress: true  # Default to bash defaults:   run:     shell: bash  jobs:   # Build job   build:     runs-on: ubuntu-latest     env:       HUGO_VERSION: 0.133.1     steps:       - name: Install Hugo CLI         run: |           wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \           && sudo dpkg -i ${{ runner.temp }}/hugo.deb       - name: Checkout         uses: actions/checkout@v3         with:           submodules: recursive       - name: Setup Pages         id: pages         uses: actions/configure-pages@v2       - name: Build with Hugo         env:           # For maximum backward compatibility with Hugo modules           HUGO_ENVIRONMENT: production           HUGO_ENV: production         run: |           hugo \             --minify \             --baseURL "${{ steps.pages.outputs.base_url }}/"       - name: Upload artifact         uses: actions/upload-pages-artifact@v1         with:           path: ./public    # Deployment job   deploy:     environment:       name: github-pages       url: ${{ steps.deployment.outputs.page_url }}     runs-on: ubuntu-latest     needs: build     steps:       - name: Deploy to GitHub Pages         id: deployment         uses: actions/deploy-pages@v1

И раз мы разворачиваем новый контент через GitHub Actions, то и в репозитории, в Settings — Pages — Build and deployment — Source тоже стоит указать GitHub Actions

Всё, уже можно нести в мир улыбку, бешенство и моральную смерть.

Obsidian

Но надо ещё редактор покомфортнее. Если вы себе ещё не нашли подходящий, редактировать сырой Markdown лениво, а редактор самого GitHub вас не устраивает, возьмите Obsidian — замечательный WYSIWYG редактор к Markdown, много кто уже использует для заметок.
Заставим его открыть директорию с нашим репозиторием блога как новый Vault и пройдёмся по настройкам

Editor

Strict line breaks = включаем
Indent using tabs = отключаем, пробелы наше всё

Files and links

Default location for new notes = in the folder specified below
Folder to create new notes in = content/posts

New link format = Relative path to file

Use [[Wikilinks]] — отключаем, нам нужен честный Markdown

Default location for new attachments = Same folder as current file
поскольку для каждой статьи всё равно будет отдельная директория. И всё это можно будет спокойно переносить куда угодно

Шаблоны

Определяемся, будем мы каждый раз ручками вызывать из консоли

hugo new content posts\whatever.md

или всё-таки за шаблон будет отвечать Obsidian и тогда прописываем пути к шаблонам.

Вообще хорошо бы поставить какой-нибудь более продвинутый плагин с шаблонами, чтобы генерить сразу в нужную директорию, но хотя бы минимально из коробки можно настроить

Core plugins — Daily notes

New file location = content/posts
Template file location = archetypes/default

Core Plugins — Templates

Пусть наши шаблоны берутся из директории archetypes

А так же меняем сам шаблон на что-то вида

--- title: PAGE TITLE description: PAGE DESCRIPTION date: {{date}} {{time:HH:mm:ss Z}} categories: blog tags: [] layout: post ---

Obsidian Git

Идём в настройках в Community Plugins, включаем их, жмём Browse и ищем всякое про Git. Находим, например, Git за авторством Vinzent (Denis Olehov). Ставим, включаем.

Теперь по Ctrl+P мы можем найти нужные нам commit/push/pull прямо в Обсидиане

Коммитаемся… всё наши настройки редактора тоже в репозитории и теперь можно синкать всё на другой ПК или телефон и неспешно, смакуя, под кофирёк, строчить всякую дичь, чтобы полыхало веселее

И простым Ctrl+C, Ctrl+V эти статьи потом при желании можно репостить на хабр и прочие ресурсы с минимальными правками.

При желании всё это можно приспособить для ведения документации, всяких лендингов, сайта-визитки с CV.


ссылка на оригинал статьи https://habr.com/ru/articles/840218/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *