
📋 Полная шпаргалка по WordPress
Открыли functions.php и забыли, как подключить сайдбар? Так бывает у каждого, кто верстает тему WordPress вручную. Под рукой нужна одна страница, а не десять вкладок developer.wordpress.org.
Здесь собраны опоры разработки на WordPress: 13 файлов шаблона и иерархия их выбора, базовый Цикл, подключающие теги и параметры bloginfo(), а дальше, хуки и фильтры, условные теги, подключение скриптов, шорткоды, WP_Query, экранирование данных, REST API и команды WP-CLI. Все примеры кода рабочие. Держите вкладку открытой во время разработки и сверяйтесь по ходу.
💡 Быстрый обзор:
- Сохраните страницу в закладки и держите открытой в отдельной вкладке во время вёрстки темы.
- Начните с раздела «Анатомия темы»: создайте файлы темы по списку, прежде чем писать код.
- Скопируйте базовый Цикл WordPress в
index.phpи обвяжите его подключающими тегами шапки, сайдбара и футера. - Подставляйте теги
bloginfo()иget_bloginfo()из таблицы прямо в шаблоны, сверяясь с колонкой «Что выводит». - Перед публикацией пройдитесь по правилам для
style.css: валидируйте CSS, минифицируйте и добавьте стили печати. - Дальше по странице, справочник: иерархия шаблонов, хуки и фильтры, условные теги, подключение скриптов, шорткоды,
WP_Query, экранирование, REST API и WP-CLI.
Анатомия темы WordPress

Тема WordPress, это набор PHP-файлов, объединённых общей логикой и подчинённых иерархии шаблонов. Ключевой компонент: style.css, он отвечает за визуальное оформление и одновременно служит идентификатором темы в админке. Но фундамент любой классической темы, именно PHP-шаблоны: каждый отвечает за свой участок страницы и вызывается в порядке, заданном иерархией WordPress.
Для создания стандартной темы нужны следующие файлы, тринадцать штук, и каждый закрывает конкретную зону сайта:
- header.php, секция
<head>и верхняя часть страницы: метаданные, заголовок сайта, подключениеstyle.css, открывающий тег<body>. - index.php, главный шаблон, точка входа. Через подключающие теги собирает остальные файлы в единую страницу. Если специализированного шаблона нет, WordPress падает в
index.php. - sidebar.php, боковая панель: виджеты, рубрики, поиск, дополнительное меню.
- footer.php, футер: копирайт, ссылки на соцсети, скрипты аналитики, закрывающие теги
</body></html>. - page.php, шаблон для страниц (статический контент, «О нас», «Контакты»).
- single.php, шаблон отдельной записи блога.
- comments.php, блок комментариев и форма их добавления.
- 404.php, страница ошибки 404. Если этого файла нет, WordPress показывает стандартное системное сообщение, что хуже для посетителя.
- search.php, шаблон выдачи результатов поиска.
- searchform.php, форма поиска (в классических темах; современные часто обходятся виджетом).
- archive.php, шаблон архивов: рубрики, метки, архивы по датам.
- functions.php, функциональное сердце темы: пользовательские хуки, подключение скриптов и стилей, регистрация меню, областей для виджетов, кастомные типы записей. Всё, что добавляет тему функциональность, живёт здесь.
- style.css, единственный НЕ-PHP файл в списке, но без него тема не существует: именно он хранит заголовок темы и определяет внешний вид сайта.
Можно обойтись и меньшим числом шаблонов, например, index.php + style.css уже образуют минимальную тему. Но для полноценного сайта лучше держать все тринадцать: каждый файл заточен под свою задачу, а WordPress сам выбирает нужный по иерархии. Типичный index.php выглядит так:
1 <?php get_header(); ?> 2 3 <!-- Основной контент, включая Цикл --> 4 5 <?php get_sidebar(); ?> 6 <?php get_footer(); ?>
Двигаемся дальше, к самому важному фрагменту кода, без которого не выводится ни одна запись.
Цикл WordPress
Цикл (The Loop), центральный механизм вывода контента. Без него вам пришлось бы вручную кодировать отображение каждого поста и каждой страницы в шаблоне темы. Цикл делает ровно то, что обещает название: проходит по всем записям, соответствующим текущему запросу, и для каждой применяет указанную вами HTML/PHP-разметку.
Базовый синтаксис Цикла:
1 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 2 <!-- HTML-разметка и теги шаблона для каждой записи --> 3 <?php endwhile; endif; ?>
have_posts() проверяет, есть ли записи для вывода. Если есть, the_post() инициализирует внутренний указатель WordPress на текущую запись, после чего внутри Цикла становятся доступны десятки тегов шаблона: the_title() для заголовка, the_content() для текста записи, the_permalink() для ссылки, the_excerpt() для цитаты и многие другие.
Цикл обычно размещают в index.php для вывода списка записей, но ничто не мешает использовать его в single.php, page.php или archive.php, логика та же, различается только контекст. Внутри Цикла добавляйте любые HTML-обёртки и PHP-теги, WordPress применит их к каждой записи по очереди.
Практический пример, вывод заголовка и даты каждой записи:
1 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 2 <article> 3 <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> 4 <time><?php echo get_the_date(); ?></time> 5 </article> 6 <?php endwhile; endif; ?>
Теперь о том, как Цикл взаимодействует с остальной темой, через подключающие теги.
Подключающие теги шаблона
Подключающие теги (Include Tags), это PHP-функции, которые загружают содержимое одного файла темы в другой. Они формируют скелет типичного index.php: заголовок, контент, сайдбар, футер. Четыре базовые функции:
<?php get_header(); ?>, подключаетheader.php. Обычно первая строка вindex.phpи любом другом шаблоне, где нужна шапка.<?php get_sidebar(); ?>, подключаетsidebar.php. Если боковая панель не нужна, просто уберите вызов.<?php get_footer(); ?>, подключаетfooter.php. Всегда в конце шаблона, закрывает страницу.<?php comments_template(); ?>, подключаетcomments.php. Размещается внутриsingle.php, после вывода контента записи.
Все четыре функции ищут файлы в папке активной темы. Если файла нет, WordPress просто ничего не выводит (кроме get_header() и get_footer(), их отсутствие сломает вёрстку).
Следующий уровень, теги, которые не просто подключают файлы, а извлекают данные из базы.
Теги bloginfo

Теги bloginfo() извлекают информацию о сайте из базы данных WordPress, ту самую, которую вы заполняете в Настройки → Общие и в профиле пользователя. Функция возвращает строку и сразу выводит её на экран. Наиболее востребованные параметры:
Параметр | Что выводит |
|---|---|
| Заголовок сайта |
| URL сайта |
| Слоган (описание) сайта |
| Кодировка (по умолчанию UTF-8) |
| URL файла |
| Версия установленного WordPress |
| Язык сайта |
| URL RSS-ленты (RSS 0.92) |
| URL RSS-ленты (RSS 2.0) |
Это лишь верхушка айсберга, полный список параметров есть в документации WordPress.
get_bloginfo(), когда нужно не вывести, а сохранить
Для случаев, когда информацию сайта нужно использовать в коде, а не просто показать на странице, применяется функция get_bloginfo():
1 <?php $info = get_bloginfo( $show, $filter ); ?>
$show, ключевое слово. Поддерживаются значения'name'(заголовок),'url'(адрес),'description'(слоган),'admin_email'(email админа) и другие; полный список в документации.$filter, режим фильтрации:'raw'(значение «как есть», по умолчанию) или'display'(значение пропускается черезwptexturize(), преобразует кавычки, тире, символы).
Пример: получаем описание сайта и выводим с префиксом:
1 <?php $site_description = get_bloginfo( 'description' ); ?> 2 <?php echo 'Слоган вашего сайта: ' . esc_html( $site_description ); ?>
Результат: «Слоган вашего сайта: Лучшие премиальные темы WordPress».
Помимо bloginfo, WordPress располагает обширной системой тегов шаблона: общие теги, теги авторов, миниатюр, рубрик, ссылок, все они работают внутри Цикла и вне его, а комбинации дают полный контроль над выводом контента.
Таблица стилей темы
style.css выполняет две роли. Первая, идентификационная: заголовок в самом верху файла сообщает WordPress название темы, автора, версию, лицензию. Вторая, визуальная: все CSS-правила, управляющие внешним видом сайта. Стандартный заголовок выглядит так:
1 /* 2 Theme Name: Название темы 3 Theme URI: https://www.example.com/theme 4 Author: Ваше Имя 5 Author URI: https://www.example.com/ 6 Description: Адаптивная тема WordPress с поддержкой... 7 Version: 1.0 8 License: GNU General Public License v2 or later 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 Tags: responsive, two-columns, right-sidebar, custom-header 11 Text Domain: mythemename 12 */
Правила хорошего тона при работе с style.css:
- Следуйте стандартам кодирования CSS WordPress, единый стиль упрощает поддержку.
- Проверяйте CSS на валидность через W3C-валидатор.
- Минифицируйте CSS в продакшене, но оставляйте читаемый исходник для разработки.
- Добавьте стили для печати (
@media print), многие читатели распечатывают статьи. - Стилизуйте все стандартные HTML-элементы, которые могут встретиться в контенте записи.
Иерархия шаблонов WordPress
Для каждого запроса WordPress сам решает, какой PHP-файл темы подключить, это и есть иерархия шаблонов. Правило одно: от самого частного файла к самому общему, а index.php, последний запасной вариант для любой ветки. Знание порядка снимает вопрос «почему правка в single.php не видна на странице рубрики».
1 Отдельная запись → single-{post_type}-{slug}.php → single-{post_type}.php → single.php → singular.php → index.php 2 Страница → {шаблон из редактора}.php → page-{slug}.php → page-{id}.php → page.php → singular.php → index.php 3 Рубрика → category-{slug}.php → category-{id}.php → category.php → archive.php → index.php 4 Архив → archive-{post_type}.php → archive.php → index.php 5 Поиск → search.php → index.php 6 Ошибка 404 → 404.php → index.php 7 Главная → front-page.php → home.php → index.php
WordPress берёт первый существующий файл слева направо. Поэтому single-product.php перекроет single.php только для записей типа product, не трогая остальные.
Хуки: действия и фильтры
Хуки, точки расширения WordPress: они позволяют вклиниться в работу ядра, не редактируя его файлы. Действия (actions) выполняют побочный эффект (подключить скрипт, отправить письмо), фильтры (filters) получают значение, меняют его и обязаны вернуть обратно. Забытый return в фильтре, самая частая причина пустого контента.
1 // Регистрация 2 add_action( 'имя_хука', 'callback', 10, 1 ); // приоритет, число аргументов 3 add_filter( 'имя_хука', 'callback', 10, 1 ); 4 5 // Вызов (в ядре или своём коде) 6 do_action( 'имя_хука', $arg ); // действие: ничего не возвращает 7 apply_filters( 'имя_хука', $value, $arg ); // фильтр: ВОЗВРАЩАЕТ значение 8 9 // Удаление (приоритет должен совпадать с тем, что был при добавлении) 10 remove_action( 'имя_хука', 'callback', 10 );
Пример, добавить абзац в конец каждой записи:
1 add_filter( 'the_content', 'my_append_note', 20 ); 2 function my_append_note( $content ) { 3 return $content . '<p>Спасибо за чтение!</p>'; // без return контент исчезнет 4 }
Ключевые хуки темы:
after_setup_theme, регистрация поддержки возможностей (add_theme_support()), меню, размеров миниатюр.wp_enqueue_scripts, единственно правильное место для подключения CSS и JS фронтенда.init, ранняя инициализация: регистрация типов записей и шорткодов.the_content, фильтрация HTML записи перед выводом.
Меньший приоритет, раньше выполнение (по умолчанию 10). Чтобы callback получил больше одного аргумента, увеличьте четвёртый параметр accepted_args.
Условные теги
Условные теги (Conditional Tags), функции, которые возвращают true или false в зависимости от того, какая страница сейчас открыта. На них строят логику «здесь показываем сайдбар, а на 404, нет».
1 is_home() // блоговая лента записей 2 is_front_page() // главная страница сайта 3 is_single() // отдельная запись 4 is_page() // отдельная страница 5 is_singular() // любая одиночная запись/страница/CPT 6 is_archive() // любой архив 7 is_category() // архив рубрики 8 is_search() // страница результатов поиска 9 is_404() // страница ошибки 404 10 is_user_logged_in() // пользователь авторизован 11 is_admin() // запрос идёт в админке (НЕ «пользователь администратор»)
Главная ловушка: запросные условные теги (is_single, is_page, is_home и другие) работают только после того, как сформирован основной запрос, то есть внутри файлов шаблона и Цикла или начиная с хука template_redirect. Вызов в начале functions.php или на init, слишком рано: WordPress выдаст _doing_it_wrong() и вернёт неверный результат. Исключения, is_admin() и is_user_logged_in(), они не зависят от запроса и доступны раньше. И помните: is_admin() проверяет контекст (админка против фронтенда), а не роль; для роли используйте current_user_can( 'manage_options' ).
Подключение скриптов и стилей
Соблазн прописать <link> и <script> прямо в header.php велик, но это ошибка: вы теряете управление зависимостями, версионирование для сброса кеша, стратегии defer/async и защиту от двойной загрузки (два плагина легко подключат jQuery дважды). Правильный путь, очередь WordPress на хуке wp_enqueue_scripts.
1 add_action( 'wp_enqueue_scripts', 'my_theme_assets' ); 2 function my_theme_assets() { 3 // Стиль темы с версией из заголовка style.css 4 wp_enqueue_style( 5 'my-theme', 6 get_stylesheet_uri(), 7 array(), 8 wp_get_theme()->get( 'Version' ) 9 ); 10 11 // Скрипт с зависимостью и современным синтаксисом (WP 6.3+) 12 wp_enqueue_script( 13 'my-app', 14 get_theme_file_uri( 'assets/js/app.js' ), 15 array( 'jquery' ), // зависимости 16 '1.0.0', // версия → сброс кеша 17 array( 18 'in_footer' => true, 19 'strategy' => 'defer', 20 ) 21 ); 22 }
Начиная с WordPress 6.3 последний параметр wp_enqueue_script(), это массив $args (in_footer, strategy), хотя старая форма с булевым true для подвала по-прежнему работает. Для фронтенда используйте wp_enqueue_scripts, для админки, admin_enqueue_scripts, для страницы входа, login_enqueue_scripts.
Шорткоды
Шорткоды превращают короткую запись в квадратных скобках в произвольный HTML, удобно для кнопок, галерей и форм внутри контента. Обработчик обязан вернуть строку, а не выводить её через echo, иначе результат «выпрыгнет» в начало страницы.
1 add_shortcode( 'btn', 'my_button_shortcode' ); 2 function my_button_shortcode( $atts, $content = null, $tag = '' ) { 3 $a = shortcode_atts( 4 array( 'url' => '#', 'label' => 'Кнопка' ), 5 $atts, 6 $tag 7 ); 8 return sprintf( 9 '<a class="btn" href="%s">%s</a>', 10 esc_url( $a['url'] ), // экранируем на выводе 11 esc_html( $a['label'] ) 12 ); 13 } 14 // Использование в записи: [btn url="https://example.com" label="Купить"]
shortcode_atts() накладывает атрибуты пользователя поверх значений по умолчанию. Если нужно выполнить шорткоды внутри строки или шаблона, оберните её в do_shortcode(), но для вызова собственной функции зовите её напрямую, без посредника.
WP_Query и кастомные запросы
WP_Query, класс для любых выборок записей: последние новости в сайдбаре, подборка по рубрике, лента кастомного типа. После своего цикла обязательно вызывайте wp_reset_postdata(), иначе теги шаблона дальше по странице получат не ту запись.
1 $q = new WP_Query( array( 2 'post_type' => 'post', 3 'posts_per_page' => 5, 4 'category_name' => 'news', 5 'orderby' => 'date', 6 'order' => 'DESC', 7 ) ); 8 9 if ( $q->have_posts() ) { 10 while ( $q->have_posts() ) { 11 $q->the_post(); 12 the_title( '<h3>', '</h3>' ); 13 } 14 wp_reset_postdata(); // вернуть глобальный $post 15 }
Чтобы изменить основной запрос страницы (например, число записей на главной), не используйте устаревший query_posts(), он гоняет лишний запрос к базе и ломает пагинацию. Правильно, хук pre_get_posts, который меняет запрос до его выполнения:
1 add_action( 'pre_get_posts', 'my_main_query' ); 2 function my_main_query( $query ) { 3 if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) { 4 $query->set( 'posts_per_page', 12 ); 5 } 6 }
Безопасность: экранирование и санитизация
Золотое правило WordPress: санитизируем на входе, экранируем на выводе, проверяем везде. Любые данные от пользователя очищаем перед сохранением в базу и экранируем перед выводом в HTML, даже если они уже были очищены.
1 // Экранирование НА ВЫВОДЕ 2 echo esc_html( $text ); // текст внутри тега 3 echo esc_attr( $value ); // значение атрибута 4 echo esc_url( $href ); // ссылки href/src 5 echo wp_kses_post( $rich_html ); // безопасный набор HTML для контента 6 7 // Санитизация НА ВХОДЕ (перед записью в БД) 8 $clean = sanitize_text_field( $_POST['name'] ); 9 $email = sanitize_email( $_POST['email'] ); 10 $num = absint( $_POST['count'] );
Формы и действия защищаем nonce, одноразовым токеном против CSRF:
1 // В форме: 2 wp_nonce_field( 'my_save_action', 'my_nonce' ); 3 4 // При обработке: 5 if ( ! isset( $_POST['my_nonce'] ) || 6 ! wp_verify_nonce( $_POST['my_nonce'], 'my_save_action' ) ) { 7 return; // запрос отклонён 8 }
На практике большинство уязвимостей тем и плагинов, это именно пропущенное экранирование вывода. Возьмите за привычку: ни одна переменная не попадает в HTML без esc_*.
REST API WordPress
REST API отдаёт данные сайта в формате JSON, его используют мобильные приложения, headless-фронтенды и интеграции. Базовый адрес, /wp-json/wp/v2/.
1 GET /wp-json/wp/v2/posts // записи 2 GET /wp-json/wp/v2/pages // страницы 3 GET /wp-json/wp/v2/media // медиафайлы 4 GET /wp-json/wp/v2/users // пользователи 5 GET /wp-json/wp/v2/posts/123 // одна запись 6 GET /wp-json/wp/v2/posts?per_page=5&search=тема&_embed
Свой маршрут регистрируют на хуке rest_api_init. Параметр permission_callback обязателен, без него WordPress выдаст предупреждение; для публичного чтения ставьте '__return_true'.
1 add_action( 'rest_api_init', function () { 2 register_rest_route( 'myplugin/v1', '/items/(?P<id>\d+)', array( 3 'methods' => 'GET', 4 'callback' => 'my_get_item', 5 'permission_callback' => '__return_true', 6 ) ); 7 } );
WP-CLI: команды под рукой
WP-CLI управляет сайтом из терминала, быстрее и надёжнее, чем кликать в админке, особенно при обслуживании нескольких сайтов. Самое ходовое:
1 wp core update # обновить ядро WordPress 2 wp core version # какая версия установлена 3 wp plugin install akismet --activate # установить и сразу включить плагин 4 wp plugin list # список плагинов со статусом и версией 5 wp theme activate twentytwentyfive # сменить активную тему 6 wp db export backup.sql # дамп базы в файл 7 wp search-replace 'old.com' 'new.com' --dry-run # сначала всегда сухой прогон 8 wp user create bob [email protected] --role=editor # создать пользователя 9 wp cache flush # сбросить объектный кеш
wp search-replace понимает сериализованные данные, поэтому безопасно меняет домен при переезде сайта, в отличие от прямого SQL-запроса, который ломает сериализацию. Перед любой опасной операцией делайте wp db export.
Классические и блочные темы в 2026 году
К середине 2026 года (актуальная версия, WordPress 7.0 «Armstrong», рекомендуемый PHP 8.3+) классические PHP-темы по-прежнему полностью поддерживаются и остаются самым массовым типом. Но всё новое ядровое тулинг развивает блочные темы и полное редактирование сайта (Full Site Editing): theme.json вместо части настроек functions.php, HTML-шаблоны вместо PHP. Цикл, bloginfo(), условные теги и хуки актуальны и в гибридных темах, и в любых PHP-фрагментах внутри FSE-темы, так что эта шпаргалка не теряет ценности. Практичный путь в 2026-м, классическая основа плюс точечная поддержка блоков там, где она действительно нужна.
⁉️🤔 Частые вопросы
Обязательно ли создавать все 13 файлов для темы?
Нет, минимальная рабочая тема,
index.php+style.css. Но для полноценного сайта лучше держать полный набор: каждый файл даёт WordPress возможность выбрать оптимальный шаблон. Например, безsingle.phpзапись отрендерится черезindex.php, и потеряет блок комментариев.
Чем get_bloginfo() отличается от bloginfo()?
bloginfo() сразу выводит значение на экран (echo). get_bloginfo() возвращает строку в переменную, её можно обработать, дополнить или использовать внутри другого выражения до фактического вывода.
Где размещать Цикл, если на странице несколько типов контента?
Цикл можно запускать многократно. Типичный сценарий: один Цикл для основного списка записей, второй, для виджета «последние новости» в сайдбаре. Перед вторым Циклом сбрасывайте указатель через wp_reset_postdata(), иначе следующий код на странице получит неверный контекст записи.
Работает ли эта шпаргалка для блочных тем (FSE)?
Частично. Блочные темы (Full Site Editing) используют
theme.jsonвместоfunctions.phpдля многих настроек и шаблоны в HTML, а не PHP. Но Цикл,bloginfo()и подключающие теги остаются актуальными для гибридных тем и любых PHP-шаблонов внутри FSE-темы.
Что делать, если functions.php становится слишком большим?
Разбейте логику на отдельные файлы и подключайте их из
functions.phpчерезrequire_onceилиinclude. Например:require_once get_template_directory() . '/inc/custom-post-types.php';. Это улучшает читаемость и упрощает сопровождение, правило хорошего тона для любой темы с более чем 20-30 хуками.
Чем действие (action) отличается от фильтра (filter)?
Действие выполняет побочный эффект и ничего не возвращает (подключить скрипт, отправить письмо). Фильтр получает значение, меняет его и обязан вернуть, забытый
returnв фильтре обнулит контент. Регистрируются они одинаково:add_action()иadd_filter().
Почему is_single() не работает в functions.php?
Запросные условные теги доступны только после формирования основного запроса, то есть в файлах шаблона или начиная с хука
template_redirect. В началеfunctions.phpзапрос ещё не готов, поэтому WordPress выдаст_doing_it_wrong(). Без привязки к запросу работают толькоis_admin()иis_user_logged_in().
Что держать под рукой при разработке на WordPress
Эта шпаргалка, каркас, с которого начинается разработка на WordPress. Файлы темы и иерархия шаблонов, Цикл, подключающие теги и bloginfo() собирают тему, а хуки и фильтры, условные теги, подключение скриптов, шорткоды, WP_Query, экранирование, REST API и WP-CLI закрывают подавляющее большинство рутинных задач. Остальное, практика и документация.
Для углублённого изучения руководство по разработке тем на developer.wordpress.org, первый адрес. Там же лежит справочник по тегам шаблона с сотнями функций на все случаи жизни. Если вы проходите путь от HTML-вёрстки до готовой темы, начните с пошагового руководства по созданию темы WordPress из HTML, где Цикл и теги разобраны в боевом контексте, от вёрстки до рабочей темы.
Берите эту шпаргалку в закладки и держите под рукой во время разработки.
Какой тег или хук вы ищете чаще всего? Напишите в комментариях, с какой задачей по WordPress вы столкнулись, и поделитесь своим кейсом, живой обмен опытом стоит десятка официальных руководств.



