В этой статье мы создадим простой минимальный шаблон для WordPress. Для начала я хочу заметить, что есть два варианта написания шаблонов для WordPress. Если вы хотите внести изменения в уже существующий шаблон, дополнить его или изменить функциональность, то самым простым вариантом будет создание дочернего шаблона. Такой шаблон может состоять всего из одного файла css, объявляющего стили новой темы, а все остальные файлы будут взяты из родительской темы. Это самый лучший вариант для создания новых шаблонов для новичков, а так же в том случае, если тема является модификацией существующей, потому что таким образом можно избежать ошибок и создать действительно корректно работающий шаблон. Темы WordPress должны отвечать всем требованиям, заявленным в кодексе, и одно из этих требований звучит так: весь код в тему должен добавляться осмысленно.
Создание дочерней темы
Для этого в директории с темами создайте папку с названием новой темы, а внутри нее файл style.css. Для того, чтобы тема заработала, необходимо оформить комментарий в начале этого файла. Вот пример заголовка для темы, которая будет дочерней для стандартной темы Twenty Fourteen:
/*
Theme Name: Twenty Fourteen Child
Theme URI: http://example.com/twenty-fourteen-child/
Description: Twenty Fourteen Child Theme
Author: John Doe
Author URI: http://example.com
Template: twentyfourteen
Version: 1.0.0
Tags: light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
Text Domain: twenty-fourteen-child
*/
Измените данные из этого примера на свои и далее можно писать css код своей темы. Для того, чтобы дочерняя тема работала, необходимо поставлять родительскую тему вместе с ней.
Дочерние темы могут объявлять свои шаблоны и свои функции, а так же перезаписывать уже существующие. Кроме того родительская тема может объявлять свои уникальные хуки, которыми дочерние темы могут пользоваться.
Создание темы с нуля
Мы создадим тему, состоящую всего из двух файлов:
- style.css
- index.php
Файл стилей
В этом файле необходимо корректно заполнить заголовок, именно из этого файла WordPress узнает всю информацию о новой теме:
- Theme Name — название новой темы. Для размещения на wordpress.org оно должно быть уникальным среди всех тем этого сайта, написано на английском и не содержать слов 'theme', 'WordPress' или рекламы.
- Theme URI — адрес сайта темы. Должна указывать на страницу или сайт, посвященный данной теме.
- Description — описание темы.
- Author — имя разработчика.
- Author URI — сайт разработчика.
- Version — версия.
- Tags — ключевые слова, используемые в фильтре поиска сайта wordpress.org.
- Text Domain — используется для перевода, имя темы с заменой пробелов на '-'.
- License: GNU General Public License v2 or later. — все темы WordPress как и она сама лицензированы GPL лицензией.
- License URI: — лицензия указывается ссылкой или файлом.
В итоге получим следующий комментарий:
/*
Theme Name: Simplest Site
Author: Layka
Author URI: http://ilovewordpress.ru/
Description: The 2014 simplest theme for WordPress.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black
Text Domain: simplest-site
This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/
Комментарий всегда размещается в начале файла style.css.
Файл index.php
Единственным файлом нашей самой простой темы будет index.php. Когда WordPress хочет отобразить ту или иную страницу сайта, она ведет поиск подходящего шаблона, начиная с самого специфического для данного вида контента. Скажем, в данный момент пользователь зашел на страницу сайта, тогда WordPress проверит, есть ли шаблон с названием page-ID.php, где ID — уникальный идентификатор страницу, не найдя этот файл, она проверит наличие файла <page.php>, если и его нет, то она обратится к файлу Index.php, лежащему в корне всей иерархии шаблонов WordPress. Названий шаблонов достаточно много, я не стану их перечислять, если интересно, вы можете посмотреть полный список в кодексе. Весь код нашей темы будет содержаться в одном единственном файле и этот файл будет отображать страницы, записи, результаты поиска и все архивы. Этот шаблон сделан с целью обучения, чтобы показать как выглядит самая простая тема WordPress, состоящая из двух файлов.
Итак, файл начинается с комментария в стиле стандартных тем:
<?php
/**
* Файл Index.php
*
*
* Отображает страницы сайта, работающего на WordPress
*
* @package WordPress
* @subpackage Simplest_Site
* @since Simplest Site 1.0
*/
?>
Здесь мы указываем назначение шаблона и версию.
Далее идет информация, которая обычно размещается в шапке сайта, доктайп и мета теги:
<!DOCTYPE html>
<!--[if IE 7]>
<html class="ie ie7" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 8]>
<html class="ie ie8" <?php language_attributes(); ?>>
<![endif]-->
<!--[if !(IE 7) | !(IE 8) ]><!-->
<html <?php language_attributes(); ?>>
<!--<![endif]-->
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<link rel="profile" href="http://gmpg.org/xfn/11">
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<link rel='stylesheet' id='main-style' href='<?php echo get_stylesheet_uri(); ?>' type='text/css' media='all' />
<?php wp_head(); ?>
</head>
Пути к js и css файлам мы не прописываем вручную, вместо этого необходимо пользоваться функциями WordPress, ведь эти url изменяются на разных сайтах. Перед тегом идет объявление обязательного хука wp_head, если этого не сделать, то большинство плагинов не сможет работать с этим шаблоном.
Цепляем к body классы:
<body <?php body_class(); ?>>
Следующая секция кода выведет шапку. Здесь мы покажем название сайта, которое пользователь вводит в персонализаторе темы WordPress, форму поиска и основное меню:
<div id="page" class="hfeed site">
<!-- Шапка -->
<header id="masthead" class="site-header" role="banner">
<!-- Название сайта -->
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<div id="search-container">
<div class="search-box">
<?php get_search_form(); ?>
</div>
</div>
<!-- Меню -->
<nav id="primary-navigation" class="site-navigation" role="navigation">
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>
</nav>
</header><!-- #masthead -->
Далее необходимо показать контент сайта. Это происходит в цикле WordPress, она отдает нам всю информацию, относящуюся к запрошенному пользователем url адресу. Начало цикла:
<?php while ( have_posts() ) : the_post(); ?>
Внутри этого цикла мы имеем полный доступ к информации, относящейся к текущей записи, для обращения к ней пользуемся стандартными функциями WordPress.
Эта строка выведет классы, относящиеся к текущей записи и ее ID:
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
А в следующей выполняются проверки: является ли текущая страница избранной и в тоже время находимся ли мы на странице списка всех записей и не разделен ли она на много страниц:
<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
Дело в том, что в WordPress есть возможность прилепить запись в начале при отображении списка всех страниц и эту возможность каждая тема должна поддерживать, избранную запись нужно выделить как-то, поэтому эти строки нам необходимы в шаблонов WordPress. Далее мы выделяем ее:
<div class="featured-post">
<?php _e( 'Избранная запись'); ?>
</div>
Этот вариант темы не поддерживает перевод, а все слова я пишу просто по-русски. Так делать не стоит. Функция _e() предназначена для перевода фраз на другой язык, вторым параметром ей задается идентификатор, который предварительно связывается с файлом перевода, обычно это происходит в файле functions.php, которого у нас просто нет.
Вернемся к нашему шаблону, дальше мы выводим заголовок записи, если это единичная страница или запись, просто покажем его, иначе сделаем из него ссылку на страницу, а затем выведем список всех категорий и меток, которые связаны с данной записью:
<header class="entry-header">
<!-- Если это запись -->
<?php if ( is_single() || is_sticky() ) : ?>
<h1 class="entry-title"><?php the_title(); ?></h1>
<?php else : ?>
<h1 class="entry-title">
<a href="<?php the_permalink(); ?>" rel="bookmark"><?php echo get_the_title(); ?></a>
</h1>
<?php endif; ?>
<?php echo get_the_category_list(); ?>
<?php echo get_the_tag_list('', ', ');?>
</header><!-- .entry-header -->
Теперь настала пора показать контент. Для результатов поиска будем выводить только краткое описание. А если страница разделена на несколько, то покажем и навигацию по страничкам:
<?php if ( is_search() ) : // Показывать только краткое описание записи, если это результаты поиска?>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php else : ?>
<div class="entry-content">
<?php the_content( __( 'Читатать дальше.. <span class="meta-nav">→</span>') ); ?>
<?php wp_link_pages( array( 'before' => '<div class="page-links">' . __( 'Страницы:'), 'after' => '</div>' ) ); ?>
</div><!-- .entry-content -->
<?php endif; ?>
В конце страницы выведем дату публикации и имя автора, а также ссылку на редактирование записи, которая будет отображаться для зарегистрированного пользователя с правами на изменение записи:
<footer class="entry-meta">
<?php printf(
__( 'Эта запись была опубликована %1$s автором %2$s.' ),
esc_html( get_the_date() ),
esc_html( get_the_author() )
);
?>
<?php edit_post_link( __( 'Редактировать', '' ), '<span class="edit-link">', '</span>' ); ?>
</footer><!-- .entry-meta -->
Конец цикла:
</article><!-- #post -->
<?php endwhile; ?>
<!-- Конец цикла WordPress -->
Покажем постраничную навигацию:
<?php if ( $wp_query->max_num_pages > 1 ) : ?>
<nav id="nav-below">
<div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">←</span> Предыдущая запись' ) ); ?></div>
<div class="nav-next"><?php previous_posts_link( __( 'Следующая запись <span class="meta-nav">→</span>' ) ); ?></div>
</nav><!-- #nav-below .navigation -->
<?php endif; ?>
Далее идет кусочек кода, отображающий информацию в том случае, если страниц в блоге нет или результаты поиска ничего не дали:
<!-- Записей для отображения нет, тогда выводим сообщение об этом -->
<?php else : ?>
<article class="not-found">
<?php if ( current_user_can( 'edit_posts' ) ) : ?>
<header class="entry-header">
<h1 class="entry-title"><?php _e( 'Нет записей для отображения.', '' ); ?></h1>
</header>
<div class="entry-content">
<p><?php printf( __( 'Готовы опубликовать свою первую запись? <a href="%s">Get started here</a>.'), admin_url( 'post-new.php' ) ); ?></p>
</div><!-- .entry-content -->
<?php else : ?>
<header class="entry-header">
<h1 class="entry-title"><?php _e( 'Ничего не найдено'); ?></h1>
</header>
<div class="entry-content">
<p><?php _e( 'Ничего не найдено, воспользуйтесь поиском.'); ?></p>
<?php get_search_form(); ?>
</div><!-- .entry-content -->
<?php endif; ?>
</article><!--.not-found -->
<?php endif; // конец have_posts() проверки ?>
Ну и подвал, где мы покажем традиционную ссылку на официальный сайт WordPress:
</div><!-- .site-content -->
<div class="clear"></div>
<!-- Подвал сайта -->
<footer id="colophon" class="site-footer">
<div class="site-info">
<a href="<?php echo esc_url( __( 'http://wordpress.org/' ) ); ?>"><?php printf( __( 'Сайт работает на %s' ), 'WordPress' ); ?></a>
</div><!-- .site-info -->
</footer><!-- #colophon -->
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>
Здесь, в самом конце сайта, объявлен хук wp_footer, это объявление крайне необходимо и используется плагинами, например, для подгрузки скриптов.
Весь файл полностью:
<?php
/**
* Файл Index.php
*
*
* Отображает страницы сайта, работающего на WordPress
*
* @package WordPress
* @subpackage Simplest_Site
* @since Simplest Site 1.0
*/
?>
<!DOCTYPE html>
<!--[if IE 7]>
<html class="ie ie7" <?php language_attributes(); ?>>
<![endif]-->
<!--[if IE 8]>
<html class="ie ie8" <?php language_attributes(); ?>>
<![endif]-->
<!--[if !(IE 7) | !(IE 8) ]><!-->
<html <?php language_attributes(); ?>>
<!--<![endif]-->
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<link rel="profile" href="http://gmpg.org/xfn/11">
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<link rel='stylesheet' id='main-style' href='<?php echo get_stylesheet_uri(); ?>' type='text/css' media='all' />
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<div id="page" class="hfeed site">
<!-- Шапка -->
<header id="masthead" class="site-header" role="banner">
<!-- Название сайта -->
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<div id="search-container">
<div class="search-box">
<?php get_search_form(); ?>
</div>
</div>
<!-- Меню -->
<nav id="primary-navigation" class="site-navigation" role="navigation">
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>
</nav>
</header><!-- #masthead -->
<div class="site-content">
<!-- Начало цикла WordPress -->
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
<div class="featured-post">
<?php _e( 'Избранная запись' ); ?>
</div>
<?php endif; ?>
<header class="entry-header">
<!-- Если это запись -->
<?php if ( is_single() || is_sticky() ) : ?>
<h1 class="entry-title"><?php the_title(); ?></h1>
<?php else : ?>
<h1 class="entry-title">
<a href="<?php the_permalink(); ?>" rel="bookmark"><?php echo get_the_title(); ?></a>
</h1>
<?php endif; ?>
<?php echo get_the_category_list(); ?>
<?php echo get_the_tag_list('', ', ');?>
</header><!-- .entry-header -->
<?php if ( is_search() ) : // Покаывать только краткое описание записи, если это результаты поиска?>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php else : ?>
<div class="entry-content">
<?php the_content( __( 'Читатать дальше.. <span class="meta-nav">→</span>') ); ?>
<?php wp_link_pages( array( 'before' => '<div class="page-links">' . __( 'Страницы:'), 'after' => '</div>' ) ); ?>
</div><!-- .entry-content -->
<?php endif; ?>
<footer class="entry-meta">
<?php printf(
__( 'Эта запись была опубликована %1$s автором %2$s.' ),
esc_html( get_the_date() ),
esc_html( get_the_author() )
);
?>
<?php edit_post_link( __( 'Редактировать', '' ), '<span class="edit-link">', '</span>' ); ?>
</footer><!-- .entry-meta -->
</article><!-- #post -->
<?php endwhile; ?>
<!-- Конец цикла WordPress -->
<?php if ( $wp_query->max_num_pages > 1 ) : ?>
<nav id="nav-below">
<div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">←</span> Предыдущая запись') ); ?></div>
<div class="nav-next"><?php previous_posts_link( __( 'следующая запись <span class="meta-nav">→</span>') ); ?></div>
</nav><!-- #nav-below .navigation -->
<?php endif; ?>
<!-- Записей для отображения нет, тогда выводим сообщение об этом -->
<?php else : ?>
<article class="not-found">
<?php if ( current_user_can( 'edit_posts' ) ) : ?>
<header class="entry-header">
<h1 class="entry-title"><?php _e( 'Нет записей для отображения.', '' ); ?></h1>
</header>
<div class="entry-content">
<p><?php printf( __( 'Готовы опубликовать свою первую запись? <a href="%s">Тогда перейдите по этой ссылке.</a>.'), admin_url( 'post-new.php' ) ); ?></p>
</div><!-- .entry-content -->
<?php else : ?>
<header class="entry-header">
<h1 class="entry-title"><?php _e( 'Ничего не найдено'); ?></h1>
</header>
<div class="entry-content">
<p><?php _e( 'Ничего не найдено, воспользуйтесь поиском.'); ?></p>
<?php get_search_form(); ?>
</div><!-- .entry-content -->
<?php endif; ?>
</article><!--.not-found -->
<?php endif; // конец have_posts() проверки ?>
</div><!-- .site-content -->
<div class="clear"></div>
<!-- Подвал сайта -->
<footer id="colophon" class="site-footer">
<div class="site-info">
<a href="<?php echo esc_url( __( 'http://wordpress.org/' ) ); ?>"><?php printf( __( 'Сайт работает на %s' ), 'WordPress' ); ?></a>
</div><!-- .site-info -->
</footer><!-- #colophon -->
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>
Окончательный вид шаблона
Я дополнила файл style.css несколькими строчками, чтобы придать шаблону внешний вид, похожий на сайт. Вот что из этого вышло:
Исходный css:
/*
Theme Name: Simplest Site
Author: Layka
Author URI: http://ILoveWordPress.ru/
Description: The 2014 simplest theme for WordPress.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black
Text Domain: simplest-site
This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/
body {
background-color: #000;
min-width: 600px;
}
a {
color: #199999;
}
a:hover {
color: red;
}
.site {
background-color: #eee;
border: 3px double #fff;
margin: 20px auto;
width: 90%;
}
.site-title {
border-bottom: 1px solid #555;
padding-bottom: 10px;
text-align: center;
}
.search-box {
border-bottom: 1px solid #555;
padding-bottom: 20px;
}
#masthead {
background-color: #111;
border-right: 1px solid #000;
color: #ddd;
display: inline-block;
float: left;
margin: 0 auto;
width: 300px;
}
#masthead a {
color: #fff;
}
#masthead a:hover {
color: #bbb;
}
#colophon {
background-color: #000;
display: block;
padding: 20px;
text-align: center;
}
.site-content {
border: none;
margin-left: 300px;
padding: 20px;
}
.clear {
clear: both;
}
.nav-previous {
float: left;
padding: 10px 0;
width: 50%;
}
.nav-next {
float: right;
padding: 10px 0;
text-align: right;
width: 50%;
}
Примечание: файл css не является законченным, а используется только как пример.
Чего в этом шаблоне нет
- Произвольного заголовка.
- Произвольного фона.
- Миниатюры записи.
- Поддержки перевода на другие языки.
- Стилей для редактора TinyMCE.
- Сайдбаров для виджетов.
- Самих виджетов.
- Иерархических меню.
- Дополнительных опций для персонализатора тем WordPress.
- Произвольных таксономий.
- Шрифтов Google.
- Различных форматов для записей.
- Дополнительных шаблонов для страниц.
- RSS.
- Комментариев.
- Хуков WordPress.
Это некоторые из возможностей, которые может включать тема WordPress, которые сразу приходят на ум. Наш шаблон очень простой и много не использует, но с чего-то надо начинать, а этот шаблон пишется с нуля и предназначен скорее для изучения WordPress, чем для использования в исходном варианте. Взяв эту тему за основу мы увидим, что да, шаблон WordPress действительно может состоять всего из двух файлов, далее, осознав для чего нам нужно добавить те или иные возможности, изменяем шаблон в соответствии со своими потребностями или желаниями. Для того, чтобы понять что и как происходит внутри WordPress необходимо ознакомиться с концепцией хуков. Эти хуки объявляются в исходных кодах WordPress и активно используются темами и плагинами, поиск нужных функций, действий и фильтров ведется в основном в исходниках WordPress, сама она является системой с открытым кодом и разрабатывается добровольцами. Любой желающий может присоединиться к команде по разработке WordPress сделав, например, новый шаблон и разместив его на сайте wordpress.org.
Примечание
Если у вас есть замечания или дополнения по этому материалу, то я буду рада услышать их в комментариях к этой статье.
При создании шаблона был использован исходный код стандартных тем WordPress.
Автор: layka