Секреты тонкой настройки WordPress

Я работаю с WordPress с незапамятных времен, и, хотя я изучил множество исходных кодов этой CMS, все равно постоянно нахожу новые секреты и тонкости. Я составил список из 21 улучшения, который может помочь в оптимизации WordPress. Надеюсь, что каждый найдет для себя что-то новое в этой статье!

Секреты тонкой настройки WordPress

1. WordPress имеет множество встроенных скриптов

Используя замечательные функции wp_enqueue_script() и wp_enqueue_style(), вы можете легко подключать собственные стили и скрипты, а также управлять ими. Но знали ли вы, что WordPress имеет в своем составе немало уже готовых к использованию скриптов? jQuery, его формы и элементы интерфейса, SWF-объекты, Tiny MCE, Jcrop и Thickbox это наиболее известные названия, помимо многих других. Полный список можно увидеть на сайте WordPress Codex.

2. Замена встроенных скриптов путем отмены их регистрации

Возможно, вы захотите использовать свои версии скриптов вместо встроенных системных. Примером этого может служить необходимость использования более новой версии jQuery, чем уже установлена в качестве системной. Это может быть сделано следующим способом:

function my_scripts_method() { 
  wp_deregister_script( 'jquery' ); //отменяем регистрацию системного скрипта jQuery 
  wp_register_script( 'jquery', get_template_directory_uri() . '/js/jquery-new.js'); // регистрируем обновленную версию скрипта
  wp_enqueue_script( 'jquery' ); // и ставим его в очередь
  }
add_action('wp_enqueue_scripts', 'my_scripts_method'); // вешаем хук

Но не делайте этого, только чтобы похвастаться новыми умениями. Как правило, WordPress включает новейшую версию jQuery, которая максимально совместима с CMS и не вызывает сбоев в работе.

Используйте другие версии jQuery только когда у вас возникают проблемы с совместимостью, либо в случае, если определенный плагин требует этого.

3. Принудительное улучшение качества JPG-изображений

Мой хороший друг Ларс рассказал мне, что WordPress не использует вывод изображений на сайте со 100% качеством, чтобы экономить дисковое пространство и полосу пропускания. Он также показал мне решение этой проблемы:

add_filter( 'jpeg_quality', 'smashing_jpeg_quality' ); //добавляем фильтр
function smashing_jpeg_quality() { return 100; } // определяем максимальное качество

По умолчанию WordPress выводит изображения в качестве лишь 90%. Во многих случаях это хорошо — сомневаюсь, что многие ощутят разницу. Но если наличие на вашем сайте изображений в наилучшем качестве необходимо (например, для портфолио), то изменение этого параметра очень актуально.

4. Перенаправление на RSS-сервис FeedBurner

FeedBurner используется почти в каждом блоге, с которым я работал. И я не знаю лучшего сервиса для расширения RSS-функций вашего сайта. Выражаю благодарность Elio за написанную им статью «10 Tips to Optimize Your WordPress Theme», которая содержит следующий код:

add_action( 'template_redirect' , 'smashing_rss_redirect');
function smashing_rss_redirect() { 	
	if ( is_feed() AND !preg_match( '/feedburner|feedvalidator/i', $_SERVER['HTTP_USER_AGENT']) ){ 		
	header( 'Location: http://feeds.feedburner.com/my_smashing_feed' ); 		header( 'HTTP/1.1 302 Temporary Redirect' ); 	
} 
}

Данный код позволяет заменить ссылку вашего сайта (например, http://mysite.com/feed) на ссылку непосредственно на сервис FeedBurner: http://feeds.feedburner.com/mysite.

5. Использование общих таксономических функций

Множество таксономических функций поможет вам создать собственные таксономии. Также можно воспользоваться встроенными тегами и категориями. Перейдя по ссылке на WordPress Codex можно увидеть полный список таксономических функций. Я использую функции get_term(), get_terms() и wp_get_object_terms(). Чтобы максимально структурировать свой сайт, я максимально полно использую данные функции, даже для тегов и категорий.

6. Настройка сессий в WordPress

Механизм сессий помогает сохранять информацию о предыдущих действиях пользователя и его настройках. Он широко используется на многих веб-сайтах. В WordPress сессии по умолчанию отключены. Используя следующий метод, вы можете открыть сессию для использования на всех страницах своего сайта.

add_action( 'init', 'smashing_session_start' ); // вешаем хук
function smashing_session_start() { 
	if ( !session_id() ) { // если сессия еще не существует, то начинаем её
		session_start(); 
	}
}

Механизм сессий достаточно безопасен, если вы не передаете конфиденциальных данных.

7. Список всех функций-хуков

Я начал писать такую функцию. Но когда я воспользовался поиском в Google, то нашел то, что мне было нужно:

function list_hooked_functions($tag=false){
	global $wp_filter;
	if ($tag) {
		$hook[$tag]=$wp_filter[$tag];
		if (!is_array($hook[$tag])) {
			trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
			return;
		}
	}
	else {
		$hook=$wp_filter;
		ksort($hook);
	}
	
	echo '<pre>';
	
	foreach($hook as $tag => $priority){
		echo "<br />&gt;&gt;&gt;&gt;&gt;t<strong>$tag</strong><br />";
		ksort($priority);
		foreach($priority as $priority => $function){
			echo $priority;
			foreach($function as $name => $properties) {
				echo "t$name<br />";
			}
		}
	}
	echo '</pre>';
	return;
}

Используя эту функцию без аргументов, вы получите список всех функций-хуков. Но так, как этот список может быть достаточно большим, то вы можете его сузить, указав конкретное имя функции. Этот прием можно использовать при отладке или настройке свойств хуков. Очень полезно знать, что и в каком порядке вы повесили, например, на функцию wp_head(). И данная функция в этом случае просто незаменима!

8. Автоматическое добавление параграфа к любому элементу

WordPress делает это автоматически для контента, но нет причин не использовать эту возможность в других случаях. Функция, которая отвечает за добавление параграфов, называется wpautop().

$my_text = 'Welcome! Smashing Magazine is a great place to learn new things. I hope you’re having a nice time!'; 
echo wpautop( $my_text );

Иногда вам потребуется отключить использование данного фильтра по умолчанию. Тогда вам нужно будет отключить его следующим образом:

remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );

9. Рассылка электронных писем с помощью WordPress

Недавно я публиковал свою статью «Creating Perfect Emails for Your WordPress Website», в которой был приведен пример использования функций wp_mail(). Эта группа функций позволяет вам использовать встроенные в WordPress возможности отправки электронных сообщений пользователям.

$message = 'Hello, thanks for reading my post! I hope to see you back soon.'; // наше сообщение
wp_mail( 'someonesemail@example.com', 'Thanks for reading my post!', $message); // отсылаем нашу строку сообщения адресату

Вы также можете отсылать HTML-содержимое, используя фильтр:

add_filter ("wp_mail_content_type", "smashing_mail_content_type"); // добавляем фильтр
function smashing_mail_content_type() { // функция, возвращающая тип содержимого
	return "text/html";
}

10. Встроенная пагинация

Шесть месяцев назад, для меня стало сюрпризом, что можно обойтись без использования сторонних плагинов и, используя стандартные средства, реализовывать пагинацию (т.е. разбиение на страницы). Встроенная функция paginate_links() позволяет постранично разбивать любой тип содержимого.

// Пагинация для циклов WordPress 
$list = new WP_Query( $query_args ); // получение списка элементов
$pagination = array( // массив для хранения элементов
'base'       => str_replace( 99999, '%#%', get_pagenum_link( 99999 ) ),
'format'     => '?paged=%#%', 
'current'    => max( 1, get_query_var( 'paged' ) ),
'total'      => $list->max_num_pages, 
'next_text'  => 'next',
'prev_text'  => 'previous'
);
echo '<div class="pagination primary-links">' . paginate_links( $pagination ) . '</div>'; // вывод на экран

// Пагинация для любого элемента
$list = range(1, 100); // список элементов
$items_per_page = 12; // элементов на странице
$pagination = array( // массив для хранения элементов
'base'       => get_bloginfo( 'url' ) . '/mypage/%_%', 
'format'     => '?paged=%#%',
'current'    => $_GET['current_page'],
'total'      => ceil( max($list) / $items_per_page ), 
'next_text'  => 'go forth', 
'prev_text'  => 'go back'
);
echo '<div class="pagination primary-links">' . paginate_links( $pagination ) . '</div>'; // вывод на экран

11. Простой способ загрузки файлов

В WordPress есть множество различных функций для загрузки. Наиболее простой функцией является wp_upload_bits(), которая загружает файл с указанным содержимым в папку с загрузками:

$upload = wp_upload_bits( $_FILES['myfile']['name'], null, file_get_contents( $_FILES['myfile']['tmp_name'] ) ); // функция загружает указанный в параметрах файл и возвращает в переменную $upload массив с информацией об этом файле
echo 'Well uploaded! The path to this file is ' . $upload['file'] . ' and the url to this file is ' . $upload['url']; // вывод сообщения об успешной загрузке

12. Отображение времени в стиле Twitter

Другой момент истины для меня наступил (учитывая, что я использую WordPress еще с версии 1.5), когда я узнал, что стандартными средствами CMS можно отображать относительное время в человеко-понятном формате, например «5 минут назад» или «один месяц назад», использовав функцию human_timed_diff():

$diff = human_time_diff( '2012-05-05 12:05:00', '2012-05-05 12:10:00' ); // указываем промежуток времени
echo "This comment was submitted ' . $diff . 'ago';  // вывод строки: «Этот комментарий был оставлен 5 минут назад»

13. Вход от имени любого пользователя

Если вы создаете сложный сайт с достаточно большим персоналом, и имеете надобность оперативно переключаться между их аккаунтами, то вам это может быть полезно. Функция wp_set_auth_cookie() позволяет вам входить под именем пользователя, используя номер ID.

$user_id = 4; // выбор id
wp_set_auth_cookie( $user_id ); // выбор  cookie-файла пользователя

Будьте осторожны при использовании этой функции. Если не вернуть значение в исходное, то каждый пользователь, который будет входить, будет попадать на панель управления пользователя с id=4. Даже во время тестирования, я делаю привязку к своему IP или даже специальной URL-строке для надежности. Можно рекомендовать использовать эту функцию с большой осторожностью.

14. Добавление настраиваемых полей в профиль пользователя в административной панели

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

<?php
add_action( 'show_user_profile', 'smashing_profile_fields' ); // вешаем хуки на 
add_action( 'edit_user_profile', 'smashing_profile_fields' ); // показ и редактирование профиля 

// определяем функцию, которая будет формировать наши настраиваемые поля
function smashing_profile_fields( $user ) { 
?>

	<h3>Социальные сети</h3>

	<table class="form-table">

		<tr>
			<th><label for="twitter">Twitter</label></th>

			<td>
				<input type="text" name="twitter" id="twitter" value="<?php echo esc_attr( get_the_author_meta( 'twitter', $user->ID ) ); ?>" /><br />
				<span class="description">Ваше имя пользователя  в Twitter</span>
			</td>
		</tr>

		<tr>
			<th><label for="twitter">Facebook</label></th>

			<td>
				<input type="text" name="facebook" id="facebook" value="<?php echo esc_attr( get_the_author_meta( 'facebook', $user->ID ) ); ?>" /><br />
				<span class="description">Ссылка на ваш аккаунт в Facebook </span>
			</td>
		</tr>
		
		<tr>
			<th><label for="twitter">Linkedin</label></th>

			<td>
				<input type="text" name="linkedin" id="linkedin" value="<?php echo esc_attr( get_the_author_meta( 'linkedin', $user->ID ) ); ?>" /><br />
				<span class="description"> Ссылка на ваш аккаунт в LinkedIn</span>
			</td>
		</tr>

	</table>

<?php
}
add_action( 'personal_options_update', 'smashing_save_profile_fields' ); // вешаем хуки
add_action( 'edit_user_profile_update', 'smashing_save_profile_fields' ); // на обновление профиля пользователя

// функция, которая будет  сохранять данные
function smashing_save_profile_fields( $user_id ) {
	if ( !current_user_can( 'edit_user', $user_id ) )
		return false;

	update_user_meta( $user_id, 'twitter', $_POST['twitter'] );
	update_user_meta( $user_id, 'facebook', $_POST['facebook'] );
	update_user_meta( $user_id, 'linkedin', $_POST['linkedin'] );
}

15. Легкая проверка URL-адресов

Когда вы работаете с URL, всегда следите за тем, чтобы они были правильно сформированы и не содержали в себе запрещенные символы. Функция esc_url() поможет вам это сделать:

$my_url = 'http://mypage.com/?awesome=true'; // URL для проверки
$url = esc_url( $my_url ); // передаем его в функцию

Также, рекомендую ознакомиться со списком других подобных функций.

16. Оптимизация использования текстовых виджетов

Чтобы облегчить использование текстовых виджетов, используйте для них шорткоды (shortcodes). Для разработчиков тем (themes) это отличный способ повысить гибкость своего продукта для конечного пользователя.

add_filter( 'widget_text', 'do_shortcode' ); // добавляем шорткод к виджету

17. Добавление настраиваемых типов записей в RSS-ленту

Невозможность сделать это из административной панели, доставляет много неудобств. Большинство разработчиков сайтов разделяют контент по отдельным записям, и хотят видеть их все в ленте RSS. Не беспокойтесь — вот функция для этого:

add_filter('request', 'smashing_custom_feed'); // добавляем фильтр
function smashing_custom_feed( $vars ) {
	if ( isset( $vars['feed'] ) ) { // проверяем, существует ли массив $vars
		$vars['post_type'] = get_post_types(); // если да, то записываем в соответствующий элемент массива все зарегистрированные типы записей
	}
	return $vars; // возвращаем массив
}

Приведенная выше функция хороша, но записывает ВСЕ зарегистрированные типы функций в RSS-фид. Если вы хотите добавить только определенные типы записей, то вот такая функция:

add_filter('request', 'smashing_custom_feed');

$post_type_list = array( 'post', 'products' ); // создаем массив со списком нужных типов
function smashing_custom_feed( $vars ) {
	if ( isset( $vars['feed'] ) AND !isset( $vars['post_type'] ) ) { 
		$vars['post_type'] = $post_type_list; // после проверки на то, установлено значение или нет, присваиваем массиву наш список имен.
	}
	return $vars;
}

18. Не нарушайте механизм функционирования циклов WordPress

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

$tmp_query = $wp_query; // сохраняем во временной переменной
query_posts('cat=5&order=ASC'); // выбираем категорию и порядок
while( have_posts() ) : the_post() // цикл вывода
?>
	<a href="<?php the_permalink() ?>'><?php the_title() ?></a><br />
<?php
$wp_query = $tmp_query; // возвращаем переменную на место

19. Настраиваемые запросы к базе данных

Если вам нужно большее, чем предоставляют стандартные функции WordPress, то вы можете использовать класс $wpdb, чтобы обратиться к базе данных напрямую. Например:

$recent_users = $wpdb->get_results( "SELECT display_name, user_registered FROM $wpdb->users ORDER BY user_registered DESC LIMIT 0,10" ); // вывод списка всех зарегистрированных пользователей

Этот класс имеет много возможностей.

20. Настройка ревизий (сохраненных версий записей) в WordPress

Ревизии записей в WordPress этот мощный, но редко используемый большинством пользователей инструмент. Записи для ревизий создаются в базе данных, даже если не используются. Это может негативно сказаться на производительности работы крупных сайтов. Поэтому, если вы не используете ревизии, то отключите их, расположив следующий код в файле wp-config.php:

// Чтобы запретить ревизии: define( 'WP_POST_REVISIONS', FALSE );
// Чтобы ограничить их количество: define( 'WP_POST_REVISIONS', 5 );

21. Настройка стилей комментариев для автора

Если вы хотите выделить комментарии автора, то используйте стилевой класс bypostauthor:

li.bypostauthor { background:#fafafa; 	color:#555; }

22. Сохранение целой страницы в переменной

В некоторых случаях, сохранение вывода страницы или её части в переменной может быть очень полезным. Это позволяет вам легко вносить изменения, которые другими способами сделать нельзя, а также сжимать данные при передаче их пользователю. Для организации буфера вывода нам нужно создать два хука.

add_action('wp_head', 'smashing_buffer_start');
add_action('wp_footer', 'smashing_buffer_end');
function smashing_buffer_start() {
	ob_start( 'smashing_callback' ); // включаем буферизацию вывода
}

function buffer_end() {
	ob_end_flush(); // освобождаем (выводим) буфер вывода и выключаем буферизацию вывода
}

function smashing_callback( $content ) {
	// здесь вы можете делать все, что угодно со своим контентом
	$content = str_replace( 'great', 'awesome', $content );
	echo $content;
}

Перевод статьи «Powerful WordPress Tips And Tricks» был подготовлен дружной командой проекта Сайтостроение от А до Я.