Pull to refresh

GitHub Pages для сайта на 8 марта

Reading time8 min
Views34K
Что такое HTML, CSS, JavaScript и Bootstrap фреймворк сложно объяснять человеку который далек от IT. А что если нужен сайт на бесплатном хостинге, без привязки к онлайн конструкту именно этого хостинга?!



Как думаете, реально научить девушку обновлять свой сайт на GitHub Pages к Международному женскому дню?! Расскажу как мне это удалось с помощью генератора сайта, который доступен на Github и написан на Java + FreeMarker, к тому же старался автоматизировать публикацию контента в git репозитарий.

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

Последнее что я верстал самостоятельно в HTML — был сайт художника во время учебы в университете и тогда была в моде табличная верстка. Веб разработка — не мой хлеб. А сейчас повсюду мобильные браузеры и блочная верстка. Барышня просто хотела сделать простой сайт-визитку, поэтому скрипты на сервере не нужны. При этом идеально было бы, чтобы обновляла фотографии и редактировала разделы этого веб ресурса с нулевым знанием HTML и без моей помощи.

Если ставить CMS — cистему управления содержимым, то хостинг сайта будет дороже и придется тратить время на настройку, шаблоны и безопасность. Слишком сложно для статичного сайта. Мне показалось все это очень похоже на задачу генерации сайта по шаблону. Не знал где найти в наши дни хостинг для сайта без рекламы. Поспрашивав у знакомых, посмотрев варианты и почитав заметки в сети, пришел к выводу что GitHub Pages — идеальный вариант. Бесплатный, версионируемый и поддерживает использование своего доменного имени для сайта.

Для GitHub Pages идеально подходит шаблонизатор jekyll, но разбираться с ним и настройкой на компьютере дизайнера Ruby и jekyll gem совсем не было времени. С jekyll я поиграюсь в другой раз, как будет нужен сайт для своего проекта на GitHub.

Для любого джависта ассоциация с шаблонами — FreeMarker, знакомый многим шаблонный движок. Мне нужно было быстро разработать сайт и генератор, учитывая что Java мой привычный инструмент в работе. Сравнивая FreeMarker с Velocity, первый до сих пор жив и выглядит более функциональным.

Начали с создания аккаунта для дизайнера на GitHub:



Потом перешли к дизайну и верстке. Bootstrap Carousel показался отличным решением для показа изображений, так как основным содержимым веб страниц будут фото из портфолио и просматривать страницы будут на мобильных устройствах.

Раз уж подключил к странице Bootstrap, пригодятся элемент Panel и иконки для навигации/контактов. Для меня верстка была самым нудным этапом в создании сайта. На втором месте по сложности было изменение размера, цветокоррекция и кадрирование большого числа фото для портфолио работ.

Следующий шаг — превращение верстки в шаблон генератора. В шаблоне FreeMarker итерации по коллекции объектов делаются с помощью директивы <#list product as prodItem>...</#list>, а условия с помощью <#if prodItem?is_first>...</#if>. Это все что используется в этих шаблонах генератора.

За основу формата данных для хранения данных выбрал XML разметку. Со структурой быстро определились, на основе макета:

<site>
    <text>.......</text>
    <product id="drapery" background-img="drapery.jpg" title-img="drapery-main.jpg">
        <title>Портьеры, тюль</title>
        <description>Портьеры из плотных тканей...</description>
	<image img="drapery/1.jpg"/>
	...
	<image img="drapery/37.jpg"/>
    </product>
    ...
    <product .../>
</site>

Из XML файла сгенерировал XSD schema в IntelliJ Idea Community Edition.



Классы с аннотациями JAXB для использования в шаблоне генерируются динамически из Maven с помощью jaxb2-maven-plugin. При сборке проекта эти классы размещаются в директории target/generated-sources/jaxb.

Пример фрагмента FreeMarker шаблона для вывода всех изображений портфолио для определенной категории:

        <#list image as imageInfo>
        <div class="item<#if imageInfo?is_first> active</#if>">
            <img src="img/${imageInfo.img}" class="img-responsive center-block">
            <div class="carousel-caption">
            <#if imageInfo.title??>
                <h3>${imageInfo.title}</h3>
                <p></p>
            </#if>
            </div>
        </div>
        </#list>

А вот и пример данных, на основе которых генерируется страница:

    <product id="pillow" background-img="pillow.jpg" title-img="pillow-main.jpg">
        <title>Покрывала, подушки</title>
        <shortDescription>Неотъемлемая часть текстильного декорирования Вашей спальни, придающее уют, изысканность и особенный стиль пространству</shortDescription>
        <description>Роскошное покрывало - это неотъемлемая часть текстильного декорирования Вашей спальни, придающее уют, изысканность и особенный стиль пространству. Со вкусом подобранные ткани и фурнитура, которые сочетаются в шторах, покрывале и подушках, создают гармонию и целостность Вашему интерьеру.</description>
        <image img="pillow/1.jpg"/>
        <image img="pillow/2.jpg"/>
        <image img="pillow/3.jpg"/>
        <image img="pillow/4.jpg"/>
        <image img="pillow/5.jpg"/>
        <image img="pillow/6.jpg"/>
        <image img="pillow/7.jpg"/>
        <image img="pillow/8.jpg"/>
        <image img="pillow/9.jpg"/>
        <image img="pillow/10.jpg"/>
        <image img="pillow/11.jpg"/>
        <image img="pillow/12.jpg"/>
        <image img="pillow/13.jpg"/>
        <image img="pillow/14.jpg"/>
    </product>

В index.html генерируется оглавление на основе всех перечисленных в site.xml тегов <product...> с помощью шаблона.

Как «клей» для шаблонов, основную работу выполняет java класс src/main/java/Site.java и maven скрипт сборки: происходит копирование изображений из директории src/main/resources/img в target/site, из XML схемы генерируются классы c JAXB аннотациями и запускается программа на java с помощью exec-maven-plugin, которая с помощью FreeMarker и данных из site.xml генерирует сайт. Для плагина jaxb2-maven-plugin важно, чтобы xjc из JDK был доступен в одном из путей в переменной окружения PATH.

public class Site {
    public static void main(String[] args) throws Exception {
        File targetDirectory = getTargetDirectory();
        SiteType siteModel = readSiteModel();
        Configuration cfg = getTemplateConfiguration();
        generateIndex(targetDirectory, siteModel, cfg);
        siteModel.getProduct().stream().forEach(product -> generateProduct(targetDirectory, cfg, product));
    }

    private static void generateIndex(File targetDirectory, SiteType siteModel, Configuration cfg) {
        try(Writer out = new FileWriter(new File(targetDirectory, "index.html"))) {
            Template template = cfg.getTemplate("index-template.html");
            template.process(siteModel, out);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    private static void generateProduct(File targetDirectory, Configuration cfg, ProductType product) {
        try(Writer out = new FileWriter(new File(targetDirectory, product.getId() + ".html"))) {
            Template prodTemplate = cfg.getTemplate("product-template.html");
            prodTemplate.process(product, out);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
...
}

Чтобы на компьютере у барышни не приходилось ничего устанавливать кроме JDK, в проект добавил mvn-classloader-1.8.jar, который в первый раз загружает из центрального maven репозитария maven-embedder и запускает сборку проекта и генерацию сайта с параметрами «clean package» и «scm-publish:publish-scm» для публикации сайта на GitHub Pages. Запускает генерацию сайта build.cmd для систем на windows и build.sh для linux. Это сильно упрощает сборку проекта и очень похоже на Gradle Wrapper/Maven Wrapper. Библиотека для maven требует только наличие JVM и подключения к интернет с доступом к центральному репозитарию. Случай изолированных сетей здесь рассматривать не будем, но даже в этом случае работают настройки зеркал и прокси из ~/.m2/settings.xml. Про всю магию этой библиотеки недавно рассказывал в «Модуляризация в JavaSE без OSGI и Jigsaw».

Пару слов про процесс обучения. Рассказывать о системе контроля версий и командах в консоли для Git мне было сложно. Не то что это невыполнимо, но не программиста это пугает. Чтобы она не ошибалась в процессе публикации сайта, я начал искать возможность автоматизировать весь процесс. Чтобы сгенерировать и опубликовать сайт можно было в один клик. Поискав как же легко публиковать сайт в github, обнаружил maven-scm-publish-plugin плагин. Добавил его в maven сборку и сконфигурировал scmpublish.pubScmUrl на адрес репозитария.

Отвлекусь от технологий и вспомню про женский праздник. Все реже можно видеть современных девушек за шитьем и рукоделием. А тут была возможность понаблюдал за работой дизайнера и как она шила:



Узнал про новую для себя область дизайна текстиля в интерьере. И даже не задумывался что существует столько видов штор, тканей и карнизов.

Еще до истории с сайтом смотрел, как она мастерила вместе с мамой подарок на День Рождения друга. Это были забавные чехлы на подушки с котенком и рыбкой, с собачкой.


Ээх, жаль что мне так давно не дарили handmade подарки, даже немного позавидовал.

Было интересно узнать про карнизы с электроприводом для «умного дома» и про опыт их установки. Хочу поэкспериментировать с электроприводом штор, прикрутить их к своему контроллеру на основе STM32 и автоматизировать открытие штор по датчику освещенности или управлять шторами удаленно с телефона. Разобраться с протоколом, подключить свой контроллер красиво и без синей изоленты! Но это уже будет, видимо, после того как разберусь с шаблонами jekyll. До этого видел подобные автоматические рулонные шторы только в Nordstar Tower.

Про то как обновлять контент… Первым делом надо выполнить команду

git clone https://github.com/nadinbox89/site.git

или скачать zip файл проекта с гитхаба:



Дизайнер копирует обработанные изображения для портфолио в директорию src/main/resources/img и добавляет запись в раздел <product...> файла src/main/resources/site.xml. После этого запускает с помощью ярлыка скрипт build.cmd, который создает сайт из данных по шаблонам и публикует его на GitHub Pages в репозитарий nadinbox89.github.io. С небольшой задержкой после git push, версия сайта обновляется по такому же адресу, как и название репозитария на GitHub — nadinbox89.github.io. Если используете в репозитарии запись домена в CNAME, то произойдет автоматическое перенаправление на этот адрес. После обновления сайта, в репозитарии с именем nadinbox89.github.io появляется commit от плагина публикации:



Хорошо бы было спрятать от нее работу с XML совсем, но писать UI для генератора пока нет желания.

Сайт-визитку украсили доменным именем. Взять домен можно почти у любого регистратора за пару сотен рублей. После этого нужно добавить в корень вашего гитхаб репозитария сайта файл CNAME с именем домена. Отлично, если у регистратора доменов есть бесплатные DNS сервера. Их нужно сконфигурировать для GitHub Pages следующим образом:
@ A 192.30.252.153
@ A 192.30.252.154
www CNAME *ваш_github_аккаунт*.github.io.

Где 192.30.252.153, 192.30.252.154 — IP адреса гитхаба. Про настройку доменного имени хорошо описано на stackoverflow и в помощи GitHub. После этого проверил cервисом mobile-friendly и, в целом, сайт неполохо работает с мобильными браузерами.


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


Заключение


Для хостинга простого статичного сайта-визитки отлично подходит GitHub Pages и все затраты — это время на верстку и покупка доменного имени за пару сотен рублей. Алгоритм не сложный и описан в этой статье:

  1. Регистрация аккаунта на github
  2. Создание репозитария *ваш_github_аккаунт*.github.io
  3. Сохранение статики (html, css, изображений) в репозитарий *ваш_github_аккаунт*.github.io
  4. Регистрация домена и создание записей DNS сервера указывающих на адрес из 3 пункта
  5. Добавить файл CNAME в корень репозитария с именем вашего домена

Генерировать html можно как с помощью встроенного в GitHub шаблонного jekyll, так и с помощью java программы и шаблонов на FreeMarker, что с моим опытом показалось проще. Так же удобно публиковать сайт на GitHub сразу из maven сборки c помощью maven-scm-publish-plugin. Требуется только настроить логин/пароль в скрипте, чтобы плагин для публикации смог выполнить git push. Мой подарок к 8 марта удался!
Tags:
Hubs:
Total votes 34: ↑23 and ↓11+12
Comments56

Articles