Не используйте HTML для резюме

·~ 8 мин

Дисклеймер

Эта статья — логическое продолжение Не используйте Word для резюме. Настоятельно рекомендую сначала прочитать ее для полного контекста, но я все же кратко напомню основные тезисы:

  1. Резюме должно иметь единый локальный источник истины в легко редактируемом сыром формате.
  2. Этот сырой формат должен конвертироваться в PDF, быть дружелюбным к LLM и ATS, версионируемым и портативным, с точным контролем верстки, богатым и гибким оформлением, удобством написания контента и разделением контента и стиля. Мы предполагаем, что пользователь — разработчик и/или может или хочет освоить этот формат.
  3. HTML подходит на эту роль, но не имел нужного инструментария.
  4. CV.html был создан, чтобы закрыть этот пробел.

Проблемы

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

Повторения

Структура резюме по своей природе повторяема — записи о работе, пункты списков, навыки — но чистый HTML не дает способа это выразить. Например, достижения внутри записи об опыте работы или сами записи об опыте.

Технически это двухуровневый список, и в повседневной работе мы бы использовали циклы и компонентную абстракцию, но чистый HTML не предоставляет таких инструментов. Можно вынести часть разметки в custom element, но все равно придется повторять его много раз в коде, раздувая файл и натыкаясь на все, о чем говорит принцип DRY.

К тому же кто захочет писать веб компоненты для своего резюме?

Изображения

В некоторых странах принято добавлять фото в резюме, и самый портативный способ встроить его в HTML — конвертировать в base64-строку. Если вы хоть раз видели закодированное изображение, знаете, что оно может быть очень большим. В текущей реализации пользователю приходится вставлять его в тег img как атрибут src:

<img src="data:image/[format];base64,[your_base64_string]" />

Это идеально сочетается с предыдущей проблемой, делая HTML еще более раздутым. А теперь представьте, что одно и то же изображение нужно отрендерить несколько раз (как в случае со списком опыта работы). Одна мысль об этом — и уже болит голова.

Мультиязычность

Один из моих сценариев — создание двуязычных резюме с одинаковым внешним видом. В процессе оказлось что это гораздо трудозатратнее из-за проблем выше плюс из-за смешения тегов, классов и самого контента. Можно вставить HTML файл в LLM и попросить перевести, но:

  1. Все равно придется проверять результат и вносить изменения.
  2. Закодированные изображения съедают лишние токены.
  3. Сравните китайскую и английскую версии одного предложения:
    > London is the capital of the United Kingdom.
    > 伦敦是英国的首都。
    

    Очевидно, что китайская версия короче английской. Если просто перевести тот же HTML-шаблон, блоки фиксированного размера и разрывы страниц поплывут. Например, двухстраничное китайское резюме может превратиться в трех- или четырехстраничное английское, что уже может считаться перегруженным. Значит, придется подстраивать стили и структуру шаблона. Помните пример со списком опыта работы? Страшно!

Решение

Не используйте HTML для резюме. Или нет?

Когда я столкнулся с этими проблемами, начал думать, как сохранить плюсы HTML и убрать минусы. И нашел очень хорошее решение.

Концепция

Нужно понять настоящую суть проблемы. Вернемся к нашим требованиям — одно из них было разделение контента и стиля.

CV.html имеет три вкладки: Template, где пользователь пишет HTML; Styles, где пишет CSS; и Head для дополнительных внешних импортов (Tailwind CSS, шрифты и т.д.). Формально разделение контента и стиля через вкладки Template и Styles существует, но на практике все было наоборот.

Потому что этот пункт нужно сформулировать чуть иначе: разделение контента, шаблона и стиля.

Сначала нужно разложить HTML на части контента и шаблона. Определим их:

  • Контент — вся информация в резюме: текст, изображения и любые другие метаданные, нужные шаблону.
  • Шаблонструктура резюме. Его также можно описать как компиляцию контента и стилей по правилам пользователя.

Реализация

Шаблон

Главная техническая проблема — раздел Template. Озвученные проблемы HTML не новы — их уже решили frontend-фреймворки. Но создавать React-приложение для резюме — оверинжиниринг: оно будет тяжелым, пользователю не понадобится большинство возможностей, усложнится экспорт в PDF, а экспорт сырого HTML станет недоступен. Для комфортной работы нужны только следующие возможности фреймворка:

  1. Циклы и условный рендеринг, чтобы убрать повторения.
  2. Привязка к динамическим переменным, передаваемым отдельным контентом.
  3. Статический HTML на выходе.

Это не самый частый сценарий, но вполне валидный — и идеальный инструмент уже существует.

Встречайте, Handlebars!

Коротко, Handlebars — простой язык шаблонов, который принимает шаблон и входной объект и генерирует HTML или другие текстовые форматы. Подробнее о возможностях — в документации, но я остановлюсь только на важном для нас:

  1. Есть циклы и условный рендеринг из коробки.
  2. Есть привязки к переменным-объектам.
  3. Можно скомпилировать в HTML в рантайме.

К тому же синтаксис очень похож на современные frontend-фреймворки, так что бонусом моим коллегам-фронтендерам его будет легко освоить.

Контент

Простая часть — извлечь контент из HTML в JS-объект. Можно создать JSON или YAML файл, где пользователь определяет свой cv — все текстовые данные, атрибуты вроде base64-строки изображения и т.д. — и затем распарсить его.

Потом передаем этот объект в Handlebars и даем пользователю обращаться к нему в шаблоне. Я выбрал YAML, потому что он более читаем для человека, чем JSON.

Результат

Я уже реализовал это решение, протестировал — работает отлично и дает огромную гибкость. Вот как это выглядит на практике:

Хотите двуязычное резюме? Или тот же шаблон для другого человека? Достаточно заменить контент.

Оригинальное резюме CV.html
То же резюме, переведенное на русский
Тот же шаблон для другого пользователя

Или хотите другой дизайн? Без проблем — просто замените шаблон.

Шаблон Pinky-cute
Шаблон Newspaper
Шаблон Terminal

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

Заключение

HTML все еще лучший сырой формат? Технически нет — мы заменили его двумя независимыми файлами yaml и hbs (Handlebars). Но он по-прежнему служит промежуточным форматом между исходными файлами и PDF, и вы по-прежнему можете использовать плюсы HTML — например, отрендерить результат на сайте.

Поэтому я бы все же сказал: относитесь к HTML как к выходному формату, а резюме пишите в абстракциях контента / шаблона. Чистый HTML не дает такого разделения, но в экосистеме уже существуют все нужные инструменты, чтобы этого достичь.