WordPress
Разбираем структуру, изучаем создание виджетов и шаблонов.
Разбираем структуру, изучаем создание виджетов и шаблонов.
Загрузка WordPress
Загрузка CMS WordPress на хостинг описана уже на многих сайтах и повторять её не имеет смысла. Сошлюсь на пару сайтов, где можно получить качественную инструкцию: //wordpress-start.ru или этот //pro-wordpress.ru
wp-config-sample.php
,
который находится в корне системы, вставить данные своей БД в следующем блоке кода:
// ** Параметры MySQL: Эту информацию можно получить у вашего хостинг-провайдера ** //
/** Имя базы данных для WordPress */
define('DB_NAME', 'имя вашей БД');
/** Имя пользователя MySQL */
define('DB_USER', 'логин');
/** Пароль к базе данных MySQL */
define('DB_PASSWORD', 'пароль');
/** Имя сервера MySQL */
define('DB_HOST', 'localhost');
/** Кодировка базы данных для создания таблиц. */
define('DB_CHARSET', 'utf8');
/** Схема сопоставления. Не меняйте, если не уверены. */
define('DB_COLLATE', '');
wp-config-sample.php
на wp-config.php.
Выбираем Тему для сайта
Одно из главных понятий в CMS WordPress — "Тема". Тема для сайта – это набор файлов, отвечающий за внешний вид и функционал вашего сайта. Этот набор помещается в папку с названием темы, которая сама размещается в папке [My-site-url]/wp-content/themes/
.
В загруженной вами только-что системе уже находится три стандартных темы. Это, как правило twentyfifteen
, twentysixteen
, twentyseventeen
.
Чтобы выбрать тему нужно войти в административную панель WP. Форма входа в админку находится по адресу [[My-site-url]]/wp-login.php
или [[My-site-url]]/wp-admin/
.
Используйте логин и пароль, которые вы определили при установке системы: вы войдёте в админ-панель с правами администратора.
Для начала можно выбрать и активировать одну из предложенных тем, вторую, третью, чтобы понять, как это работает и как выглядит ваш файл с разными темами.
Как это работает
В корне любой темы находится минимальный обязательный набор файлов с именами, зарезервированными системой. Эти файлы система распознает и использует для вывода того или иного вида контента. Обязательные файлы:
style.css — файл стилей темы. Этот файл должен быть у любой темы, так как именно он отвечает за ее объявление. В этом файле прописаны все CSS стили темы.
index.php — отображает главную страницу WordPress темы, если не указана другая (но об этом – ниже).
single.php — выводит отдельный пост вашей темы.
page.php — выводит статичные страницы (базовый шаблон).
header.php — выводит все важные метатеги для продвижения, подключает все скрипты и стили, необходимые для работы CMS Wordpress, которые должны выводиться между тегами <head></head>
. Отображает шапку сайта.
footer.php — подключает все скрипты и стили, необходимые для работы CMS Wordpress, которые должны выводиться в конце кода - перед тегами </body></html>
/ Отображает подвала сайта.
sidebar.php — отображает сайдбар (боковую колонк) страницы сайта.
functions.php — файл, содержащий дополнительные php-функции темы, используемые при написании кодов файлов темы.
comments.php — отвечает за отображение комментариев.
404.php — отображение страницы с 404 ошибкой.
search.php — отображение страницы поиска.
Делаем общую CSS для всех тем
Так как мы делаем свой, уникальный сайт, то будем делать и свой стиль. Чтобы не настраивать его каждый раз при тестировании новой темы (шаблона)
мы сделаем в корне папку /kids/css
, куда и будем загружать некоторые элементы стилей, которые мы бы хтели иметь независимо от шаблона,
например, цвет заголовков и т.п.
После этого, нам нужно для каждого шаблона, с которым мы экспериментируем, в файле header.php
добавить
перед тегом </head>
строчку:
<link rel="stylesheet" href="//radiokidsfm/kids/css/site.css" type="text/css" media="screen, projection" />
Начинаем с разбора файловой структуры WordPress
После распаковки архива WordPress имеем следующий набор папок и файлов
Все элементы, кроме выделенных красными прямоугольниками, составляют ЯДРО WP.
Первым загружается файл index.php
. Вот его код:
<?php
define('WP_USE_THEMES', true);
/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
Здесь определена переменная системы WP_USE_THEMES
.
Таблицу переменных системы составляем здесь. Затем загружается файл wp-blog-header.php
.Вот его код:
<?php
if ( !isset($wp_did_header) ) {
$wp_did_header = true;
// Load the WordPress library.
require_once( dirname(__FILE__) . '/wp-load.php' );
// Set up the WordPress query.
wp();
// Load the theme template.
require_once( ABSPATH . WPINC . '/template-loader.php' );
}
Если файл wp-blog-header.php
ещё не загружался (переменная-флажок $wp_did_header
равна false), то
загружаем библиотеку wp-load.php
. Затем выполняем функцию wp
- запуск WordPress. И. наконец, звгружаем шаблон wp-includes/template-loader.php
.
Ниже приведена схема подключения (загрузки) файлов и выполнения функций внутри файла wp-blog-header.php
.
wp-blog-header.php
├── wp-load.php
│ ├── wp-config.php
│ ├── define DB params
│ └── wp-settings.php
│ ├── wp-includes/load.php
│ ├── wp-includes/default-constants.php
│ ├── wp-includes/version.php
│ ├── ... выполнение ряда wp-функций
│ ├── wp-includes/compat.php
│ ├── wp-includes/functions.php
│ ├── wp-includes/class-wp.php
│ ├── wp-includes/class-wp-error.php
│ ├── wp-includes/plugin.php
│ ├── wp-includes/pomo/mo.php
│ ├── ... выполнение ряда wp-функций
│ ├── wp-includes/default-filters.php
│ ├── wp-includes/ms-blogs.php
│ ├── wp-includes/ms-settings.php
│ ├── wp-includes/l10n.php
│ // Load most of WordPress.
│ ├── wp-includes/class-wp-walker.php
│ ├── wp-includes/class-wp-ajax-response.php
│ ├── wp-includes/formatting.php
│ ├── . . . . . .
│ ├── wp-includes/rest-api/class-wp-rest-server.php
│ ├── wp-includes/rest-api/class-wp-rest-response.php
│ ├── wp-includes/rest-api/class-wp-rest-request.php
│ // Load multisite-specific files.
│ ├── wp-includes/ms-functions.php
│ ├── wp-includes/ms-default-filters.php
│ ├── wp-includes/ms-deprecated.php
│ // Load must-use plugins.
│ ├── $mu_plugin
│ // Load network activated plugins.
│ ├── $network_plugin
│ ├── ... выполнение ряда wp-функций
│ // Create common globals.
│ ├── wp-includes/vars.php
│ // Load active plugins.
│ ├── include_once( $plugin );
│ // Load pluggable functions.
│ ├── wp-includes/pluggable.php
│ ├── wp-includes/pluggable-deprecated.php
│ ├── ... выполнение ряда wp-функций
│ // Fires before the theme is loaded.
│ ├── do_action( 'setup_theme' );
│ // Define the template related constants.
│ ├── wp_templating_constants( );
│ // Load the default text localization domain.
│ ├── require( $locale_file );
│ ├── wp-includes/locale.php
│ // Load the functions for the active theme, for both parent and child theme if applicable.
│ ├── STYLESHEETPATH . '/functions.php
│ ├── TEMPLATEPATH . '/functions.php
│ // Fires after the theme is loaded.
│ ├── do_action( 'after_setup_theme' );
│ // Set up current user.
│ ├── $GLOBALS['wp']->init();
│ // Most of WP is loaded at this stage, and the user is authenticated. WP continues.
│ ├── do_action( 'init' );
│ // Check site status.
│ ├── require( $file );
│ // This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated.
│ ├── do_action( 'wp_loaded' );
├── wp()
│
└── wp-includes/template-loader.php
├── . . .
└── . . .
Загрузка констант, глобальных переменных и функций
Разбираем далее по шагам. Вот первая часть кода файла '/wp-load.php'
<?php
/** Define ABSPATH as this file's directory */
define( 'ABSPATH', dirname(__FILE__) . '/' );
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
*
* If neither set of conditions is true, initiate loading the setup process.
*/
if ( file_exists( ABSPATH . 'wp-config.php') ) {
/** The config file resides in ABSPATH */
require_once( ABSPATH . 'wp-config.php' );
} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
/** The config file resides one level above ABSPATH but is not part of another install */
require_once( dirname( ABSPATH ) . '/wp-config.php' );
} else {. . .}
Здесь определена переменная системы ABSPATH
- абсолютный путь к корню системы.
(Все переменные здесь).
Выполняем PHP-функцию вычисления уровня ошибок error_reporting
Далее ищем файл wp-config.php
или в корне сайта, или на уровень выше.
ABSPATH . 'wp-config.php'
- это следующий путь:
C:\OpenServer\domains\radiokidsfm/wp-config.php
dirname( ABSPATH ) . '/wp-config.php'
- это другой путь на уровень выше:
C:\OpenServer\domains/wp-config.php
В нашем случае файл wp-config.php
находится по первому адресу и он загружается.
Посмотрим, что там?
<?php
/**
* Основные параметры WordPress.
*
* Скрипт для создания wp-config.php использует этот файл в процессе
* установки. Необязательно использовать веб-интерфейс, можно
* скопировать файл в "wp-config.php" и заполнить значения вручную.
*
* Этот файл содержит следующие параметры:
*
* * Настройки MySQL
* * Секретные ключи
* * Префикс таблиц базы данных
* * ABSPATH
*
* @link https://codex.wordpress.org/Editing_wp-config.php
*
* @package WordPress
*/
// ** Параметры MySQL: Эту информацию можно получить у вашего хостинг-провайдера ** //
/** Имя базы данных для WordPress */
define('DB_NAME', 'radiokidsfm');
/** Имя пользователя MySQL */
define('DB_USER', 'root');
/** Пароль к базе данных MySQL */
define('DB_PASSWORD', '');
/** Имя сервера MySQL */
define('DB_HOST', 'localhost');
/** Кодировка базы данных для создания таблиц. */
define('DB_CHARSET', 'utf8');
/** Схема сопоставления. Не меняйте, если не уверены. */
define('DB_COLLATE', '');
/**#@+
* Уникальные ключи и соли для аутентификации.
*
* Смените значение каждой константы на уникальную фразу.
* Можно сгенерировать их с помощью {@link https://api.wordpress.org/secret-key/1.1/salt/ сервиса ключей на WordPress.org}
* Можно изменить их, чтобы сделать существующие файлы cookies недействительными. Пользователям потребуется авторизоваться снова.
*
* @since 2.6.0
*/
define('AUTH_KEY', 'SPa$6_G^Q9Z?rjVSM6o*R!L_h:Pq(v}p^jGu~!aakq,AjG4zL}]>cQL^]i6T})e2');
define('SECURE_AUTH_KEY', 'KAt&%{(Q^;$iz+/t%{Ct0GZn7sh^QhO=UyZg@ub_4zY4ik^jZD2e|W*Z]q@Df+t;');
define('LOGGED_IN_KEY', 'rc*yzhDTux)yy]#KTB{gNivV<%J{aeOgJLY9?w2=)!btrM~8QdA,7C[h?n=7:W 4');
define('NONCE_KEY', '8C$X7jh)r@QMN54seqvC6y|CU;o}Qg[A2|/x{,CFH0-7h,ZP|)1(WL$]nSc?kKz$');
define('AUTH_SALT', 'k.U[DOv6}[W,<P;8L!]l]tPTgA@7n(~R|f-lt7vLd_zc9nrO^:V-t;@j|}#H)p!U');
define('SECURE_AUTH_SALT', 'kd*Z+8(6CQu+xhm|phsRz`T=/=]#]&ck7oWmi33$W28@6O3D^a7H');
/**#@-*/
/**
* Префикс таблиц в базе данных WordPress.
*
* Можно установить несколько сайтов в одну базу данных, если использовать
* разные префиксы. Пожалуйста, указывайте только цифры, буквы и знак подчеркивания.
*/
$table_prefix = 'wp_';
/**
* Для разработчиков: Режим отладки WordPress.
*
* Измените это значение на true, чтобы включить отображение уведомлений при разработке.
* Разработчикам плагинов и тем настоятельно рекомендуется использовать WP_DEBUG
* в своём рабочем окружении.
*
* Информацию о других отладочных константах можно найти в Кодексе.
*
* @link https://codex.wordpress.org/Debugging_in_WordPress
*/
define('WP_DEBUG', true);
/* Это всё, дальше не редактируем. Успехов! */
/** Абсолютный путь к директории WordPress. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Инициализирует переменные WordPress и подключает файлы. */
require_once(ABSPATH . 'wp-settings.php');
Здесь сначала вводятся параметры работы с БД. Это можно делать вручную в этом файле или через админовский интерфейс.
Далее загружается файл wp-settings.php, который должен инициализировать переменные WordPress.
Вот начало кода этого файла:
<?php
/**
* Used to set up and fix common variables and include
* the WordPress procedural and class library.
*
* Allows for some configuration in wp-config.php (see default-constants.php)
*
* @internal This file must be parsable by PHP4.
*
* @package WordPress
*/
/**
* Stores the location of the WordPress directory of functions, classes, and core content.
*
* @since 1.0.0
*/
define( 'WPINC', 'wp-includes' );
// Include files required for initialization.
require( ABSPATH . WPINC . '/load.php' );
require( ABSPATH . WPINC . '/default-constants.php' );
Здесь сначала вводятся определяется переменная WPINC
- путь к директории wp-includes
.
Затем загружается файл /wp-includes/load.php
, в котором определяется большое количество функций(функции можно посмотреть здесь).
Затем загружается файл /wp-includes/default-constants.php
, в котором определяются константы и глобальные переменные, которые могут быть переопределены
, в основном в wp-config.php
.
Потребление ресурсов
Сайт загружается... загружается ... и никак не загрузится... Оказалось, что превышен лимит на оперативную память, установленный хостингом. Ищем причины превышения.
Как любая CMS, WordPress потребляет много ресурсов для собственного обслуживания, что не есть хорошо, но с этим приходится мириться... но нужно и бороться. Находим советы здесь
Прежде всего отключил сайт - дал возможность хостингу фиксировать снижение использования оперативной памяти. Включил, сайт заработал. Следую совету - установить в футере код
<?php echo get_num_queries(); ?> запросов. <?php timer_stop(1); ?> секунд. <?php echo memory_get_usage()/1024/1024, 2; ?> Мб
Открываю страницу просмотра кода сайта и в конце футера вижу ожидаемое сообщение:
34 запросов. 0,189 секунд. 14.1012039184572 Мб
Вроде не так уж и страшно... хотя 34 запроса в секунду к БД и не очень мало... Решаю последовать советам, описанным здесь - почистить БД с помощью плагина WP Clean Up. Установил, почистил - он удаляет из базы ревизии постов и многое другое позволяет почистить, в частности транзитное кэширование (о котором можно прочитать здесь) - убирать его или нет - нужно решать для конкретного случая.
Теперь можно (и нужно!) убрать остатки таблиц в БД от неиспользуемых плагинов, которые подключались когда-то, но уже не используются. Для этого используем плагин WPDBSpringClean.
Проделаем то же самое с сайтом КПД. По ресурсам до чистки БД имеем:
61 запросов. 0,460 секунд. 16.0060806274412 Мб
После чистки с помощью WP Clean Up ничего не изменилось.
WPDBSpringClean не обнаружил остатков неиспользуемых плагинов.
Попробуем определить, какие из установленных плагинов в какой степени нагружают сервер с помощью плагина P3 - Plugin Performance Profiler.Установил. просканировал сайт - оказалось, что только этот плагин и грузил сайт на момент сканирования.
Загрузка векторных изображений
На одном из сайтов нам понадобилось, чтобы логотипы представленных там компаний, отображались в разных размерах и в одинаково хорошем качестве. Решили использовать логотипы в векторном исполнении.
Но обнаружилась проблема - стандартная загрузка медиафайлов в WordPress воспринимает расширение .svg
как недопустимый формат (по крайней мере на версии 4.7.3 и более ранних).
Есть много ссылок в интернете, как это преодолеть. Самый простой совет - вставить в function.php
вашей темы следующий код:
// allow SVG uploads
add_filter('upload_mimes', 'custom_upload_mimes');
function custom_upload_mimes ( $existing_mimes=array() ) {
$existing_mimes['svg'] = 'image/svg+xml';
return $existing_mimes;
}
function fix_svg() {
echo '<style type="text/css">
.attachment-266x266, .thumbnail img {
width: 100% !important;
height: auto !important;
}
</style>';
}
add_action('admin_head', 'fix_svg');
Это работает. Но так как уверенности в том, что это сработает во всех случаях не было, стали разбираться и проверили такую «хитрость». Загрузили логотип в формате .png
. При загрузке через стандартную опцию «Медиафайлы» в папке /wp-content/uploads
появилось
несколько файлов изображения логотипа разных размеров, которые делает WordPress автоматически в соответствии с настройками темы.
Мы сделали векторные картинки логотипа таких же размеров и загрузили их в ту же папку с такими же именами, но с расширением .svg
. Затем в базе данных в таблицах wp_posts, wp_postmeta
нашли следы загруженного файла логотипа и заменили все .png
на .svg
. Например, в таблице wp_posts
была запись со значением поля post_title
соответствующим названию загруженного файла png-логотипа.
В таблице wp_postmeta
были обнаружены записи с ключами (meta_key) _wp_attached_file
и _wp_attachment_metadata
, в которых также располагались ссылки на файлы логотипа в поле meta_value
.
Везде заменили все .png
на .svg
. И это сработало! То же самое сделали и с иконкой (favicon).
Например, мы обнаружили такие коды в шапке сайта, предназначенный для краулеров сторонних приложений:
<link rel="icon" href="//dev.nedorub.com/wp-content/uploads/2017/03/cropped-favicon-32x32.png" sizes="32x32" />
<link rel="icon" href="//dev.nedorub.com/wp-content/uploads/2017/03/cropped-favicon-192x192.png" sizes="192x192" />
<link rel="apple-touch-icon-precomposed" href="//dev.nedorub.com/wp-content/uploads/2017/03/cropped-favicon-180x180.png" />
<meta name="msapplication-TileImage" content="//dev.nedorub.com/wp-content/uploads/2017/03/cropped-favicon-270x270.png" />
Но после того, как мы проделали описанные выше манипуляции с таблицами БД, все .png
заменились на .svg
. А один из плагинов, например, сгенерировал скрипты, типа этого:
<script type='application/ld+json'>{"@context":"http:\/\/schema.org","@type":"Organization","url":"http:\/\/dev.nedorub.com\/","sameAs":[],"@id":"#organization","name":"SAN&SAN Studio","logo":"http:\/\/dev.nedorub.com\/wp-content\/uploads\/2017\/03\/logo-sanisan-300x23.png"}</script>
Следы этой ссылки на логотип были обнаружены в таблице wp_options
и .png
исправлен на .svg
.
Как только мы выложили сайт с локального сервера на хостинг обнаружилась неприятная проблема: стал поступать спам двух видов - регистрация на сайте явных ботов и появление спамовских записей! Стали искать способы борьбы с ними.
Изменяем wp-login
Самый простой способ для разного рода вредителей войти в ваш сайт через wp-login.php
, то есть через открытые «ворота» для регистрации и залогинивания.
Простейший способ уменьшить эту угрозу описан здесь. А именно: нужно сделать три шага:
wp-login.php
, который находится в корне сайта. Например, в abcde.php
wp-login.php
на abcde.php
general-template.php
, который находится в папке wp-includes
, заменить wp-login.php
на abcde.php
Но этого оказалось недостаточно. Так, при регистрации новых пользователей им отправлялось письмо с обратной ссылкой, содержащей wp-login.php
. Чтобы ссылка была корректной, нужно
также заменить wp-login.php
на abcde.php
в файле /wp-includes/plaggeble.php
.
Блокируем доступ по wp-login.php и wp-admin
Подробно эта процедура описана здесь. Делаем это через файл .htaccess
# Hide admin URL start
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^new_admin/?$ /new_wp-login.php?secret_key [R,L]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^blackhole/?$ /new_wp-login.php?secret_key&redirect_to=/wp-admin/ [R,L]
RewriteRule ^blackhole/?$ /wp-admin/?secret_key [R,L]
RewriteCond %{SCRIPT_FILENAME} !^(.*)admin-ajax\.php
RewriteCond %{HTTP_REFERER} !^(.*)my_site/wp-admin
RewriteCond %{HTTP_REFERER} !^(.*)my_site/new_wp-login\.php
RewriteCond %{HTTP_REFERER} !^(.*)my_site/blackhole
RewriteCond %{QUERY_STRING} !^secret_key
RewriteCond %{QUERY_STRING} !^action=logout
RewriteCond %{QUERY_STRING} !^action=rp
RewriteCond %{QUERY_STRING} !^action=postpass
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^.*wp-admin/?|^.*new_wp-login\.php /not_found [R,L]
RewriteCond %{QUERY_STRING} ^loggedout=true
RewriteRule ^.*$ /new_wp-login.php?secret_key [R,L]
</IfModule>
# Hide admin URL end
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Здесь new_admin
- любой адрес, по которому теперь будет доступна страница входа в админ-панель сайта; new_wp-login.php
- это тот новый файл, который мы сделали вместо
wp-login.php
на предыдущем шаге; my_site
- домен нашего сайта и secret_key
- любой сложный набор символов.
Внимание! Чтобы эти коды в .htaccess работали, мне пришлось отключить первоначальные коды, которые были прописаны в WP - первый модуль в скобках # BEGIN WordPress
и # END WordPress
,
который я закоммитил с помощью символа #, но оставил в тексте для наглядности и напоминания.
Теперь вход на сайт возможен по адресу [my_site]/new_admin
или [my_site]/new_wp-login.php?secret_key
, а при попытке обратиться по адресам [my_site]/wp-admin
или [my_site]/wp-login.php
выдается 404 ошибка.
Удаляем readme.html
По присутствию этого файла в корне сайта и его содержанию злоумышленники выудят информацию о том, что ваш сайт сделан на WordPress и узнают версию движка. Поэтому следует просто удалить readme.html
.
Удаляем meta-name Generator
Вордпресс добавляет внутри <head>
метатеги <meta name="generator" content="WordPress 4.6.4" />
и <meta name="generator" content="WooCommerce 2.6.4" />
, если подключен WooCommerce
.
Очевидно, что по этим метатегам также легко определить следы WordPress. Устраним их следующим образом. В файле /wp-includes/functions.php
добавляем код
// Полностью убираем версию WordPress
add_filter('the_generator', '__return_empty_string');
Удаляем версии из ссылок на css- и js-файлы
Версия WP также присутствует на ссылках типа
<link rel='stylesheet' id='dashicons-css' href='//back2money.club/wp-includes/css/dashicons.min.css?ver=4.6.4' type='text/css' media='all' />
.
Устраним эти версии из ссылок следующим образом. В файле /wp-includes/functions.php
добавим код
// Удаление параметра ver из добавляемых скриптов и стилей
function rem_wp_ver_css_js( $src ) {
if ( strpos( $src, 'ver=' ) )
$src = remove_query_arg( 'ver', $src );
return $src;
}
add_filter( 'style_loader_src', 'rem_wp_ver_css_js', 9999 );
add_filter( 'script_loader_src', 'rem_wp_ver_css_js', 9999 );
?ver=4.6.4
Редактируем права пользователей
Для редактирования прав пользователей мы используем плагин User Role Editor
. Подробнее о плагине написано здесь
После установки плгина появляется возможность редактировать права пользователя в настройках:
Первое, что мы делаем - устанавливаем роль пользовтеля по умолчанию, который впервые регистрируется еа сайте - это самая низшая роль - Подписчик.
Редактируем общие настройки
Многие спамят обратными ссылками с британских, французских, китайских и других сайтов.
Поэтому сейчас посмотрим, как отключить обратные ссылки в постах.
Обратные ссылки выглядят, как обычные комментарии – некто ставит на своих говносайтах ссылку на вашу статью, у вас в комментариях появляется
цитата с этой ссылкой и ссылкой на чужой сайт. Эта ссылка обычно по-настоящему ужасна для вашего авторитета у поисковиков.
Вот, что видно в меню «Комментарии», и это только верхняя часть всего списка обратных ссылок, которые ожидают одобрения.
Поближе это выглядит примерно так: какой-то бред, в который затесалась ссылка на ваш блог.
Во-первых, отключаем в блоге WordPress оповещения в/из других блогов об упоминаниях их в статьях. Во-вторых, отключаем обратные ссылки во всех уже опубликованных старых постах.
Никак не допишу статью о первоначальных настройках вордпресс-блога, а там будет информация и о «Настройках обсуждения». Поэтому пока просто переходим в админке в меню «Параметры» – «Обсуждения» и вверху страницы снимаем «галочки» в настройках для статьи по умолчанию:
Также можно включить опцию «Автоматически закрывать обсуждение статей старше столько-то дней».
Нажимаем внизу кнопку «Сохранить изменения».
Но на этом дело не закончиться, потому что для старых статей разрешены обратные ссылки.
Для одной статьи обратные ссылки отключить легко: нужно перейти к меню «Записи», нажать «Свойства» для нужной статьи и снять отметку «Разрешить отклики». После этого нажать кнопку «Обновить».
Но если статей много, то проще всего изменить их свойства с помощью SQL-запроса в базе данных. Сделать это можно в панели phpMyAdmin или с помощью специальных плагинов WordPress.
Отключение обратных ссылок в старых статьях в панели phpMyAdmin
В панели phpMyAdmin выбираем нужную базу данных и переходим на вкладку «SQL».
В поле «Выполнить SQL-запрос(ы) к базе данных…» пишем такой запрос:
UPDATE wp_posts SET ping_status = 'closed';
Здесь «UPDATE» - команда изменения данных в таблице, «wp _posts» - указание, что данные нужно поменять в таблице записей, «SET» - установка значения для «ping_status» (состояние обратных ссылок) как «closed» (закрыто).
После этого нажимаем кнопку «ОК» справа внизу, под полем для SQL-запросов. Если всё сделано правильно, то появится сообщение: «Затронуто столько-то строк…».
Это означает, что для всех записей блога обратные ссылки отключены, и спамеры со своими ссылками идут лесом.
А можно удалить сразу все комментарии, ожидающие одобрения, с помощью другого SQL-запроса к базе данных.
В этом случае запрос будет таким:
DELETE FROM wp_comments WHERE comment_type='trackback' ;
Здесь «DELETE» - команда на удаление строк, «FROM wp_comments» – из таблицы комментариев, «WHERE comment_type» - где тип комментария соответствует значению «trackback».
Чтобы наш сайт не был похож на миллионы других, сделанных на WordPress, в первую очередь следует убрать все стандартные следы от WP. Начнем с формы входа/регистрации.
Изменяем логотип на странице Входа
В оргигинале страница входа выглядит так:
Чтобы заменить логотип на свой, в файле нашей темы functions.php
пропишем код, который это сделает, а именно:
function my_login_logo(){
echo '
<style type="text/css">
#login h1 a { background: url('. get_bloginfo('template_directory') .'/images/my_logo.png) no-repeat 0 0 !important;width:211px !important; height:108px !important }
</style>';
}
add_action('login_head', 'my_login_logo');
И, соответственно, в папку нашей темы images
загружаем наш логотип с именем my_logo.php
Кроме того, чтобы при клике на логотип мы отправлялись на нашу главную страницу (а не на сайт WordPress), добавим еще две строчки кода в файл functions.php
add_filter('login_headerurl',create_function('','return get_home_url();'));
add_filter('login_headertitle',create_function('','return "San&San Studio";'));
Теперь форма залогинивания выглядит так:
Если нужно поменять цвет кнопки, фона и пр., то внутри тегов в функции
my_login_logo()
нужно добавить соответствующие стили, например:
function my_login_logo(){
echo '
<style type="text/css">
body{background-color: rgba(113, 55, 200, .1) !important;}
.wp-core-ui .button-primary {
background: #5a2ca0 !important;
border-color: #442178 #2d1650 #2d1650 !important;
-webkit-box-shadow: 0 1px 0 #2d1650 !important;
box-shadow: 0 1px 0 #2d1650 !important;
color: #fff !important !important;
text-decoration: none !important;
text-shadow: 0 -1px 1px #2d1650, 1px 0 1px #2d1650, 0 1px 1px #2d1650, -1px 0 1px #2d1650 !important;
}
.wp-core-ui .button-primary:hover {
background-color: rgba(113, 55, 200, .7) !important;
}
.login form .input:focus, .login form input[type=checkbox]:focus{border-color: #7137c8 !important;}
#login h1 a { background: url('. get_bloginfo('template_directory') .'/images/kp-logo.png) no-repeat center center;background-size:100%; width:87px !important; height:104px !important }
</style>';
Изменяем логотип в админ-панели
После залогинивания пользователь попадает в стандартную админку WP, где в левом верхнем углу размещен логотип WordPress.
«dashicons»
.
Вам (или вашему клиенту) захочется заменить этот логотип на свой. Что для этого нужно сделать?
В файл function.php
нужно вставить код:
add_action('add_admin_bar_menus', 'reset_admin_wplogo');
function reset_admin_wplogo( ){
remove_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 ); // удаляем стандартную панель (логотип)
add_action( 'admin_bar_menu', 'my_admin_bar_wp_menu', 10 ); // добавляем свою
}
function my_admin_bar_wp_menu( $wp_admin_bar ) {
$wp_admin_bar->add_menu( array(
'id' => 'wp-logo',
'title' => '<img style="max-width:24px;height:auto;" src="'. SITE_IMGPATH .'admin-logo.png" alt="" >',
'href' => home_url(''),
'meta' => array(
'title' => '[my_site_title]
',
),
) );
}
Этот код заменяет стандартный логотип в админ-панели на ваш - admin-logo.png
, который следует загрузить на сайт по адресу SITE_IMGPATH
. Например, мы сделали в корне сайта
папку assets/images
и в файле function.php
определили к ней путь:
if ( !defined('SITE_IMGPATH') )
define('SITE_IMGPATH', SITEROOT. 'assets/images/' );
Рекомендуем размер логотипа для админки - 24х24px.
Теперь админ-панель выглядит так:
Если вы хотите для логотипа админки использовать dashicons, то функция my_admin_bar_wp_menu
в предыдущем коде должна быть такой:
. . .
function my_admin_bar_wp_menu( $wp_admin_bar ) {
$wp_admin_bar->add_menu( array(
'id' => 'wp-logo',
'title' => '<span style="font-family:dashicons; font-size:20px;" class="dashicons dashicons-carrot"></span>', // морковка',
'href' => home_url(''),
'meta' => array(
'title' => '[my_site_title]
',
),
) );
}
Теперь админ-панель выглядит так:
Создаем логотип сайта
Логотип сайта - это логотип, который можно выводить в нужном месте на страницах сайта с помощью функции WP the_custom_logo()
.
Если вы загрузили какую-либо тему, то там уже прописано место (как правило в хёдере сайта), где должен загружаться логотип сайта. Загрузка логотипа осуществляется из админки в разделе Внешний вид -> Настроить
Открывается страница настроек внешнего вида сайта для данной темы.
В меню справа открываем раздел Свойства сайта
.
Загружаем логотип. Здесь же вводим название сайта и заменяем описание сайта на своё.
Опубликовать
.
Вот так выглядел хёдер темы Twenty Seventeen
до загрузки логотипа:
А так - после:
Для этого вставим в файл function.php
следующий код:
add_theme_support( 'custom-logo' );
function wp_custom_logo() {}
add_action('wp_before_admin_bar_render', 'wp_custom_logo');
Размер логотипа задайте в вашем файле style.css
, например, вот так:
.custom-logo-link img {
display: inline-block;
max-height: 80px;
width: auto;
}
Управляем админ-баром
После входа пользователя на сайт (после залогинивания) поверх хедера страницы появляется черная полоска админ-бара с меню (переход в консоль админки, переход в настройки профиля, поиск по сайту, выход и т.п.). Это не всегда нужно. Как не показывать эту панель? Вообще-то, каждый пользователь может самостоятельно отключить этот бар в своём профиле. Там есть соответствующая возможность:
Но чаще всего, вы хотите отключить этот админ-бар совсем, чтобы пользователь его не видел на страницах сайта (а только в консоли админки).
Для этого нужно в файле function.php
вставить следующий код:
// Удаление админ-бара на страницах сайта
if ( ! current_user_can( 'edit' ) ) {
show_admin_bar( false ); // не показывать
//show_admin_bar( true ); // показывать
}
Начинаем с создания папки темы
Итак, мы уже знаем, что в файловой структуре Вордпресса имеется директория /wp-content/themes/
, в которой размещены папки с наименованиями стандартных тем, поставленных в коробке Wordpress:
Интуитивно понимаем, что для создания собственной темы нам нужно здесь же разместить папку с названием нашей темы. Это и будет корневая папка нашей темы. Назовем тему (и соответственно папку), например: kidspromo
.
Затем, как мы привыкли, создадим в этой новой папке файл index.php
с традиционным приветствием Миру:
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* For example, it puts together the home page when no home.php file exists.
*
* @link //codex.wordpress.org/Template_Hierarchy
*
*/
echo "Hellow World! I am index.php";
index.php
стандартной темы. Изучим его внимательнее попозже.Итак, если бы мы делали сайт без использования WP, то при переходе на сайт в браузере увидели бы наше приветствие. В данном же случае возникает естественный вопрос: а как же система увидит, что мы создали новую тему и хотим увидеть наше приветствие?
Для активации темы мы должны в админке пройти в Внешний вид -> Темы
и там выбрать, и активировать нашу тему. Но если мы это сделаем, то обнаружим, что нашей темы там нет!
Для этого в WP предусмотрена следующая процедура.
Размещаем в корне темы наряду с index.css
файл style.css
с вот таким комментарием:
/*
Theme Name: Kids Promo
Theme URI: //nedorub.com/wordpress-themes/kidspromo
Description: Themes special for kidspromo.ru.
Author: Sergey Nedorub
Author URI: //nedorub.com
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: //www.gnu.org/licenses/gpl-2.0.html
Tags: sergeynedorub, kidspromo, wordpress
Text Domain: sanradio
*/
Оказывается, WordPress прочитает этот комментарий и разместит новую тему в админке.
Theme Name
- очень важно. Именно это название (в нашем случае Kids Promo
) WordPress будет
определять и выводить как название темы. Если мы делаем дочернюю тему, то описание несколько другое. О дочерних темах можно прочитать здесь
При программировании сайта при необходимости можно вывести данные, размещенные в этом комментарии файла style.css
с помощью функции wp_get_theme()
. Вот что выдаёт эта функция с помощью
php-кода print_r(wp_get_theme());
:
WP_Theme Object ( [update] => [theme_root:WP_Theme:private] => C:\OpenServer\domains\kidspromo/wp-content/themes [headers:WP_Theme:private] => Array ( [Name] => SanRadio [ThemeURI] => https://everpeek.com/wordpress-themes/sanradio [Description] => Themes special for radiokidsfm.ru. [Author] => Sergey Nedorub [AuthorURI] => https://www,everpeek.com [Version] => 1.0.0 [Template] => [Status] => [Tags] => light, blue, green, orange, pink, white, gray, red, black, one-column, two-columns, right-sidebar, left-sidebar, fluid-layout, responsive-layout, custom-background, custom-colors, custom-header, custom-menu, editor-style, featured-images, flexible-header, full-width-template, microformats, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready [TextDomain] => sanradio [DomainPath] => ) [headers_sanitized:WP_Theme:private] => [name_translated:WP_Theme:private] => [errors:WP_Theme:private] => [stylesheet:WP_Theme:private] => sanradio [template:WP_Theme:private] => sanradio [parent:WP_Theme:private] => [theme_root_uri:WP_Theme:private] => [textdomain_loaded:WP_Theme:private] => [cache_hash:WP_Theme:private] => 7aa716ea677bf530f8db62f93fb73c59 )
Эти данные можно извлекать и использовать, например, с помощью такого php-кода:
$my_theme = wp_get_theme( 'kidspromo' );
if ( $my_theme->exists() ){
echo $my_theme->get( 'Name' ) . " is version " . $my_theme->get( 'Version' );
}
Если теперь зайти в панели администратора WP в раздел выбора шаблонов Внешний вид > Темы
, то можно увидеть, что появилась наша тема в списке прочих:
Мы не поленимся и создадим еще файл-картинку нашей темы (размер 300 на 225 пикселей) и загрузим в папку kidspromo
под именем screenshot.png
. Теперь наша тема в разделе выбора тем в админке выглядит гораздо привлекательнее:
Активируем нашу тему и смотрим, что видит браузер при обращении к нашему сайту: Hellow World! I am index.php
index.php
заработал!Файловая структура Темы
Теперь вернемся назад и прочитаем комментарий в файле index.php
. Там написано, что этот файл является основным, и, например, выводится в качестве главной страницы, если нет файла home.php
Сделаем файл home.php
с кодом:
<?php
/**
* The home.php file
*
*/
echo "Hellow World! I am home.php";
и перезагружаем сайт: видим, что выводится Hellow World! I am home.php
. То есть, WordPress проигнорировал файл index.php
и загрузил home.php
!
Так вот! Оказывается, система WordPress распознает не только index.php
но и ещё несколько специальных файлов-шаблонов и распоряжается с ними (выстраивает определенную иерархию и предоставляет к ним доступ из php-кодов)
в соответствии со своим кодексом. Подробнее можно прочитать здесь.
К таким специальным файлам относятся:
Делаем главную страницу
Как мы описали выше, при загрузке сайта выводится страница home.php
, а если её нет, то index.php
. Но страница home.php
не является обязательной. WP предусматривает два варианта выдачиглавной страницы сайта.
Проследуем в админке по адресу Настройки -> Чтение
:
Здесь мы должны определить, что выводить на главной странице. Если мы выбираем «Ваши последние записи», то при загрузке сайта первой (главной) должна загружаться страница с нашими записями.
Если выбираем «Статическую страницу», то активируются два поля со списками страниц сайта из которых нужно выбрать, какую страницу использовать в качестве главной (front-page
), а на какой странице отображать последние записи.
Но сначала, такие страницы нужно создать. Проследуем по адресу Страницы -> Добавить новую
:
Здесь мы можем ввести заголовок страницы и её содержание.
Но для того, чтобы это все отображалось на сайте, необходимо разместить в корне темы файлы index.php
, single.php
и page.php
, с правильно прописанными php-кодами для вывода постов, комментариев и страниц.
Начнем с файла index.php
, который должен выводить все записи (посты). Создадим такой файл:
<?php
/**
* The main template file
* . . .
*/
get_header();
?>
<?php
while ( have_posts() ) : the_post();
?>
<article>
<header>
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header>
<div>
<?php the_content(); ?>
</div>
</article>
<?php
endwhile;
?>
<?php get_footer();
Убедились, что при загрузке сайта (при настройке вывода на первой странице последних постов) выдается список постов.
Разберем вышенаписанный код.
Здесь используется несколько WP-функций, а именно: get_header()
и get_footer()
создают хёдер и футер HTML страницы и всавляют туда некоторые скрипты и ссылки,
необходимые для функционирования системы (то есть для работы функций, хуков, тегов из арсенала Вордпресса). А также, что важно иметь ввиду, здесь отрабатывает главный запрос wp()
и определяются
глобальные переменные $wp_query, $wp_the_query;$query_string, $posts, $post, $request, $more и $single (для is_singular()), $authordata (для is_author()) и все переменные $wp_query.
Цикл while ( have_posts() ) : the_post();
перебирает в БД записи из таблицы wp_posts
и достает все записи, у которых значение поля post_type
равно post
. То есть все наши посты. Функция the_title()
выдает заголовок поста, а функция the_content()
- содержание поста.
Теперь сделаем файл-шаблон page.php
, который по умолчанию будет являться шаблоном (базовым шаблоном) для вывода всех станиц сайта, для которых не задан другой шаблон. Создадим такой файл:
<?php
/**
* The template for displaying all pages
* . . .
*/
get_header();
?>
<?php
while ( have_posts() ) : the_post();
?>
<article>
<header>
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header>
<div>
<?php the_content(); ?>
</div>
</article>
<?php
endwhile;
?>
<?php get_footer();
Здесь код такой же как и на странице index.php
. Разница в том, что WordPress определяет, что это не пост, а страница и выбирает из таблицы wp_posts
записи, у которых значение поля post_type
равно page
, а поле . То есть все наши посты.
Делаем header.php
Простейший код хёдера нашей темы может выглядеть так:
<?php
/**
* The header for our theme.
*/
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
<body>
Чтобы в хёдере HTML кода появился заголовок Title
можно использовать функционал WordPress.
Вставим в файл нашей темы function.php
следующую функцию:
add_theme_support( 'title-tag' );
Подробнее об этой функции и ее возможностях (не только title-tag) подробно описано здесь.
Теперь на каждой странице есть свой title
, состоящей из названия страницы/поста и названия сайта. Именно так WP сформирует заголовок страницы, который и будет выводиться поисковиками.
Но такой заголовок может оказаться далеко не оптимальным с точки зрения SEO. Если вас такие заголовки не устраивают, то можно поступить так, как описано ниже.
Итак, убираем add_theme_support( 'title-tag' )
из файла function.php
. Далее, в админке на каждой странице добавляем новое произвольное поле с именем, например, seo-title
и вводим его значение (не забываем обновить изменения). Как это сделать - подробно описано здесь.
Теперь в БД в таблице postmeta
появится запись с ID
страницы и значением, которое вы ввели в админке.
И, наконец, в хёдере (перед мета-тегом description
) вставляем следующую строчку:
<title><?php echo get_post_meta($post->ID, 'seotitle', true); ?></title>
description
и keywords
.В настоящее время декларируется, что эти мета-теги не являются обязательными и не влияют на ранжирование сайта в поиске. Тем не менее, Яндекс, например, будет ругаться, если отсутствует тег описания сайта. Поэтому, установка этих тегов желательна.
Установить эти мета-теги можно либо с помощью плагинов, например: All in One SEO Pack, либо вручную: вставляем в хедере внутри <head> </head> следующий код, например:
<meta name="description" content="<?php
if ( is_front_page() || is_home() ) {
echo 'Разработка, продвижение и сопровождение сайтов - San&San Studio - ВЕБ Студия.';
} elseif ( is_single() || is_page() ) {
echo get_post_meta($post->ID, "description", true);
}
remove_filter('term_description','wpautop');
if (is_category()) {echo category_description();
} ?>" />
<meta name="keywords" content="<?php
if ( is_front_page() || is_home() ) {
echo 'San&San Studio, Сергей Недоруб, создание сайтов, разработка сайтов, СЕО, SEO, продвижение сайта, поддержка сайта, разработка ИТ проектов';
} elseif ( is_single() || is_page() ) {
echo get_post_meta($post->ID, "keywords", true);
} ?>" />
Теперь в админке WP для каждой страницы и записи добавляем произвольные поля description
и keywords
и содержание этих полей. Как это сделать - подробно описано здесь.
Если активировать нашу тему, то в разделе Внешний вид панели администратора увидим следующую картину:
А если активировать, например, тему Ribosome, то увидим такую картину:
Таким образом, наша тема пока не поддерживает ни Меню, ни Виджеты, ни Фон, ни Заголовок.
Все долгие поиски в интернете ответа на вопрос (и естественно, попыток этими ответами воспользоваться), не приносили успеха, пока я не наткнулся
на статью Андрея Морковина. Следуя его инструкции, всё удалось настроить и научиться
делать и подключать различные меню. Опишу подробнее. Начинаем с файла functions.php
. Запишем в этом файле следующий сод:
// Регистрируем две области locations) для загрузки меню: header-menu1 и footer-menu1
function register_my_menus()
{
register_nav_menus
(
array( 'header-menu' => 'header-menu1', 'footer-menu' => 'footer-menu1')
);
}
// Инициируем подключение этих облостей при загрузке WordPress
if (function_exists('register_nav_menus'))
{
add_action( 'init', 'register_my_menus' );
}
Перезагружаем тему и видим, что WordPress подключил нам функцию работы с меню.
Создаём несколько меню (перед этим нужно создать несколько страниц, чтобы было, что добавлять в меню) и соотносим их к определенным областям - это несложно понять, поэкспериментировав с функцией Меню в админке.
Мы создали два меню с именами: header-menu-2
и footer-menu-2
.
Чтобы вывести меню на сайте, нужно в соответствующем месте ( в нашем случае в файлах heder.php
footer.php
вставить
в html-код, где мы хотим разместить меню кусок php-кода с вызовом меню wp-функцией wp_nav_menu()
:
в хёдере, например:
<div id="navigation">
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-static-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1" style="height: 1px;">
<?php wp_nav_menu( array( 'theme_location' => 'header-menu' ) ); ?>
</div>
</div>
</nav>
</div>
</div>
</div>
</div>
При загрузке файла WordPress генерирует HTML-код и вставляет его вместо wp_nav_menu()
. Для
нашего хёдера этот код имеет вид:
<div class="menu-header-menu-2-container">
<ul id="menu-header-menu-2" class="menu"><li id="menu-item-247" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-70 current_page_item current_page_parent menu-item-247"><a href="//test/index/">KIDSFM</a></li>
<li id="menu-item-248" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-248"><a href="//test/%d0%be-%d0%bd%d0%b0%d1%81/">О НАС</a></li>
<li id="menu-item-249" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-249"><a href="//test/%d1%88%d0%ba%d0%be%d0%bb%d0%b0/">ШКОЛА</a></li>
<li id="menu-item-250" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-250"><a href="//test/%d0%be-%d0%bd%d0%b0%d1%81/%d0%bd%d0%b0%d1%88-%d0%b0%d0%b4%d1%80%d0%b5%d1%81/">Наш адрес</a></li>
<li id="menu-item-251" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-251"><a href="//test/%d0%b0%d1%84%d0%b8%d1%88%d0%b0/">АФИША</a></li>
<li id="menu-item-252" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-252"><a href="//test/%d1%80%d0%b0%d0%b4%d0%b8%d0%be%d0%b2%d0%b5%d0%b4%d1%83%d1%89%d0%b8%d0%b5/">РАДИОВЕДУЩИЕ</a></li>
<li id="menu-item-253" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-253"><a href="//test/%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8/">ПЕРЕДАЧИ</a></li>
<li id="menu-item-254" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-254"><a href="//test/%d1%82%d0%be%d0%bf/">ТОП</a></li>
<li id="menu-item-255" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-255"><a href="//test/%d0%b3%d0%b0%d0%bb%d0%b5%d1%80%d0%b5%d1%8f/">ГАЛЕРЕЯ</a></li>
</ul>
</div>
Остаётся прописать стили для всех нужных классов меню, чтобы оно выглядело так, как нам нужно. Следует обратить внимание на класс current-menu-item, который должен определять стиль для кнопки меню, соответствующей текущей отображаемой странице... всё! Дело сделано!
Управление логотипом в WP
Конечно, можно вставлять свой логотип в коды страниц сайта, где это требуется, простыми средствами HTML. Но это будет не правильно, если мы все-таки делаем WP-тему. Чтобы можно было загружать логотип из админки, нужно для начала вставить в
functions.php
следующий код:
// Добавление в админке загрузки логотипа
add_theme_support( 'custom-logo' );
function wp_custom_logo() {
echo '
';
}
//хук в вывод шапки в административной панели
add_action('wp_before_admin_bar_render', 'wp_custom_logo');
Если теперь зайти в админке Внешний вид -> Настроить -> свойства сайта
, то увидим, что появилась форма для загрузки логотипа:
Вставить логотип в коде можно теперь с помощью функции the_custom_logo()
. А наименование сайта, введенного там же в Внешний вид -> Настроить -> свойства сайта
- с помощью функции bloginfo('name')
.Например:
<?php the_custom_logo()?><br>
<a href="<?php bloginfo('url');?>" title="My Site"><?php bloginfo('name'); ?></a>
Загрузка .svg
- файлов векторной графики
Очень часто логотипы исполнены в виде файлов векторной графики, например с расширением .svg
. Чтобы разрешить загрузку таких файлов в админке WordPress, нужно в файле function.php
прописать следующий код:
// Разрешить поддержку SVG
function my_myme_types($mime_types){
$mime_types['svg'] = 'image/svg+xml'; // поддержка SVG
return $mime_types;
}
add_filter('upload_mimes', 'my_myme_types', 1, 1);
Делаем functions.php
Выше мы уже начали создавать файл functions.php
, вставляя в него некоторые нужные нам функции для реализации определенных возможностей.
Пора, как мне кажется, подробнее описать этот файл. Понятно, что как обычно мы в каком-то файле можем прописать различные функции, которые мы считаем нужными написать для облегчения программирования сайта.
Для этого этот файл и предназначен. Но, так как мы работаем в WordPress, то в этом файле нужно прописать и определенные функции, открывающие возможности WordPress для нашей темы. Продолжим их создавать.
Зайдем в админке на Записи -> Добавить новую
. Мы попадаем на страницу редактирования записи (post) и в правом сайдбаре видим следующее:
Но, если вы активируете стандартную тему, например Twentyseventeen
, то увидите следующую картинку:
Сразу встает вопрос: почему в нашей теме нет возможности загружать Изображение записи
и выбирать Формат записи
? И как эти возможности добавить?
Большинство рекомендаций в интернете сводится к тому, что нужно кликнуть на кнопку Настройка экрана
и добавить нужные вам опции. Если вы это сделаете, например. в Twentyseventeen
, то увидите следующее:
Но если вы сделаете то же самое в своей создаваемой теме, то обнаружите, что ни опции Формат
, ни опции Изображение записи
у вас нет! Что делать?
functions.php
:
/*
* Enable support for Post Formats.
*
* See: https://codex.wordpress.org/Post_Formats
*/
if ( ! function_exists( 'kidspromo_theme_setup' ) ) :
/* Sets up theme defaults and registers support for various WordPress features. */
function kidspromo_theme_setup() {
// языковая поддержка
load_theme_textdomain( 'kidspromo', get_template_directory() . '/languages' );
// фиды для rss-подписки
add_theme_support( 'automatic-feed-links' );
// добавление миниатюры поста
add_theme_support( 'post-thumbnails' );
// html5 форма поиска, форма и список комментариев
add_theme_support( 'html5', array(
'search-form', 'comment-form', 'comment-list',
) );
// какие форматы постов будут поддерживаться
add_theme_support( 'post-formats', array(
'aside', 'image', 'video', 'quote', 'link', 'status',
) );
}
endif;
add_action( 'after_setup_theme', 'kidspromo_theme_setup' );
Чтобы в разделе левого меню админ панели Внешний вид появился подраздел Виджеты (управление виджетами) добавим аналогично тому, как это было сделано выше, следующий код в функцию functions.php
/**
* Register widget area.
*
* @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
*/
function my_theme_widgets_init() {
register_sidebar( array(
'name' => __( 'Sidebar', 'my_theme' ),
'id' => 'sidebar-1',
'description' => __( 'Add widgets here to appear in your sidebar.', 'my_theme' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
) );
register_sidebar( array(
'name' => __( 'Footer 1', 'my_theme' ),
'id' => 'sidebar-2',
'description' => __( 'Add widgets here to appear in your footer.', 'my_theme' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
) );
register_sidebar( array(
'name' => __( 'Footer 2', 'my_theme' ),
'id' => 'sidebar-3',
'description' => __( 'Add widgets here to appear in your footer.', 'my_theme' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
) );
}
add_action( 'widgets_init', 'my_theme_widgets_init' );
Заголовок Header Image
Теперь займёмся подключением функции Заголовка (Картинки заголовка).
Для того, чтобы была возможность установить картинку заголовка для темы нужно включить опцию custom-header
в функции add_theme_support()
.
Пропишем в файле functions.php
следующий код:
/**
* Set up the WordPress core custom header arguments and settings.
*
* @uses add_theme_support() to register support for 3.4 and up.
* @uses sanfirst_header_style() to style front-end.
* @uses sanfirst_admin_header_style() to style wp-admin form.
* @uses sanfirst_admin_header_image() to add custom markup to wp-admin form.
*
* @since Sanfirst 1.0
*/
function sanfirst_custom_header_setup() {
$args = array(
// Text color and image (empty to use none).
'default-text-color' => 'EAEAEA',
'default-image' => '',
// Set height and width, with a maximum value for the width.
'height' => 292,
'width' => 1144,
'max-width' => 2000,
// Support flexible height and width.
'flex-height' => true,
'flex-width' => true,
// Random image rotation off by default.
'random-default' => false,
// Callbacks for styling the header and the admin preview.
'wp-head-callback' => 'sanfirst_header_style',
'admin-head-callback' => 'sanfirst_admin_header_style',
'admin-preview-callback' => 'sanfirst_admin_header_image',
);
add_theme_support( 'custom-header', $args );
}
add_action( 'after_setup_theme', 'sanfirst_custom_header_setup' );
Этого достаточно, чтобы включить поддержку картинки заголовка для темы:
Теперь вставим в нужном месте HTML кода в хёдере вызов картинки заголовка:
<?php if( has_header_image() )
echo '<img src="'. get_header_image() .'" alt="'. get_bloginfo('title') .'">';
?>
В нашем случае картинку нужно было использовать как фон блока. Поэтому мы написали следующий код:
<div id="header" class="hidden-sm hidden-xs" style="background:url(<?php echo header_image() ?>); background-position:center;">
</div>
Здесь мы использовали функцию header_image()
, которая выдаёт URL картинки.
Теперь встал вопрос о том, чтобы выводить эту картинку заголовка только на главной странице. Для этого мы поместили кодс выводом картинки внутри условного оператора:
<?php
if(is_home() OR is_page(91) ) { ?>
<div id="header" ...>
. . .
</div>
<?php } ?>
Здесь мы использовали два условных тега: is_home() и is_page(). Причём тег is_page() можно использовать либо с ID страницы или с её наименованием, например:is_page(91) и is_page('АФИША') выдаёт один и тот же результат.
Подключаем JS и CSS
Уже на этапе создания меню возникает вопрос о подключении скриптов и таблиц стилей. Если наше меню достаточно креативное и требует подключения скриптов .js
и таблиц стилей .css
, то возникает вопрос о их подключении.
Первый вариант - просто прописать путь к этим файлам в хёдере и футере (что где нужно). И это работает. Но, так как мы делаем сайт на WP, то было бы правильно использовать средства вордпресса, тем более, что такие имеются.
Допусти, мы разместили необходимый нам скрипт my-script.js
по адресу /assets/js/my-script.js
. Для его подключения средствами WP поместим в файл functions.php
нашей темы следующие функции:
/**
* Enqueue scripts and styles.
*/
function mytheme_scripts() {
wp_register_script('my-script', get_template_directory_uri() . '/assets/js/my-script.js', array(),'1.0',true);
wp_enqueue_script('my-script');
}
add_action( 'wp_enqueue_scripts', 'mytheme_scripts' );
Функция wp_register_script()
имеет 5 аргументов, разделенных запятыми. С первыми двумя понятно из контекста выше. третий параметр нужен, если для работы нашего скрипта требуется библиотека jquery
. Тогда пишем
array('jquery') вместо array(). Четвертый параметр - версия нашего скрипта - ставим что угодно. Пятый параметр указывает на размещение скрипта. Если это true
, то скрипт будет размещен в футере, если false
, то в хёдере. Если этот параметр
отсутсвует, то скрипт будет помещен в хёдере.
Аналогично подключаем таблицу стилей:
/**
* Enqueue scripts and styles.
*/
function mytheme_scripts() {
wp_register_script('my-script', get_template_directory_uri() . '/assets/js/my-script.js', array(),'1.0',true);
wp_enqueue_script('my-script');
wp_register_style('my-style', get_template_directory_uri() . '/assets/css/my-style.css');
wp_enqueue_style('my-style');
}
add_action( 'wp_enqueue_scripts', 'mytheme_scripts' );
Подробнее здесь.
Подключаем Font Awesome
Подключить иконки Fontawesome можно двумя способами (по крайней мере в моей практике). Первый - скачать неоходимые папки с файлами от разработчика fontawesome.ru,
разместить эти папки на сайте и подключить файл font-awesome.min.css
описанным выше способом.
Второй способ - разместить в файле темы style.css
следующий код:
@import url("https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css");
Я рекомендую второй способ по понятным причинам.
Настраиваем вход для пользователей
Если на сайте предусмотрен вход пользователей, то после корректной регистрации и авторизации WordPress отправляет всех пользователей на стандартную админ-панель. Для администраторов и редакторов сайта это нормально. Но обычных пользователей, которые привыкли к интерфейсу типа Вконтакте, админ-панель WordPress вводит в состояние ступора и ужаса. Если ваш заказчик портала для общения сосвоими клиентами увидит один раз эту админ-панель, то больше видеть её не захочет. Встает вопрос: как после аутентификации напривлять пользователей на другую станицу сайта, а не на админ-панель?
Для этого достаточно в файле темы functions.php
добавить следующую функцию:
add_filter('login_redirect', '_myplugin_lgn_redirect');
function _myplugin_lgn_redirect() {
return '/some-page-on-my-website';
}
Настраиваем вход для пользователей в зависимости от роли
Часто возникает необходимость перенаправлять пользователей после авторизации на разные страницы сайта в зависимости от роли пользователя. Для этого в файл темы functions.php
достаточно добавить функцию:
function my_redirect_users_by_role() {
$current_user = wp_get_current_user();
$role_name = $current_user->roles[0];
if ( 'subscriber' === $role_name ) {
wp_redirect( '//yoursite.com/dashboard' );
} // if
} // my_redirect_users_by_role
add_action( 'admin_init', 'my_redirect_users_by_role' );
А лучше так:
function my_redirect_users_by_role() {
if ( ! defined( 'DOING_AJAX' ) ) {
$current_user = wp_get_current_user();
$role_name = $current_user->roles[0];
if ( 'subscriber' === $role_name ) {
wp_redirect( '//yoursite.com/dashboard' );
} // if $role_name
} // if DOING_AJAX
} // my_redirect_users_by_role
add_action( 'admin_init', 'my_redirect_users_by_role' );
Эти коды заимствованы отсюда.
И хотя авторы предлагают использовать их в специальном плагине, но, оказывается, они работают и при простом размещении в файле functions.php
.
Редирект с произвольной страницы сайта
Иногда возникает задача перенаправлять пользователя с произвольной страницы сайта на другую. Например, я хочу закрыть доступ неаутентифицированным пользователям на страницу account.php
.
Стандартная функция wp-redirect()
для этого не пригодна. Вот такой код работать не будет:
if(!is_user_logged_in()){ wp-redirect('//my_site.com')}
Для этих целей я использую следующий код:
if(!is_user_logged_in()){
<script>document.location.href = '//my_site.com';</script>
}
Подробнее можно прочитать здесь.
Подключаем плагины
Первы плагин, который мы подключали и учились подклчать и активировать плагины, был TablePress
. Нам просто понадобилось сделать красивую
табличку на одной из страниц (О НАС).
Последовательность действий: 1 - скачиваем папку с архивом плагина, например, отсюда https://wordpress.org/plugins/tablepress/
; 2- разархивируем и
содержимое помещаем в папку /wp-content/plagins/
; 3- заходим в раздел "Плагины" в левом меню админ-панели, ищем только-что подгруженный плагин и активируем его.
Псле обновления в левом меню админ-панели появился раздел "TablePress":
Кроме того, что появился раздел "TablePress" в меню админ-панели, при создании или редактирвании постов и страниц появилась новая кнопочка в редакторе:
.Здесь можно вставлять таблицу в текст и её редактировать. Подробнее здесь.
Сайдбары - это контейнеры для вставки виджетов. Они могут быть вставлены в любом месте на сайте (не обязательно сбоку) функцией
?lt;php get_sidebar('[имя сайдбара]'); ?>
Но для того, чтобы это работало, нужно 1 - сначала создать в корне шаблона файл sidebar-[имя сайдбара].php
и вставить в него следующий код:
<?php if ( function_exists ( dynamic_sidebar(4) ) ) : ?>
<?php dynamic_sidebar (4); ?>
<?php endif; ?>
где 4 - это номер сайдбара (по-порядку). Затем 2 - в файле functions.php
добавить описание этого сайдбара:
/** Регистрируем сайдбары */
if ( function_exists('register_sidebar') )
register_sidebar(array(
'before_widget' => '',
'after_widget' => '',
'before_title' => '<h3>',
'after_title' => '</h3>',
));
register_sidebar( array(
'name' => '[имя сайдбара 1]',
) );
register_sidebar( array(
'name' => '[имя сайдбара 2]',
) );
. . .
register_sidebar( array(
'name' => '[имя сайдбара 4]',
) );
Строим страницу постов (index.php)
После вывода хёдера начинаем строить вывод постов. Примерный код страницы index.php
может выглядеть так:
<?php
/**
* The main template file
*/
get_header(); ?>
<div class="wrap">
<?php if ( is_home() && ! is_front_page() ) : ?>
<header class="page-header">
<h1 class="page-title"><?php single_post_title(); ?></h1>
</header>
<?php else : ?>
<header class="page-header">
<h2 class="page-title">
<?php _e( 'Posts' ); ?>
<?php echo "Page title" ?></h2>
</header>
<?php endif; ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php
if ( have_posts() ) :
/* Start the Loop */
while ( have_posts() ) : the_post();
/*
* Include the Post-Format-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Format name) and that will be used instead.
*/
get_template_part( 'template-parts/post/content', get_post_format() );
endwhile;
else :
get_template_part( 'template-parts/post/content', 'none' );
endif;
?>
</main><!-- #main -->
</div><!-- #primary -->
<?php //get_sidebar(); ?>
</div><!-- .wrap -->
<?php get_footer();
Здесь в цикле while
сначала с помощью условного тега have_posts()
проверяем наличие посов для данной страницы в БД. Если посты есть, запускаем цикл их выдачи.
Если посты есть, то они начинают выводиться в цикле while ...
, при этом на каждом витке цикла сначала устанавливается индекс поста с помощью функции
the_post()
(подробнее об этой функции можно прочитать здесь), после чего в нашем случае выполняется функция get_template_part( )
.
Эта функция WP загружает в шаблон часть шаблона, а именно в нашем сучае, файл content.php
, который находится в папке /template-parts/post/
.
В этой части шаблона мы, собственно, задаем то, что именно хотим вывести и делаем html разметку.
Вот примерно так может выглядеть код файла (content.php
):
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php
if ( is_single() ) {
the_title( '<h1 class="entry-title">', '</h1>' );
} elseif ( is_front_page() && is_home() ) {
the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' );
} else {
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
}
?>
</header><!-- .entry-header -->
<?php if ( '' !== get_the_post_thumbnail() && ! is_single() ) : ?>
<div class="post-thumbnail">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail( '...' ); ?>
</a>
</div><!-- .post-thumbnail -->
<?php endif; ?>
<div class="entry-content">
<?php
/* translators: %s: Name of current post */
the_content( sprintf(
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', '...' ),
get_the_title()
) );
wp_link_pages( array(
'before' => '<div class="page-links">' . __( 'Pages:', '...' ),
'after' => '</div>',
'link_before' => '<span class="page-number">',
'link_after' => '</span>',
) );
?>
</div><!-- .entry-content -->
</article><!-- #post-## -->
Условный тег is_home()
определет, находимся ли мы на главной странице?
Здесь следует обратить внимание на то, что такое Главная страница? Главной страницей в WP называется страница,
на которой выводятся посты (записи). А страница, которая выводится первой при обращении к сайту по адресу //my_site
, является страницей
Front_page. Таким образом, на главной странице is_home()==1
, а на первой странице is_front_page()==1
.
Если установить «отображать - Ваши последние записи», то автоматически страница с выводом постов становится и Home, и Front_page. Если мы хотим, как в нашем случае, первой
загружать страницу KIDSFM, то выбираем «отображать - Статическая страница» и выбираем, какая страница будег Front, а какая Home. Как показано на рисунке,
у нас первой будет загружаться KIDSFM, а записи (посты) будут выводиться на странице ЛЕНТА
Теперь разберём, что такое sticky
? Оказывается, можно «прилепить» запись на странице home, тогда
эта запись будет отображаться в верхней части страницы записей, а новые записи будут отображаться ниже. Естественно, для такой прилепленной записи имеет смысл
оформить стили, отличные от текущих записей. В нашем случае мы для этого и используем шаблон /template-parts/sticky.php
.
Навигация по записям на index.php
Так как постов (записей) может быть очень много, то нам нужно выводить определенное их количество и иметь возможность выводить следующее количество и так далее - то, что мы называем навигацией по записям
Для этого добавим в файле index.php
функцию the_posts_pagination()
:
<?php
if ( have_posts() ) :
/* Start the Loop */
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/post/content', get_post_format() );
endwhile;
the_posts_pagination( array(
'prev_text' => '<i class="fa fa-arrow-left"></i>' . '<span class="screen-reader-text">' . 'предыдущая страница' . '</span>',
'next_text' => '<span class="screen-reader-text">' . 'следущая страница' . '</span>' . '<i class="fa fa-arrow-right"></i>',
'before_page_number' => '<span class="meta-nav screen-reader-text">' . 'Страница' . ' </span>',
) );
else :
get_template_part( 'template-parts/post/content', 'none' );
endif;
?>
Сколько постов выводить - настроим в админке: Настройки -> Чтение
Теперь на странице постов выводятся первые четыре поста и строка навигации:
Если кликнуть по цифре 2
в строке навигации, то будут выданы следующие четыре поста:
Навигация по записям на произвольной странице
Если нам требуется выводить посты на произвольной странице, например, на статической главной странице, то описанные выше коды не будут работать, так как функция the_post()
не определит наличие записей для этой страницы.
В этом случае требуются следующие коды
<?php
// 1 значение по умолчанию
//$paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1; // Вариант для не статической страницы
$paged = (get_query_var('page')) ? get_query_var('page') : 1; // Вариант для статической страницы
//echo "Мы на странице:". $page ." на главной странице блога, указанной как статическая.";
$the_query = new WP_Query( array(
'posts_per_page' => 4,
//'category_name' => 'artist',
'post_type' => 'post',
'paged' => $paged,
) );
// цикл вывода полученных записей
while( $the_query->have_posts() ){
$the_query->the_post();
?>
<!-- HTML каждой записи -->
<?php
} ?>
<?
wp_reset_postdata();
// пагинация для произвольного запроса
$big = 999999999; // уникальное число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
// 'current' => max( 1, get_query_var('paged') ), //вариант для не статической страницы
'current' => max( 1, get_query_var('page') ), // Вариант для статической страницы
'total' => $the_query->max_num_pages
) );
?>
Делаем Шаблон страницы
Итак, нам понадобилась страница, для которой не подходят базовые шаблоны В WP существует возможность создания собственных шаблонов. Пусть страница называется, например, РАДИОВЕДУЩИЕ.
Для этой страницы мы делаем свой шаблон. Для этого создаём в корне темы файл presenters.php
, заходим в админ панели на редактирование
этой страницы и видим, что справа в разделе Атрибуты -> Шаблоны
появился выбор шаблона Presenters
.
Его и выбираем!
Далее в страницу presenters.php
вставляем код, который будет выводить посты из категории (рубрики) ведущие
.
Это стандартный код вывода постов, но вначале добавляем условие того, что выводятся посты только данной рубрики:
<?php
if (is_page('93') ) {
$cat = array(16);
} elseif ( is_page('16') ) {
$cat = array(32);
} elseif ( is_page('28') ) {
$cat = array(17);
} else {
$cat = '';
}
$showposts = -1; // -1 shows all posts
$do_not_show_stickies = 1; // 0 to show stickies
$args=array(
'category__in' => $cat,
'showposts' => $showposts,
'caller_get_posts' => $do_not_show_stickies
);
$my_query = new WP_Query($args);
?>
Здесь 93
- ID страницы РАДИОВЕДУЩИЕ
, а 16
- ID рубрики Ведущие
.
Как видим один шаблон можно использовать для разных страниц и выводить на них разные посты.
Делаем форму (технология NONCE)
В WordPress предусмотрен механизм защиты формы от хакерской попытки использования формы. Форма должна выглядеть примерно так:
<form id="add_location_1" method="post" action="<?=DESTINATION_URL ?>" enctype="multipart/form-data" >
<?php wp_nonce_field( 'key','name_of_nonce' ); ?>
[ таблица формы ]
<input type="submit" class="btn btn-primary" value="<?php _e('Сохранить', 'admin'); ?>" />
</form>
Функция wp_nonce_field( 'key','name_of_nonce' )
вставит в HTML код две строки:
<input type="hidden" id="name_of_nonce" name="name_of_nonce" value="421df8a5ea">
<input type="hidden" name="_wp_http_referer" value="/permalink">
Таким образом, вместе с другими данными форма отправит еще две константы, а именно: сгенерированное на основе key
уникальное сочетание знаков (в нашем случае - 421df8a5ea),
которое при приеме данных можно получить, используя имя name="name_of_nonce"
, а именно: $_POST['name_of_nonce']
,
а также адрес страницы, на которой находится форма, то есть откуда передаются данные. При приеме данных этот адрес также можно получить, а именно:
$_POST['_wp_http_referer']
.
При приеме данных нужно убедиться, что они отправленны именно из формы на странице нашего сайта. Для этого следует написать такой код:
if ( isset( $_POST['name_of_nonce'] )
&& wp_verify_nonce( $_POST['name_of_nonce'], 'key' )
)
{
echo "Проверка пройдена. Поздравляем!";
} else {
echo "Проверка не пройдена. Загружать данные опасно!";
}
Исключение рубрики из HOME.page
После того, как мы начали делать записи в рубрике ведущие
оказалось, что эти записи появляются как посты на страницк ЛЕНТЫ, то есть на странице home
, но нам этого не нужно.
Вста вопрос, как исключить показ постов из этой рубрики на странице home
.
Один вариант, который мы нашли - вставить в файл functions.php
следующий код:
/**
* Исключаем категорию с ID=33 из показа в ленте
*
*/
function exclude_category($query) {
if ( $query->is_page ) {
$query->set('category__not_in', array(33));}
return $query;
}
add_filter('pre_get_posts', 'exclude_category');
Но это, как ни странно - не помогло. А помогло вот что: в файле index.php
перед строкой
<?php if ( have_posts() ) : ?>
нужно вставить строку, чтобы получилось вот так:
<?php if (is_home()) { query_posts('cat=-33'); } ?>
<?php if ( have_posts() ) : ?>
Добавляем и/или редактируем роли
Теперь нам потребовалось ведущим делегировать определенные права, то есть создать новую роль - "Ведущий".
В WP предусмотрены базовые роли:
Что в русскоязычном варианте WP выглядит как:
Данные о ролях и их правах хранятся в БД в таблице wp_options
в записи с option_name
= wp_user_roles
в поле option_value
в виде следующей строки:
a:6:{s:13:"administrator";a:2:{s:4:"name";s:13:"Administrator";s:12:"capabilities";a:93:{s:13:"switch_themes";b:1;s:11:"edit_themes";b:1;s:16:"activate_plugins";b:1;s:12:"edit_plugins";b:1;s:10:"edit_users";b:1;s:10:"edit_files";b:1;s:14:"manage_options";b:1;s:17:"moderate_comments";b:1;s:17:"manage_categories";b:1;s:12:"manage_links";b:1;s:12:"upload_files";b:1;s:6:"import";b:1;s:15:"unfiltered_html";b:1;s:10:"edit_posts";b:1;s:17:"edit_others_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:10:"edit_pages";b:1;s:4:"read";b:1;s:8:"level_10";b:1;s:7:"level_9";b:1;s:7:"level_8";b:1;s:7:"level_7";b:1;s:7:"level_6";b:1;s:7:"level_5";b:1;s:7:"level_4";b:1;s:7:"level_3";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:17:"edit_others_pages";b:1;s:20:"edit_published_pages";b:1;s:13:"publish_pages";b:1;s:12:"delete_pages";b:1;s:19:"delete_others_pages";b:1;s:22:"delete_published_pages";b:1;s:12:"delete_posts";b:1;s:19:"delete_others_posts";b:1;s:22:"delete_published_posts";b:1;s:20:"delete_private_posts";b:1;s:18:"edit_private_posts";b:1;s:18:"read_private_posts";b:1;s:20:"delete_private_pages";b:1;s:18:"edit_private_pages";b:1;s:18:"read_private_pages";b:1;s:12:"delete_users";b:1;s:12:"create_users";b:1;s:17:"unfiltered_upload";b:1;s:14:"edit_dashboard";b:1;s:14:"update_plugins";b:1;s:14:"delete_plugins";b:1;s:15:"install_plugins";b:1;s:13:"update_themes";b:1;s:14:"install_themes";b:1;s:11:"update_core";b:1;s:10:"list_users";b:1;s:12:"remove_users";b:1;s:13:"promote_users";b:1;s:18:"edit_theme_options";b:1;s:13:"delete_themes";b:1;s:6:"export";b:1;s:22:"tablepress_edit_tables";b:1;s:24:"tablepress_delete_tables";b:1;s:22:"tablepress_list_tables";b:1;s:21:"tablepress_add_tables";b:1;s:22:"tablepress_copy_tables";b:1;s:24:"tablepress_import_tables";b:1;s:24:"tablepress_export_tables";b:1;s:32:"tablepress_access_options_screen";b:1;s:30:"tablepress_access_about_screen";b:1;s:29:"tablepress_import_tables_wptr";b:1;s:23:"tablepress_edit_options";b:1;s:24:"NextGEN Gallery overview";b:1;s:19:"NextGEN Use TinyMCE";b:1;s:21:"NextGEN Upload images";b:1;s:22:"NextGEN Manage gallery";b:1;s:19:"NextGEN Manage tags";b:1;s:29:"NextGEN Manage others gallery";b:1;s:18:"NextGEN Edit album";b:1;s:20:"NextGEN Change style";b:1;s:22:"NextGEN Change options";b:1;s:24:"NextGEN Attach Interface";b:1;s:14:"ure_edit_roles";b:1;s:16:"ure_create_roles";b:1;s:16:"ure_delete_roles";b:1;s:23:"ure_create_capabilities";b:1;s:23:"ure_delete_capabilities";b:1;s:18:"ure_manage_options";b:1;s:15:"ure_reset_roles";b:1;s:22:"edit_tablepress_tables";b:1;s:29:"edit_others_tablepress_tables";b:1;s:25:"publish_tablepress_tables";b:1;s:30:"read_private_tablepress_tables";b:1;}}s:6:"author";a:2:{s:4:"name";s:6:"Author";s:12:"capabilities";a:20:{s:12:"upload_files";b:1;s:10:"edit_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:4:"read";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:12:"delete_posts";b:1;s:22:"delete_published_posts";b:1;s:22:"tablepress_edit_tables";b:1;s:24:"tablepress_delete_tables";b:1;s:22:"tablepress_list_tables";b:1;s:21:"tablepress_add_tables";b:1;s:22:"tablepress_copy_tables";b:1;s:24:"tablepress_import_tables";b:1;s:24:"tablepress_export_tables";b:1;s:32:"tablepress_access_options_screen";b:1;s:30:"tablepress_access_about_screen";b:1;s:19:"moderate_quick_chat";b:1;}}s:11:"contributor";a:2:{s:4:"name";s:11:"Contributor";s:12:"capabilities";a:5:{s:12:"delete_posts";b:1;s:10:"edit_posts";b:1;s:7:"level_0";b:1;s:7:"level_1";b:1;s:4:"read";b:1;}}s:6:"editor";a:2:{s:4:"name";s:6:"Editor";s:12:"capabilities";a:44:{s:17:"moderate_comments";b:1;s:17:"manage_categories";b:1;s:12:"manage_links";b:1;s:12:"upload_files";b:1;s:15:"unfiltered_html";b:1;s:10:"edit_posts";b:1;s:17:"edit_others_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:10:"edit_pages";b:1;s:4:"read";b:1;s:7:"level_7";b:1;s:7:"level_6";b:1;s:7:"level_5";b:1;s:7:"level_4";b:1;s:7:"level_3";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:17:"edit_others_pages";b:1;s:20:"edit_published_pages";b:1;s:13:"publish_pages";b:1;s:12:"delete_pages";b:1;s:19:"delete_others_pages";b:1;s:22:"delete_published_pages";b:1;s:12:"delete_posts";b:1;s:19:"delete_others_posts";b:1;s:22:"delete_published_posts";b:1;s:20:"delete_private_posts";b:1;s:18:"edit_private_posts";b:1;s:18:"read_private_posts";b:1;s:20:"delete_private_pages";b:1;s:18:"edit_private_pages";b:1;s:18:"read_private_pages";b:1;s:22:"tablepress_edit_tables";b:1;s:24:"tablepress_delete_tables";b:1;s:22:"tablepress_list_tables";b:1;s:21:"tablepress_add_tables";b:1;s:22:"tablepress_copy_tables";b:1;s:24:"tablepress_import_tables";b:1;s:24:"tablepress_export_tables";b:1;s:32:"tablepress_access_options_screen";b:1;s:30:"tablepress_access_about_screen";b:1;s:19:"moderate_quick_chat";b:1;}}s:10:"subscriber";a:2:{s:4:"name";s:10:"Subscriber";s:12:"capabilities";a:3:{s:4:"read";b:1;s:7:"level_0";b:1;s:19:"moderate_quick_chat";b:1;}}}
Это текстовая строка в специальном формате, в котором WP хранит данные о массивах и их элементах. Подробнее об этом фрмате
можно посмотреть здесь.
Как английские наименования превращаются в русские - изучим позже, когда будем разбираться с локализацией. А сейчас займёмся созданием новой роли.
Конечно, можно попробовать просто в эту строку в БД вписать тупо новую роль, но мы хотим, чтобы администратор мог это делать из панели администратора,
поэтому мы подключили новый плагин - User Role Editor
.
У этого плагина, как оказалось,
много возможностей и работает он хорошо, но смущает то, что в БД он прописывает странную длину строки наименования роли, если она написана кириллицей, например:
s:14:"Ведущий"
. То есть, длина строки 14 символов, хотя в слове "Ведущий" их 7! Подозревая, что это может отобразиться на корректности работы функций WP, которые
работают с ролями, будем поступать так: писать наименования латиницей, а потом
займемся локализацией WP и будем ручками добавлять наименование роли на русском или другом языке.
Вход на сайт - редактируем
После залогинивания (входа) пользователя, WP выводит его на админ-панель, что очень плохо для нормального сайта, а не блога!
Поэтому стоит задача, выводить пользователя на нужную страницу сайта в зависимости от его роли.
После тестирования разных вариантов, оказалось, что нормально работает код, описанный в WP Codex
, который нужно вставить в functions.php
файл темы:
Если вам нужно, чтобы пользователи могли входить на сайт через свои аккаунты в социальных сетях, то этот плагин именно то, что вам нужно.
Загрузить этот плагин можно непосредственно из админ-панели: Плагины -> Добавить плагин
, затем в поиске ввести Social Login. После установки плагина - активировать его обычным образом.
Теперь в меню админ-панели появляется кнопка плагина:
Наводим курсор и кликаем Setup
:
Открывается страница настроек, содержащая несколько разделов. Оставляем все настройки по умолчанию. Но! В разделе API Settings
необходимо заполнить три поля.
Чтобы получить данные для этих полей, необходимо зарегистрироваться на сайте разработчика. Перейти на этот сайт можно непосредственно из админки, кликнув на ссылку
Click here to create and view your API Credentials
.
Зарегистрируйтесь на этом сайте. В личном кабинете найдите, где привязать свой сайт и получите для него значения API Subdomain
, API Public Key
, API Private Key
.
Скопируйте эти значения и вставьте в соответствующие поля формы в админке вашего сайта, показанные на рисунке выше.
Verify API Settings
Опускаемся ниже в раздел Enable the social networks/identity providers of your choice
. . .
Ставим галочки в чек-боксах тех сетей, которые мы хотим подключить, например: VK, Одноклассники, Twitter, Facebook и Instagram
Save Chandes
Теперь наша форма входа на сайт выглядит так:
Покажем на примере FB
Заходим в кабинет на OneAll -> Sites -> Socisl Networks
и кликаем на кнопку FB.
Перед нами первая страница инструкции. Кликаем на кнопку Facebook
Перед нами первая страница инструкции из шести. Нам советуют перейти на страницу нашего приложения в FB (или создать новое) по адресу https://developers.facebook.com/apps. что мы и делаем.
Кликаем на + Добавить новое приложение
Всплывает форма:
Возвращаемся в OneAll и переходим ко второй странице инструкции. Здесь нам подсказывают, какие мы должны использовать Отображаемое название (Display Name) и Эл. адрес для связи (Contact Email). Именно эти значения мы и прописываем в форме нашего приложения на FB:
Далее продолжаем строго выполнять рекомендации инструкции и в конце - на 6-странице - вставляем в форму данные из приложения в FB:
А именно: Идентификатор приложения и Секрет приложения.
Залогинивание через Twitter
Enable Callback Locking (It is recommended to enable callback locking to ensure apps cannot overwrite the callback url)
.
Privacy Policy и Terms of Service
Некоторые соц. сети требуют, чтобы разработчик при создании приложения указал адреса страниц Privacy Policy
и Terms of Service
. При использовании плагина
OneAll в качестве страницы Privacy Policy (эта страница определяют политику разработчика в отношении персональных (личных) и других данных пользователей приложения, которые разработчик получает в процессе использования приложения)
можно указать адрес https://www.oneall.com/company/privacy-policy/
или сделать собственную. Страницу Terms of Service (смысл Terms of Service заключается, прежде всего, в том, чтобы дать пользователям понять, что можно делать в отношении приложения, а чего – нельзя) придется делать самому.
Подробнее об этом можно прочесть здесь.
Залогинивание через Instagram
Здесь есть своя неприятность. Логиниться через Инстаграм могут только пользователи, которых вы пригласили в инстаграме в свою "песочницу". Чтобы предоставить возможность логиниться всем пользователям, имеющим аккаунт в Инстграме, нужно подать запрос на ревизию вашего приложения. При заполнении формы на ревизию, ко всему прочему, вас просят ввести ссылку на видео инструкцию, в которой вы разъясняете пользователям, как они могут использовать ваше приложение . . . вот такая заморочка.
Плагин User Role Editor
Убираем бокс, позволяющий редакторам изменять ник в процессе чата, то есть писать сообщения под другим ником:
Плагин Quick Chat
Убираем бокс, позволяющий редакторам изменять ник в процессе чата, то есть писать сообщения под другим ником:
Для этого в админке в настройках чата убираем галочку:
При этом у тех пользователей,которым мы дали права модерировать чат остается возможность менять ник.
Теперь убираем дату и время в чате.
<div class="quick-chat-history-timestring">'+
a.timestring+'</div>
в файле quick-chat/js/quick-chat-core.js
После подключения плагина регистрации в ВК обнаружилась проблема - в качестве имени участника чата плагин использует
логин, что плохо! Нужно сделать так, чтобы высвечивалось Имя Фамилия. Делаем.
В файле плагина /wp-content/plugins/quick-chat/quick-chat.php
изменяем два куска кода:
global $current_user;
get_currentuserinfo();
if(isset($_COOKIE['quick_chat_alias_'.$current_user->ID])){
$this->user_name = stripslashes($_COOKIE['quick_chat_alias_'.$current_user->ID]);
} else{
setcookie('quick_chat_alias_'.$current_user->ID, $current_user->user_login, 0, COOKIEPATH, COOKIE_DOMAIN);
$this->user_name = $current_user->user_login;
}
. . . . .
if($username_bad_words == 0 && (!is_user_logged_in() || (is_user_logged_in() && strcasecmp($_POST['username_check'], $current_user->user_login) != 0))){
Меняем на:
global $current_user;
get_currentuserinfo();
$chat_name = $current_user->first_name.' '.$current_user->last_name;
if(isset($_COOKIE['quick_chat_alias_'.$current_user->ID])){
$this->user_name = stripslashes($_COOKIE['quick_chat_alias_'.$current_user->ID]);
} else{
setcookie('quick_chat_alias_'.$current_user->ID, $chat_name, 0, COOKIEPATH, COOKIE_DOMAIN);
$this->user_name = $chat_name;
}
. . . . .
if($username_bad_words == 0 && (!is_user_logged_in() || (is_user_logged_in() && strcasecmp($_POST['username_check'], $chat_name) != 0))){
Пользователи должны почистить куки!!!
Изменяем интервал времени отключения пользователя за неактивность. Дело в том, что плагин удаляет окно чата, если пользователь не участвует какое-то время
в переписке. Нам понадобилось вывести чат ведущим, но при этом они не долны в нем участвовать по определению. Чтобы чат не отключался - просто увеличим время отклчения.
Для этого в файле wp-content/plugins/quick-chat/js/quick-chat-core.js
находим строчку
quick_chat.users_interval&&(quick_chat.users_interval=setInterval(function(){quick_chat.update_users()},1E3*quick_chat.timeout_refresh_users));
и меняем 1E3
на 1E6
, например. Или поступаем проще: идем в админку и в настройках Quick Chat изменяем параметр в соответствующем блоке:
Плагин TablePress
Кроме того, что появился раздел "TablePress" в меню админ-панели, при создании или редактирвании постов и страниц появилась новая кнопочка в редакторе:
.Здесь можно вставлять таблицу в текст и её редактировать. Вот пример такой таблицы (как она выглядит):
Плагин Meta Slider
Мы протестировали несколько плагинов для создания слайдеров. а именно: banner-slider
, len-slider
,ml-slider
.
Первые два забраковали, а Мета слайдер вполне подошёл: простые настройки, наличие шорт-кода, возможность устанавливать лбые размеры и
прочее - очень простой и вполне достаточен. Можно создавать несколько слайдеров и вставлять как в постах и страницах, так и в сайд-барах с помощьюсоответствующего виждета.
Вот пример php-кода, который мыиспользовали для вставки двух баннеров на страницах:
<?php if(is_page(70) OR is_page('РАДИОВЕДУЩИЕ') ) {
?>
<div id="top-advertising" class="hidden-sm hidden-xs">
<div class="container" style="position: relative;">
<div class="row">
<div class="col-md-12">
<?php echo do_shortcode("[metaslider id=344]"); ?>
</div>
</div>
</div>
</div>
<?php } else {?>
<div id="top-advertising" class="hidden-sm hidden-xs">
<div class="container" style="position: relative;">
<div class="row">
<div class="col-md-12">
<?php echo do_shortcode("[metaslider id=348]"); ?>
</div>
</div>
</div>
</div>
<?php } ?>
<!-- Top Banner -->
При создании слайд-баннера ему автоматически присваивается ID, который видно в настройках Meta Slider в разделе "Использование" - там приводится как шорт-код, так и php-код для вставки в шаблон.
Плагин Full Width Background Slider
Этот слайдер создает изменяющийся бэкграунд страницы. Смотрится привлекательно. При его активации в редактировании страниц и постов появляется новая настройка
и можно выбрать - показывать его на данной странице - или нет.
index.php
. Чтобы не показывать его
на этой странице мы вставили в коде этой страницы перед подключением футера (именно в футере этот плагин подключает скрипт и ссылки на картинки для баннера)
написали следующий стиль для блока с картинками:
. . .
<style type="text/css" media="screen">
<!--
#fwbslider{display:none !important;}
-->
<!--
a.fwb_fromthis {display:none !important;}
-->
</style>
<?php get_footer(); ?>
. . .
page.php
следующий стиль для этого логатипа:
. . .
<style type="text/css" media="screen">
<!--
a.fwb_fromthis {display:none !important;}
-->
</style>
<?php get_footer(); ?>
. . .
Плагин NextGEN Gallery
CRUD (Create, Read, Update, Delete)
Эти функции работы с БД в Wordpress подробно описаны здесь
Cтруктура строки массивов
Массивы и их значения хранятся в БД в виде строк специального формата, например:
a:5:{s:13:"administrator";a:2:{s:4:"name";s:13:"Administrator";s:12:"capabilities";a:93:{s:13:"switch_themes";b:1;s:11:"edit_themes";b:1;s:16:"activate_plugins";b:1;. . .
Разберем, что мы видим:
Такая строка получается из массива с помощью php-функции serialize()
. Например, из массива $new_role_array
:
$new_role_array = Array ( 'editor' => 1, 'shop' => 0 );
$new_role_string = serialize($new_role_array);
echo $new_role_string;
получаем строку $new_role_string
:
a:2:{s:6:"editor";i:1;s:4:"shop";i:0;}
Разберём шаблон twentysixteen
Первым загружается файл index.php
. Вот его код:
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
*
* @link //codex.wordpress.org/Template_Hierarchy
*
* @package WordPress
* @subpackage Twenty_Sixteen
* @since Twenty Sixteen 1.0
*/
get_header(); ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php if ( have_posts() ) : ?>
<?php if ( is_home() && ! is_front_page() ) : ?>
<header>
<h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>
</header>
<?php endif; ?>
<?php
// Start the loop.
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content', get_post_format() );
// End the loop.
endwhile;
// Previous/next page navigation.
the_posts_pagination( array(
'prev_text' => __( 'Previous page', 'twentysixteen' ),
'next_text' => __( 'Next page', 'twentysixteen' ),
'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>',
) );
// If no content, include the "No posts found" template.
else :
get_template_part( 'template-parts/content', 'none' );
endif;
?>
</main><!-- .site-main -->
</div><!-- .content-area -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
В этом коде вызываются 9 функций, а именно:
# | Имя фунции | Source File | Описание |
---|---|---|---|
1 | get_header() | wp-includes/general-template.php. | the header.php template file from your current theme's directory. If a name is specified then a specialised header header-{name}.php will be included. If the theme contains no header.php file then the header from the default theme wp-includes/theme-compat/header.php will be included. |
2 | have_posts() | wp-includes/query.php | This function checks to see if the current WordPress query has any results to loop over. This is a boolean function, meaning it returns either TRUE or FALSE.. |
3 | single_post_title() | wp-includes/general-template.php | Display or retrieve page title for post. This is optimized for single.php template file for displaying the post title. It does not support placing the separator after the title, but by leaving the prefix parameter empty, you can set the title separator manually. The prefix does not automatically place a space between the prefix, so if there should be a space, the parameter value will need to have it at the end.. |
4 | the_post() | wp-includes/query.php. | Iterate the post index in The Loop. Retrieves the next post, sets up the post, sets the 'in the loop' property to true. |
5 | get_template_part | wp-includes/general-template.php | Load a template part into a template Makes it easy for a theme to reuse sections of code in a easy to overload way for child themes. Includes the named template part for a theme or if a name is specified then a specialised part will be included. If the theme contains no {slug}.php file then no template will be included. The template is included using require, not require_once, so you may include the same template part multiple times. For the $name parameter, if the file is called “{slug}-special.php” then specify “special”.. |
6 | get_post_format() | wp-includes/post-formats.php | Retrieve the format slug for a post |
7 | the_posts_pagination | wp-includes/link-template.php | Display a paginated navigation to next/previous set of posts, when applicable. |
8 | get_sidebar() | wp-includes/general-template.php | Load sidebar template. Includes the sidebar template for a theme or if a name is specified then a specialised sidebar will be included. For the parameter, if the file is called “sidebar-special.php” then specify “special”. |
9 | get_footer() | wp-includes/general-template.php | the footer.php template file from your current theme's directory. if a name is specified then a specialised footer footer-{name}.php will be included. If the theme contains no footer.php file then the footer from the default theme wp-includes/theme-compat/footer.php will be included. |
Первая функция get_header()
вставляет файл header.php
из нашего шаблона. Как он должен выглядеть?
Посмотрим, например, хёдер из шаблона Twentysixteen
:
<?php
/**
* The template for displaying the header
*
* Displays all of the head element and everything up until the "site-content" div.
*
* @package WordPress
* @subpackage Twenty_Sixteen
* @since Twenty Sixteen 1.0
*/
?><!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="//gmpg.org/xfn/11">
<?php if ( is_singular() && pings_open( get_queried_object() ) ) : ?>
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<?php endif; ?>
<?php wp_head();?>
</head>