Не используйте HTML для резюме
Дисклеймер
Эта статья — логическое продолжение Не используйте Word для резюме. Настоятельно рекомендую сначала прочитать ее для полного контекста, но я все же кратко напомню основные тезисы:
- Резюме должно иметь единый локальный источник истины в легко редактируемом сыром формате.
- Этот сырой формат должен конвертироваться в PDF, быть дружелюбным к LLM и ATS, версионируемым и портативным, с точным контролем верстки, богатым и гибким оформлением, удобством написания контента и разделением контента и стиля. Мы предполагаем, что пользователь — разработчик и/или может или хочет освоить этот формат.
- HTML подходит на эту роль, но не имел нужного инструментария.
- CV.html был создан, чтобы закрыть этот пробел.
Проблемы
С тех пор я много работал со своим инструментом, экспериментируя со стилями, контентом, визуальным дизайном и прочим. На бумаге все звучит отлично, но на практике проявились неожиданные проблемы.
Повторения
Структура резюме по своей природе повторяема — записи о работе, пункты списков, навыки — но чистый HTML не дает способа это выразить. Например, достижения внутри записи об опыте работы или сами записи об опыте.
Технически это двухуровневый список, и в повседневной работе мы бы использовали циклы и компонентную абстракцию, но чистый HTML не предоставляет таких инструментов. Можно вынести часть разметки в custom element, но все равно придется повторять его много раз в коде, раздувая файл и натыкаясь на все, о чем говорит принцип DRY.
К тому же кто захочет писать веб компоненты для своего резюме?
Изображения
В некоторых странах принято добавлять фото в резюме, и самый портативный способ встроить его в HTML — конвертировать в base64-строку. Если вы хоть раз видели закодированное изображение, знаете, что оно может быть очень большим. В текущей реализации пользователю приходится вставлять его в тег img как атрибут src:
<img src="data:image/[format];base64,[your_base64_string]" />
Это идеально сочетается с предыдущей проблемой, делая HTML еще более раздутым. А теперь представьте, что одно и то же изображение нужно отрендерить несколько раз (как в случае со списком опыта работы). Одна мысль об этом — и уже болит голова.
Мультиязычность
Один из моих сценариев — создание двуязычных резюме с одинаковым внешним видом. В процессе оказлось что это гораздо трудозатратнее из-за проблем выше плюс из-за смешения тегов, классов и самого контента. Можно вставить HTML файл в LLM и попросить перевести, но:
- Все равно придется проверять результат и вносить изменения.
- Закодированные изображения съедают лишние токены.
- Сравните китайскую и английскую версии одного предложения:
> 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 станет недоступен. Для комфортной работы нужны только следующие возможности фреймворка:
- Циклы и условный рендеринг, чтобы убрать повторения.
- Привязка к динамическим переменным, передаваемым отдельным контентом.
- Статический HTML на выходе.
Это не самый частый сценарий, но вполне валидный — и идеальный инструмент уже существует.
Встречайте, Handlebars!
Коротко, Handlebars — простой язык шаблонов, который принимает шаблон и входной объект и генерирует HTML или другие текстовые форматы. Подробнее о возможностях — в документации, но я остановлюсь только на важном для нас:
- Есть циклы и условный рендеринг из коробки.
- Есть привязки к переменным-объектам.
- Можно скомпилировать в HTML в рантайме.
К тому же синтаксис очень похож на современные frontend-фреймворки, так что бонусом моим коллегам-фронтендерам его будет легко освоить.
Контент
Простая часть — извлечь контент из HTML в JS-объект. Можно создать JSON или YAML файл, где пользователь определяет свой cv — все текстовые данные, атрибуты вроде base64-строки изображения и т.д. — и затем распарсить его.
Потом передаем этот объект в Handlebars и даем пользователю обращаться к нему в шаблоне. Я выбрал YAML, потому что он более читаем для человека, чем JSON.
Результат
Я уже реализовал это решение, протестировал — работает отлично и дает огромную гибкость. Вот как это выглядит на практике:
Хотите двуязычное резюме? Или тот же шаблон для другого человека? Достаточно заменить контент.
Или хотите другой дизайн? Без проблем — просто замените шаблон.
Вариантов кастомизации так много, что я до сих пор нахожу новые идеи использования и дизайны. При желании, вы тоже можете поэксперементировать в CV.html.
Заключение
HTML все еще лучший сырой формат? Технически нет — мы заменили его двумя независимыми файлами yaml и hbs (Handlebars). Но он по-прежнему служит промежуточным форматом между исходными файлами и PDF, и вы по-прежнему можете использовать плюсы HTML — например, отрендерить результат на сайте.
Поэтому я бы все же сказал: относитесь к HTML как к выходному формату, а резюме пишите в абстракциях контента / шаблона. Чистый HTML не дает такого разделения, но в экосистеме уже существуют все нужные инструменты, чтобы этого достичь.