Как вы уже наверное заметили, в последний месяц я много экспериментировал с внешним видом своего блога. Наконец, этот долгий этап подошёл к концу и то, что вы сегодня можете наблюдать на страницах этого ресурса, является финальной версией дизайна сайта. Скорее всего будет ещё несколько незначительных изменений и улучшений, но общая концепция останется прежней. В соответствии с современными тенденциями внешнего вида интерфейсов, дизайн блога стал более простым и «плоским», без различных градиентов и выпуклых кнопок, чтобы ничего не отвлекало от чтения полотна текстовой информации. Кроме того, яркие оранжевые цвета, раздражающие многих посетителей ресурса, были изменены на нейтральные синие и серые тона. Но для тех, кому нравился яркий оранжевый цвет, была оставлена возможность его возвращения путём переключения цветовых схем. Благодаря этому механизму удалось сделать поддержку тёмного скина, который тоже может приглянуться посетителям моего блога.
Новый дизайн ресурса, выбран скин «Серая безмятежность», скриншот сделан в браузере Safari.
Делать собственную тему с нуля для блога на движке WordPress, не имея опыта работы с ним, достаточно накладно и сложно. Поэтому было решено пойти по самому простому пути. Я попробовал найти какой-нибудь красивый и популярный WordPress-шаблон и изменив вёрстку, дизайн и функциональность, превратить его в эксклюзивную тему для моего ресурса. Я достаточно долго перебирал огромное количество кастомных шаблонов, но так и не находил ничего из того, что мне бы сразу безоговорочно понравилось. На самом деле то, что я искал, лежало всегда на виду. Я слишком поздно заглянул в стандартные темы WordPress’а, решив что там не будет ничего интересного. И очень даже зря, стоковый шаблон Twenty Fourteen выглядел весьма симпатично. На его основе я и решил создать тему Moto Juice, немного упростив вёрстку и добавив требуемые возможности. Эта тема отлично смотрелась и работала не только на настольных компьютерах, но и на мобильных устройствах.
Если вы не впервые попали на мой ресурс, то наверное помните старую и ужасную тему сайта. Она была создана в далёком 2010 году за несколько минут в проприетарной программе Artisteer из комбинации нескольких похожих друг на друга случайных блоков. Я назвал её Moto Orange, поскольку она получилась у меня в ярких оранжевых тонах. Затем я просто набрал в популярном графическом редакторе каким-то светлым шрифтом с тенью заголовок, вставил его в шапку и установил этот шаблон в качестве дефолтной темы WordPress. Поддерживать Moto Orange было тем ещё «удовольствием», поскольку весь код темы был автоматически сгенерирован программой Artisteer. Ещё это сильно влияло и на безопасность, так как аудит сгенерированного кода никто никогда не проводил.
Старый и ужасный дизайн моего блога, тема Moto Orange, скриншот сделан в браузере Chrome (превью, увеличение по клику).
Мой блог переехал на WordPress достаточно давно, когда ещё не было такого активного развития мобильных устройств и планшетов, поэтому тема Moto Orange получилась абсолютно неприспособленной к современному миру. А потому поисковики, например, Google, понижали сайт в своей выдаче результатов поиска. Стало ясно, что мне требуется тема с адаптивной вёрсткой. К счастью, в шаблоне Twenty Fourteen, который я выбрал в качестве отправной точки и базы, эта функциональность досталась мне в наследство.
Предупреждение Google, выдаваемое на моей старой теме Moto Orange, скриншот из браузера Firefox.
Тема Twenty Fourteen использует такие современные технологии, как библиотеку jQuery и иконки из векторного шрифта Genericons. Специалист по Web-технологиям и дизайнер из меня довольно плохой, знание языков программирования PHP, JavaScript и языка описания внешнего вида CSS у меня на начальном уровне, поэтому, если какое-либо решение вызывает у вас удивление и негодование, прошу меня простить, это мой первый опыт использования современных Web-технологий в действии.
Содержание:
1. Конфигурация Web-сервера Nginx для WordPress
2. Отключение избыточной функциональности
3. Главное меню и проблемы с боковой панелью
4. Классный логотип в шапку блога
5. Виджет с моими случайными проектами
6. Виджет переключения цветовых скинов
7. Некоторые дополнительные улучшения темы
8. Локализация темы WordPress
9. Заключение, полезные советы, ссылки и информация
1. Конфигурация Web-сервера Nginx для WordPress
Движок WordPress достаточно легко установить на Web-сервер Nginx, в интернете полно материалов, посвящённых процессу установки. Однако, очень многие системные администраторы забывают правильно отредактировать дефолтный конфигурационный файл Nginx’а. Из-за чего на многих WordPress-сайтах, запущенных на этом Web-сервере, возникает очень интересный баг: при использовании внутреннего поиска невозможно перейти на вторую страницу выдачи результатов. Вместо перехода просто перебрасывает на вторую страницу главной, где содержится общая лента постов.
Оказывается, нужно просто немного изменить дефолтный конфигурационный файл Nginx, добавив конструкцию ?$args сразу после index.php в секции try_files раздела location. Это должно выглядеть приблизительно вот так:
1 2 3 4 5 6 7 8 |
server { location / { try_files $uri $uri/ /index.php?$args; } ... } |
На исправление этой досадной ошибки я потратил достаточно много времени и нервов. В начале я винил свой новоиспечённый шаблон, думал, что каким-то магическим образом нарушил пагинацию страниц в нём, но, как оказалось, на старой теме тоже присутствует этот баг. Я даже попробовал переключиться на стандартные шаблоны и баг сохранился. А это могло означать только одно: причина неправильного поведения была гораздо глубже и заключалась в Web-сервере. Спустя несколько минут поиска я наткнулся на решение проблемы на ресурсе wordpress.stackexchange.com, которое выложил пользователь, использующий ник MultiformeIngegno, огромное ему спасибо за это.
Так что, если у вас в WordPress, развёрнутом на Nginx, не работает переход на вторую страницу результатов поиска, то данная информация поможет вам решить эту проблему и сэкономить время.
2. Отключение избыточной функциональности
В самом начале создания собственной темы на основе шаблона Twenty Fourteen, я решил отключить избыточную для моего блога функциональность. Мне очень не нравится, когда на сайтах при чтении текста во время прокрутки страницы по ней перемещаются различные интерфейсные элементы, вроде кнопок или шапки. Они мешают читать и отвлекают на себя внимание. Поэтому первым делом я отключил «плавающий» заголовок в главном стиле темы, в файле style.css:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
diff --git a/style.css b/style.css index 4221371..05cebab 100644 --- a/style.css +++ b/style.css @@ -3453,12 +3453,11 @@ a.post-thumbnail:hover { /* Fixed Header */ .masthead-fixed .site-header { - position: fixed; - top: 0; + position: relative; } .admin-bar.masthead-fixed .site-header { - top: 32px; + top: 0px; } .masthead-fixed .site-main { |
Кроме того, на старой теме я вообще не пользовался тегами, мне было достаточно различных категорий. Поэтому теги были использованы мной для ключевых поисковых фраз, что выглядело не очень прилично. Я решил вообще отключить вывод тегов, раз так и не научился их правильно готовить. Для этого я удалил из всех релевантных PHP-файлов строку:
1 |
<?php the_tags( '<footer class="entry-meta"><span class="tag-links">', '', '</span></footer>' ); ?> |
Помимо этих небольших преобразований я отцентрировал контент страницы по середине окна, увеличил размер сайта до 1366 пикселей по ширине, уменьшил всевозможные отступы, удалил нестандартный шрифт Lato, немного переделал подвал сайта, изменил базовые цвета темы и сделал ещё много мелких изменений, которые можно будет посмотреть в истории коммитов репозитория (ссылка на него будет ниже).
3. Главное меню и проблемы с боковой панелью
Стандартное главное меню, которое можно вызывать нажав на кнопку в шапке мобильной версии сайта, в теме Twenty Fourteen было недостаточно функциональным. Оно было практически бесполезным, поскольку отображало лишь несколько страничек, которые были опубликованы для всех посетителей блога.
Главное меню сайта, шаблон Twenty Fourteen, скриншот из мобильной версии браузера Chrome.
Я решил немного увеличить его функциональность и перенести туда содержимое боковой панели. Для этого я отредактировал файл header.php следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
diff --git a/header.php b/header.php index d21a652..e501a4a 100644 --- a/header.php +++ b/header.php @@ -93,7 +93,10 @@ <nav id="primary-navigation" class="site-navigation primary-navigation" role="navigation"> <button class="menu-toggle"><?php _e( 'Primary Menu', 'twentyfourteen' ); ?></button> <a class="screen-reader-text skip-link" href="#content"><?php _e( 'Skip to content', 'twentyfourteen' ); ?></a> - <?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu', 'menu_id' => 'primary-menu' ) ); ?> + <div id="primary-menu" class="nav-menu" aria-expanded="true"> + <?php dynamic_sidebar( 'sidebar-1' ); ?> + </div> </nav> </div> |
Потом немного поправил главный стиль темы так, чтобы этим меню было удобно пользоваться на мобильных устройствах и планшетах. Получилось, на мой взгляд, весьма неплохо и функционально:
Главное меню сайта с моими добавлениями, шаблон Moto Juice, скриншот из мобильной версии браузера Chrome (превью, увеличение по клику).
Главный плюс такого подхода в том, что все виджеты WordPress’а, которые я добавлю на боковую панель, будут отображаться и в меню сайта мобильной версии. Например, я добавил туда строку поиска и сортировку постов по рубрикам. Функциональность панели полностью повторяет главное меню, это отличное решение для навигации по страницам моего блога.
Кроме того, я поправил ещё одно досадное недоразумение в теме Twenty Fourteen. Почему-то в этом шаблоне изначально был очень странный порядок загрузки блоков сайта: в начале загружалась шапка, потом контент страницы, потом боковая панель и, наконец, подвал. Если страница содержала много текста и долго загружалась, то боковая панель прогружалась с огромной задержкой, что откровенно раздражало, так как она появлялась внезапно и отвлекала на себя внимание. Я исправил порядок загрузки таким образом, чтобы боковая панель грузилась сразу после шапки. Все мои изменения были произведены в тех PHP-файлах, где встречалась следующая конструкция:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
diff --git a/404.php b/404.php index 7f5bef8..c23b707 100644 --- a/404.php +++ b/404.php @@ -7,7 +7,8 @@ * @since Twenty Fourteen 1.0 */ -get_header(); ?> +get_header(); +get_sidebar(); ?> <div id="primary" class="content-area"> @@ -28,5 +29,4 @@ get_header(); ?> <?php get_sidebar( 'content' ); -get_sidebar(); get_footer(); |
Ещё я немного отредактировал стиль и незначительно поправил файл js/functions.js с различными вспомогательными функциями, например, в нём была обработка нажатия кнопки в шапке сайта. По моему скромному мнению, именно такой порядок загрузки и должен был быть в шаблоне сразу. Я до сих пор не понимаю зачем и с какой целью разработчикам темы понадобилось его изменять. После моих исправлений раздражающий эффект запоздалого отображения боковой панели полностью исчез.
4. Классный логотип в шапку блога
Как уже было сказано выше, для старой темы Moto Orange я просто набрал название ресурса незамысловатым шрифтом с тенью и добавил его изображением в шапку. Для новой темы Moto Juice я решил сделать красивый логотип в стиле Graffiti, поскольку этот стиль мне очень нравится. К сожалению, художник из меня совсем плохой и всё что я пытался нарисовать выглядело весьма неказисто и невзрачно. Я хотел изобразить надпись в таком вот стиле:
Надпись Style в стиле Graffiti.
Но у меня ничего не получалось. Тогда я решил доверить это дело профессионалам и обратился к своему другу Zorge.R‘у за помощью. Мы с ним целых полчаса выбирали какой-нибудь похожий и интересный шрифт в Graffiti-стиле на замечательном ресурсе dafont.com. В конце концов остановились на двух шрифтах: Docallisme On Street и Next Ups. Увы, но первый шрифт оказался собран с какой-то ошибкой и не смог нормально отрендерится в Photoshop’е у Zorge.R’а. Зато второй шрифт отлично отобразился и я решил использовать именно его.
Zorge.R набрал этим шрифтом название моего блога, преобразовал текст в объёмный 3D-слой, добавил обводки и градиент на гранях глифов. Затем немного сбил плотность букв в логотипе, чтобы он смотрелся более компактно и контрастно. В завершении дополнил надпись несколькими штрихами круглой красной кисти, как в это было сделано на оригинальном изображении выше.
Классный логотип блога, который сделал мне Zorge.R.
Получилось просто здорово, огромное спасибо Zorge.R’у за работу! Логотип не только отлично вписался в шапку сайта, он ещё идеально подошёл ко всем цветовым скинам, которые я реализовал немного позже. Ещё отдельная благодарность создателю шрифта Next Ups, который использует ник imagex, за то, что поделился результатами своего творчества.
5. Виджет с моими случайными проектами
Изначально шапка в шаблоне Twenty Fourteen выглядела довольно узкой, поэтому я решил сделать её немного шире и добавить в появившееся пространство какую-нибудь полезную информацию. В качестве источника этой информации я решил выбрать несколько моих актуальных проектов для различных платформ, над которыми я работал в последнее время. Поскольку этих проектов было больше пяти, а место в шапке не было бесконечным, я решил выводить только пять случайных пунктов из всего списка. При наведении курсора мышки на иконку, сбоку слева отображается небольшое описание проекта. В целом получилось достаточно симпатично:
Виджет со случайными проектами, скриншот из браузера Firefox (превью, увеличение по клику).
Для этого виджета я создал специальный PHP-файл headerwidget.php, в котором написал код случайного выбора пяти уникальных элементов из общего массива. Этот файл выглядит следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<div class="headerWidget" id="headerWidgetId"> <?php $imagesCount = 5; $themeDir = get_stylesheet_directory_uri(); $imageLinks = array( "<a href=\"//exlmoto.ru/spout-droid/\" title=\"Spout\">" . "<img class=\"imgElem\" id=\"imgElem0\" src=\"" . $themeDir . "/images/widget/0.png\" />" . "</a>", "<a href=\"//exlmoto.ru/kenlab3d-droid/\" title=\"Ken's Labyrinth\">" . "<img class=\"imgElem\" id=\"imgElem1\" src=\"" . $themeDir . "/images/widget/1.png\" />" . "</a>", "<a href=\"//exlmoto.ru/astrosmash-droid/\" title=\"AstroSmash\">" . "<img class=\"imgElem\" id=\"imgElem2\" src=\"" . $themeDir . "/images/widget/2.png\" />" . "</a>", "<a href=\"//exlmoto.ru/snooder21-droid/\" title=\"Snooder 21\">" . "<img class=\"imgElem\" id=\"imgElem3\" src=\"" . $themeDir . "/images/widget/3.png\" />" . "</a>", "<a href=\"//exlmoto.ru/bezier-clock/\" title=\"Bezier Clock\">" . "<img class=\"imgElem\" id=\"imgElem4\" src=\"" . $themeDir . "/images/widget/4.png\" />" . "</a>", "<a href=\"//exlmoto.ru/nxengine/\" title=\"Cave Story\">" . "<img class=\"imgElem\" id=\"imgElem5\" src=\"" . $themeDir . "/images/widget/5.png\" />" . "</a>", "<a href=\"//exlmoto.ru/writing-telegram-bots/\" title=\"Gadget Hackwrench\">" . "<img class=\"imgElem\" id=\"imgElem6\" src=\"" . $themeDir . "/images/widget/6.png\" />" . "</a>" ); $lengthArr = count($imageLinks); $randNum = rand(0, $lengthArr - 1); $offset = ($randNum + $imagesCount) - $lengthArr; if ($randNum <= $lengthArr - $imagesCount) { for ($i = $randNum; $i < $randNum + $imagesCount; $i++) { echo $imageLinks[$i]; } } else { for ($j = $randNum; $j < $lengthArr; $j++) { echo $imageLinks[$j]; } for ($k = 0; $k < $offset; $k++) { echo $imageLinks[$k]; } } ?> <?php /* * Please use the PoEdit program for changing the descriptions. Don't edit this labels manually! * PoEdit site: https://poedit.net/ */ ?> <div class="imgDescription" id="imgDesc0"><?php printf( __( '<b>Project 1</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc1"><?php printf( __( '<b>Project 2</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc2"><?php printf( __( '<b>Project 3</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc3"><?php printf( __( '<b>Project 4</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc4"><?php printf( __( '<b>Project 5</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc5"><?php printf( __( '<b>Project 6</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc6"><?php printf( __( '<b>Project 7</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc7"><?php printf( __( '<b>Project 8</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc8"><?php printf( __( '<b>Project 9</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc9"><?php printf( __( '<b>Project 10</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc10"><?php printf( __( '<b>Project 11</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc11"><?php printf( __( '<b>Project 12</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc12"><?php printf( __( '<b>Project 13</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc13"><?php printf( __( '<b>Project 14</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc14"><?php printf( __( '<b>Project 15</b> Description.', 'moto-juice' ) ); ?></div> <div class="imgDescription" id="imgDesc15"><?php printf( __( '<b>Project 16</b> Description.', 'moto-juice' ) ); ?></div> </div> |
В массиве imageLinks в HTML-разметке хранится список всех ссылок на проекты, вместе с их иконками. Алгоритм получения массива из пяти случайных и уникальных элементов тривиален. В начале выбирается случайное число-указатель, которое определяет индекс элемента в общем массиве, который будет нашим первым элементом и точкой отсчёта. Затем отбираются последующие четыре элемента, которые находятся правее. Если происходит вылет за границы первоначального массива, недостающие элементы добираются с его конца. Далее располагаются шестнадцать уже подготовленных строк-заглушек. Эти строки переводятся в индивидуальное описание каждого проекта благодаря встроенной системе перевода в WordPress. Когда все строки закончатся, я просто добавлю новые и обновлю файлы переводов.
Для того, чтобы всё это работало, получившийся файл был включён в header.php и в него же были добавлены два блока. Первый, mainDescription, используется для описания проекта, а второй, secondDescription, используется для приветствия, которое постоянно отображается в шапке ресурса:
1 2 3 4 |
<?php include_once("headerwidget.php") ?> <div class="mainDescription" id="imgDescMain"></div> <div class="secondDescription" id="imgDescSecond"><?php printf( __( 'Welcome!', 'moto-juice' ) ); ?></div> |
Для того, чтобы описание проектов менялось в зависимости от того, на какую иконку был наведён курсор мышки, я использовал магию JavaScript и добавил в файл js/functions.js следующее:
1 2 3 4 5 6 7 8 9 10 |
// Show or Hide Image Widget description // substring(7) because imgDescX jQuery('.imgElem').mouseenter(function() { jQuery('.mainDescription').html(jQuery('#imgDesc' + $(this).attr('id').substring(7)).html()); jQuery('.mainDescription').show(); }); jQuery('.imgElem').mouseleave(function() { jQuery('.mainDescription').hide(); }); |
При наведении курсора на иконку берётся её идентификационный номер и вызывается функция отображения нужного текстового описания. После того, как курсор покинет область иконки, описание скрывается. Стиль для виджета в файле style.css используется следующий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/* Header Widget Settings */ .headerWidget { position: absolute; right: 64px; top: 58px; } .imgElem { float: right; margin-left: 5px; border: none; } .imgElem:hover { outline: 1px solid white; } .imgDescription { display: none; } .mainDescription, .secondDescription { position: absolute; top: 58px; font-size: 10px; color: #F5F5F5; } .mainDescription { display: none; left: 280px; width: 470px; } .mainDescription b { color: #EEE8AA; font-weight: bold; } .secondDescription { left: 30px; width: 240px; } .widgetBreaker { position: absolute; top: 48px; width: 100%; margin: 0 0 0 0; background-color: black; } .widget ul { font-size: 1.1em; } |
Как видно выше, все объекты класса mainDescription по умолчанию скрыты и отображаются лишь тогда, когда на них будет наведён курсор мышки. Иконка проекта подсвечивается с помощью рамки, которая задаётся свойством outline и не изменяет размеров блока.
Таким образом, чтобы добавить дополнительный проект в этот виджет, мне потребуется произвести всего три простейших действия:
- Добавить дополнительную строку в массив imageLinks;
- Загрузить иконку проекта в директорию images/widget/;
- Перевести стандартную строку-заглушку описания нужным образом (об этом будет ниже).
Виджет с проектами отображается только в настольной версии сайта, потому что в мобильной и планшетной версии он бесполезен и лишь занимает полезное пространство на небольшом экране.
6. Виджет переключения цветовых скинов
Идея кастомизации блога с помощью цветовых схем мне пришла в голову после того, как я начал активно изменять цвета в главном CSS-стиле шаблона. Я хотел выполнить дизайн блога в нейтральных и спокойных тонах, но некоторые читатели привыкли к ярким и сочным оттенкам. Почему бы не угодить и тем, и другим, сделав аккуратный виджет и механизм переключения CSS-стилей? Я задумался над реализацией и размещением такого виджета и получилось следующее:
Виджет переключения цветовых скинов, расположенный в правой части подвала сайта, скриншот из браузера Chrome.
Виджет я разместил внизу блога, на правой стороне подвала. Он представляет из себя восемь небольших цветных квадратов, при нажатии на которые будет перегружена страница и выбрана соответствующая цветовая схема.
Работает это следующим образом: в PHP-файл footer.php, который отвечает за подвал сайта, был добавлен следующий блок кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<div class="skin-selector"> <table class="skin-table" cellspacing="5" cellpadding="0"> <tr> <td><div name="Skin0" class="skinClass" title="<?php printf( __( 'Light Skin', 'moto-juice' ) ); ?>" id="skinDefault"></div></td> <td><div name="Skin1" class="skinClass" title="<?php printf( __( 'Gray Skin', 'moto-juice' ) ); ?>" id="skinOgre"></div></td> </tr> <tr> <td><div name="Skin2" class="skinClass" title="<?php printf( __( 'Green Skin', 'moto-juice' ) ); ?>" id="skinGreen"></div></td> <td><div name="Skin3" class="skinClass" title="<?php printf( __( 'Orange Skin', 'moto-juice' ) ); ?>" id="skinOrange"></div></td> </tr> <tr> <td><div name="Skin4" class="skinClass" title="<?php printf( __( 'Blue Skin', 'moto-juice' ) ); ?>" id="skinBlue"></div></td> <td><div name="Skin5" class="skinClass" title="<?php printf( __( 'Yellow Skin', 'moto-juice' ) ); ?>" id="skinYellow"></div></td> </tr> <tr> <td><div name="Skin6" class="skinClass" title="<?php printf( __( 'Solarized Skin', 'moto-juice' ) ); ?>" id="skinSolarized"></div></td> <td><div name="Skin7" class="skinClass" title="<?php printf( __( 'Dark Skin', 'moto-juice' ) ); ?>" id="skinDark"></div></td> </tr> </table> </div> |
Это табличная вёрстка, благодаря которой и создаётся таблица из нужного количества квадратов. Чтобы эти квадраты были разноцветными, в файл требуемого стиля скина добавлены следующие фрагменты:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
/* Skin Widget */ .skin-table { margin-bottom: 0px; border-spacing: 0px; } .skin-table, .skin-table tr, .skin-table td, .skin-table th { border: none; } .skin-selector { position: relative; display: inline-block; float: right; width: 35px; margin-top: 4px; margin-right: 2px; z-index: 9; } .skinClass { height: 10px; width: 10px; border: 1px solid black; margin-bottom: 2px; } #skinDefault { background-color: #6699CC; border: 1px solid white; } #skinOgre { background-color: #B5B8B1; border: 1px solid black; } #skinGreen { background-color: #4CBB17; border: 1px solid black; } #skinOrange { background-color: #FF7E00; border: 1px solid black; } #skinBlue { background-color: #B0C4DE; border: 1px solid black; } #skinYellow { background-color: #FFFF00; border: 1px solid black; } #skinSolarized { background-color: #C1B58D; border: 1px solid black; } #skinDark { background-color: #696969; border: 1px solid black; } |
Задействованная цветовая схема выделена белой рамкой. Теперь снова переходим к магии JavaScript, чтобы закрепить действия за нажатием на эти цветные квадратики. Для этого я добавил в файл js/functions.js несколько функций и изменений:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function setCookie(key, value) { var expires = new Date(); expires.setTime(expires.getTime() + (365 * 24 * 60 * 60 * 1000)); document.cookie = key + '=' + value + ';path=/' + ';expires=' + expires.toUTCString(); } ... ( function( $ ) { // Switch Skins jQuery('.skinClass').click(function() { var i = $(this).attr('name').slice(-1); setCookie('skin', i); location.reload(); }); ... } |
В принципе, здесь абсолютно нет ничего сложного: каждому цветному квадрату добавляется собственный обработчик нажатия, который устанавливает идентифицирующую переменную скина skin в хранилище Cookies с помощью функции setCookie(), а потом просто перегружает страницу.
Далее в действие вступает PHP-файл colorize.php, который включается в header.php и выглядит следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php switch (intval($_COOKIE["skin"])) { default: case 0: break; case 1: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_gray.css\" title=\"gray\" />\n"; break; case 2: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_green.css\" title=\"green\" />\n"; break; case 3: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_orange.css\" title=\"orange\" />\n"; break; case 4: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_blue.css\" title=\"blue\" />\n"; break; case 5: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_yellow.css\" title=\"yellow\" />\n"; break; case 6: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_solarized.css\" title=\"solarized\" />\n"; break; case 7: echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . get_stylesheet_directory_uri() . "/style_dark.css\" title=\"dark\" />\n"; break; } ?> |
Здесь с помощью языка программирования PHP мы читаем ранее сохранённую в Cookie переменную skin и в соответствии с её значением подгружаем требуемый стиль скина из отдельных CSS-файлов. Эти файлы представляют собой копии главного стиля темы, но с изменёнными цветами и незначительными исправлениями.
Благодаря этому механизму удалось сделать целых восемь различных цветных скинов и читатель моего блога теперь может настроить внешний вид сайта в соответствии со своим вкусом и предпочтениями. В некоторых скинах, например, в тёмном, прописано изменение не только базовых элементов ресурса, но и цветовой подсветки кода. Это достигается просто расширением CSS-стиля с добавлением в него подходящей темы WordPress-плагина Crayon, который отвечает за подсветку кода.
Новый дизайн моего блога, используется шаблон Moto Juice, выбран скин «Тёмная полночь», скриншот сделан в браузере Chrome (превью, увеличение по клику).
В качестве цветовой схемы сайта по умолчанию был установлен наиболее нейтральный скин в классических тонах, к которым все уже давно привыкли и которые меньше всего вызывают раздражение: оттенки синего, серый, белый, жёлтый и бежевый цвета.
7. Некоторые дополнительные улучшения темы
Ссылки на рубрики в боковой панели блога было решено сделать блочными, так их гораздо удобнее нажимать и в мобильной версии сайта, и в настольной. К сожалению, дело не обошлось просто правкой CSS, так как эти ссылки хитро создавались самим виджетом. Я решил не разбираться как они генерируются в дебрях движка WordPress, ведь все мои изменения после очередного обновления были бы отменены. Поэтому пришлось патчить их «на лету» с помощью JavaScript, для этого в файл js/functions.js я добавил следующее:
1 2 3 4 5 6 7 8 9 10 |
// Hack for Categories Widget if (jQuery('.cat-item')) { for (var i = 0; i < jQuery('.cat-item').length; ++i) { var s = jQuery('.cat-item')[i].innerHTML; s = s.replace('</a>', '').trim() + '</a>'; jQuery('.cat-item')[i].innerHTML = s; } } jQuery('.widget a').css({ display: "block" }); |
Справа от ссылки написано число статей в рубрике и эта цифра является обычным текстом, а не её частью. Этим фрагментом кода я вношу число в ссылку, а закрывающий тег выношу за цифру. Затем применяю CSS-свойство block к общему классу ссылок в виджете. Цвет ссылок и цвет текста в боковой панели с помощью CSS сделан одинаковым, поэтому в момент выполнения Js-кода нет резкого перехода и на странице ничего не мелькает.
Ещё одно улучшение, которое я добавил в тему — прокрутка страницы на самый верх при нажатии на пустое место в боковой панели:
1 2 3 4 |
// Click to the sidebar to top of page jQuery("#sec-block").click( function() { $("html, body").animate({ scrollTop: 0 }, "slow"); }); |
Практически все мои последние посты в блоге весьма объёмные и это нововведение значительно упрощает навигацию. Теперь, чтобы перейти в самое начало статьи, не нужно тянуться к клавиатуре или долго прокручивать страницу колесом мышки.
Ещё одно улучшение предложил мой друг yakimka, посоветовав добавить возможность полного скрытия боковой панели, чтобы ничего не отвлекало от чтения текста, как это было сделано в мобильной и планшетной версиях сайта. С помощью CSS и JavaScript я легко реализовал эту функциональность:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
function hideSideBar() { $('#secondary').hide(); $('#sec-block').hide(); $('#content').css('margin-left', '0px'); } function showSideBar() { $('#secondary').show(); $('#sec-block').show(); $('#content').css('margin-left', '130px'); } // Enable menu toggle for small screens. ( function() { if ( ! nav.length || ! button.length ) { return; } // Hide button if menu is missing or empty. if ( ! menu.length || ! menu.children().length ) { button.hide(); return; } button.on( 'click.twentyfourteen', function() { var width = Math.max( $(window).width(), window.innerWidth); if (width < 1008) { isPushedMenu = !isPushedMenu; nav.toggleClass( 'toggled-on' ); if ( nav.hasClass( 'toggled-on' ) ) { $( this ).attr( 'aria-expanded', 'true' ); menu.attr( 'aria-expanded', 'true' ); } else { $( this ).attr( 'aria-expanded', 'false' ); menu.attr( 'aria-expanded', 'false' ); } } else { isPushedSideBar = !isPushedSideBar; if (isPushedSideBar) { hideSideBar(); } else { showSideBar(); } } } ); } )(); function onResizeARIA() { // http://stackoverflow.com/a/8501499/2467443 var width = Math.max( $(window).width(), window.innerWidth); // Hack for disable main description widget if ( width < 1218 ) { jQuery('.mainDescription').hide(); } if ( width < 1008 ) { button.attr( 'aria-expanded', 'false' ); menu.attr( 'aria-expanded', 'false' ); hideSideBar(); isPushedSideBar = true; //button.attr( 'aria-controls', 'primary-menu2' ); } else { if (isPushedMenu) { nav.toggleClass( 'toggled-on' ); // console.log('isPushedMenu!') isPushedMenu = false; } if (isPushedSideBar) { showSideBar(); isPushedSideBar = false; } button.removeAttr( 'aria-expanded' ); menu.removeAttr( 'aria-expanded' ); //button.removeAttr( 'aria-controls' ); } } _window .on( 'load.twentyfourteen', onResizeARIA ) .on( 'resize.twentyfourteen', function() { onResizeARIA(); } ); |
Функции hideSideBar() и showSideBar(), как видно из их названия, скрывают и показывают боковую панель. Они вызываются в изначально написанном обработчике button.on(), который отвечает за нажатие на кнопку в шапке сайта. Функция onResizeARIA() реагирует на изменение размеров окна и убирает панель, когда ширина сайта уменьшается до 1007 пикселей и ниже. Далее я меняю иконку в кнопке с помощью CSS-правила @media и CSS-свойства content. Иконка меняется после того, как ширина страницы становится равной 1008 пикселям:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.menu-toggle:before { color: #ffffff; content: "\f419"; padding: 16px; } @media screen and (min-width: 1008px) { .primary-navigation .menu-toggle::before { content: "\f453"; } ... } |
В качестве иконки для кнопки используется юникодный символ, который указывает на соответствующую пиктограмму в наборе Genericons.
Мне никогда не нравилась стандартная форма отправки комментариев WordPress, которая была задействована на старой теме Moto Orange. Эта форма была плохо свёрстана, имела огромные поля ввода и выглядела следующим образом:
Стандартная форма отправки комментариев WordPress, старая тема Moto Orange, скриншот из браузера Chrome.
Я решил немного её переделать, в частности, слить все три линии ввода персональных данных в один блок, уменьшить его ширину и перенести выше поля ввода комментария. Для этого я отредактировал стандартный PHP-файл шаблона function.php, в котором располагаются основные функции темы, добавив туда специальный фильтр:
1 2 3 4 5 6 7 |
function move_comment_field( $fields ) { $comment_field = $fields['comment']; unset( $fields['comment'] ); $fields['comment'] = $comment_field; return $fields; } add_filter( 'comment_form_fields', 'move_comment_field' ); |
В главный CSS-стиль темы было добавлено следующее:
1 2 3 4 5 6 |
/* Comments */ .comment-form-author, .comment-form-email, .comment-form-url { display: inline-block; } |
После внесёния этих изменений, форма стала выглядеть более привычно и логично:
Новая форма отправки комментариев в теме Moto Juice, скриншот из браузера Chrome.
Кроме формы комментариев я подверг изменениям и стандартную форму поиска, которая была использована в теме Twenty Fourteen. По какой-то причине в ней отсутствовала кнопка. Я создал PHP-файл searchform.php и наполнил его следующим содержимым:
1 2 3 4 5 6 7 8 9 10 |
<form method="get" name="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <div class="search"> <input class="search-input" name="s" type="text" value="<?php echo esc_attr(get_search_query()); ?>" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" /> <span class="button-wrapper"> <input class="button-search" type="submit" value="<?php echo esc_attr(__('Find', 'moto-juice')); ?>" /> </span> </div> </form> |
Согласно официальной документации, если в теме присутствует файл searchform.php, то при вызове функции get_search_form() будет отображена форма поиска именно из этого файла. Это помогло мне вернуть потерянную кнопку.
8. Локализация темы WordPress
Стандартный шаблон Twenty Fourteen уже переведён на множество языков, но в своей теме Moto Juice я добавил некоторые дополнительные строки, которые тоже нуждались в переводе. Локализация тем для движка WordPress базируется на технологии GNU gettext, которая достаточно проста в использовании. Эту систему локализации используют множество проектов, например, GTK+ и GNOME. Её основной принцип таков: из исходного кода необходимо получить обобщённый POT-файл, являющийся шаблоном и содержащий все строки, которые необходимо локализовать в теме. Затем из POT-файла нужно сгенерировать PO-файлы для определённого языка, с которыми может работать переводчик, занимающийся локализацией программного обеспечения. После того как перевод закончен, PO-файлы нужно скомпилировать в компактные бинарные MO-файлы, с которыми и будет работать движок WordPress.
Тема Twenty Fourteen уже использовала домен перевода twentyfourteen, но я решил для своей темы добавить отдельный домен moto-juice и зарегистрировать его в functions.php следующим образом:
1 2 |
load_theme_textdomain( 'twentyfourteen', get_stylesheet_directory() . '/languages/default' ); load_theme_textdomain( 'moto-juice', get_stylesheet_directory() . '/languages' ); |
Для того, чтобы шаблон Moto Juice перестал зависеть от системных файлов WordPress, я переместил стандартные файлы локализации Twenty Fourteen в каталог languages/default/, а мои собственные на уровень выше, в директорию languages/.
Далее, все необходимые строки, которые мне нужно было перевести, я обернул в специальную функцию __(), с которой работает gettext:
1 2 3 4 |
<div class="design-sign"> <?php printf( __( 'Designed by ', 'moto-juice' ) ); ?> <a href="<?php echo esc_url( __( '//exlmoto.ru/', 'moto-juice' ) ); ?>"><?php printf( __( 'EXL', 'moto-juice' ) ); ?></a> </div><!--.design-sign--> |
Для нахождения таких строк в исходных файлах темы и генерации итогового POT-шаблона используется специальная утилита makepot.php, о том как её установить и как ей пользоваться можно прочитать в разделе официальной документации WordPress, который посвящен локализации тем. Суть сводится примерно к следующему:
1 2 3 |
svn co http://develop.svn.wordpress.org/trunk/tools/ ln -s . src php tools/i18n/makepot.php wp-theme src/wp-content/themes/MotoJuice/ |
В начале скачивается исходный код инструментов из репозитория WordPress, затем пробрасывается симлинк на директорию с исходным кодом WordPress и нужным шаблоном, а потом утилитой makepot.php генерируется POT-файл, который называется MotoJuice.pot в моём случае.
С файлом MotoJuice.pot уже может работать переводчик с помощью привычных ему прикладных инструментов для перевода. Разработчики WordPress советуют использовать кросс-платформенную программу Poedit, которая умеет создавать из POT-шаблонов как PO-файлы, так и скомпилированные MO-файлы.
Итак, открываем файл MotoJuice.pot с помощью программы Poedit, нажимаем кнопку «Create New Translation» и выбираем требуемый язык. После перевода необходимых строк сохраняем результат с помощью кнопки «Save», которая создаст как PO-файл, так и его скомпилированную MO-версию. Забрасываем эти два файла в каталог languages/ и всё, перевод шаблона на нужный язык, собственно, выполнен. Всё просто и элементарно, основная сложность заключается лишь в генерации изначального POT-шаблона.
Главное окно прикладной программы локализации Poedit, запущенной в дистрибутиве GNU/Linux.
Если будет необходимо просто поправить перевод, например, исправить опечатку, то генерировать снова POT-файл не требуется. Нужно лишь открыть PO-файл программой Poedit, сделать в нём нужные изменения, сохранить их, при этом автоматически обновится и скомпилированный MO-перевод. Повторная генерация POT-файла необходима тогда, когда в самом шаблоне были добавлены или удалены какие-либо строки для перевода. Поэтому очень важно начинать работать над переводом когда вся основная работа уже выполнена и строки в PHP-файлах гарантированно не будут изменяться. Так можно избежать повторяющейся работы, сэкономить время и сократить количество генераций POT-файлов.
Более подробно изучить вопросы локализации WordPress-тем можно на сайте WordPress Codex, в разделе I18n for WordPress Developers.
9. Заключение, полезные советы, ссылки и информация
Процесс разработки собственного шаблона для WordPress на основе стандартной темы познакомил меня с некоторыми современными изысками Web-технологий. Я немного вник в суть разработки Web-сайтов на движке WordPress и смог опробовать в деле такие языки программирования, как PHP и JavaScript. Я понял, что быть сегодня Web-разработчиком довольно трудно, так как это самая быстроразвивающаяся отрасль IT и нужно быть постоянно в тренде всех текущих событий. Дополнительно я разобрался с тем, как локализовывать и подготавливать для релиза свои темы.
При создании шаблона Moto Juice я вдохновлялся дизайном таких сайтов, как Orange Smoothie Productions (OSP) и Ogre3D. Их чистый, лаконичный и простой дизайн мне очень сильно понравился.
Помимо обновления дизайна блога, я исправил разметку во всех его постах и добавил огромное количество разнообразного старого материала. В основном, добавленный материал посвящён портам приложений на платформу MotoMAGX и смартфон Motorola ZN5. Это было замечательное время, благодаря которому я познакомился с GNU/Linux на мобильных устройствах. Количество страниц на ресурсе изменилось с 15 до 22. Кроме того, на сайт была добавлена новая страница с моими актуальными на сегодняшний день проектами для самых различных платформ.
Поскольку тема Twenty Fourteen была выпущена под лицензией GNU GPLv2, я обязан предоставить все изменения, которые я внёс в этот шаблон. С огромной радостью я публикую тему Moto Juice в своём репозитории на GitHub, под этой же лицензией:
https://github.com/EXL/MotoJuice
Любой желающий может воспользоваться моими наработками и установить эту тему на свою копию движка WordPress. Для этого достаточно склонировать репозиторий, сделать ZIP-пакет и установить его через админку: «Appearance» => «Themes» => «Add New» => «Upload Theme» => «Install Now». Создать готовый к установке ZIP-пакет с шаблоном Moto Juice можно следующими командами:
1 2 3 |
git clone https://github.com/EXL/MotoJuice cd MotoJuice/ git archive master --prefix='moto-juice/' --format=zip > MotoJuice.zip |
Будьте внимательны! Префикс темы, в моём случае moto-juice/, обязательно должен быть набран маленькими буквами, а вместо пробела должен использоваться знак минуса. В противном случае движок WordPress с темой будет работать некорректно, например, её будет невозможно удалить стандартными средствами.
Внешний вид темы Moto Juice в админке WordPress, скриншот снят из браузера Chrome (превью, увеличение по клику).
Скачать собранный ZIP-пакет шаблона Moto Juice версии 1.0 можно по этой ссылке:
Остальные и последние версии шаблона можно найти здесь.
Если вы используете на своём ресурсе для отслеживания статистики посещений сервис Google Analitycs, то обязательно впишите свой корректный идентификатор UA ID в файл analyticstracking.php, который находится в корневой директории темы.
Тема Moto Juice имеет адаптивную вёрстку и ей удобно пользоваться как на смартфонах и планшетах, так и на настольных компьютерах.
Коллаж из скриншотов Moto Juice: настольная, мобильная и две планшетных версии сайта (превью, увеличение по клику).
Для проверки вашего WordPress-шаблона на типовые ошибки, я рекомендую использовать плагин, который называется Theme Check. Лично мне этот плагин помог выявить ошибку, связанную с неправильным названием домена темы.
В этой работе я использовал огромное количество материалов, основные из них я выделю в полезных ссылках ниже. Огромное спасибо ресурсам stackoverflow.com и google.com за то, что они есть.
- WordPress Codex — сайт с документацией, где собрано огромное количество информации о движке WordPress;
- WordPress Developer Resources — портал и справочник для разработчиков WordPress;
- jQuery API — документация JavaScript-библиотеки jQuery;
- PHP Documentation — документация по языку программирования PHP;
- JavaScript Reference — справочник по языку программирования JavaScript;
- Twenty Fourteen WordPress Theme — обзор возможностей стандартной WordPress-темы Twenty Fourteen;
- Палитра HTML-цветов и их названий — весьма полезная таблица цветов, если нужно подобрать какой-либо оттенок.
Отдельную благодарность хочу выразить Zorge.R‘у за просто офигенный логотип в шапку ресурса и полезные советы, yakimka‘е за полезные советы и справедливую/объективную критику и sinbad‘у (Steve Streeting) за то, что мотивировал меня заняться собственной темой.
offtop:
У Зорге сейчас есть свой блог?
Был по адресу blog.z-lab.me, но вроде сейчас он отключён.
Нет, отключил. Но я заглядываю сюда.