Покупанда, мой первый старт-ап, сайт коллективных покупок (да, как Groupon). Когда-нибудь я расскажу историю о том, как я его построил, но в данный момент это совсем другая сказка.

“Poke-your-panda”, как ее называют мои американские друзья, построена целиком на WordPress 3.0, так что никому не рассказывайте, что это “платформа для блогов”, потому что это не так. В WP теперь есть куча новых возможностей, которых нам так хотелось долгое время, например, собственные типы постов. Ура? Не совсем, потому что по прежнему приходится немного кодить. Константин Ковшенин написал пару отличных статей на тему реализации кастомных постов в вашей теме/плагине для WP, так что я распространяться не буду, а лучше расскажу, с какими проблемами мой проект столкнулся в первые дни после официального запуска.

Хьюстон, у нас 404-я

Кастомные посты существовали до WP3.0. Финальная версия просто дала возможность не использовать хак с query_vars, чтобы подключать собственные шаблоны. Сейчас, если нужно показать один пост кастомного типа, достаточно просто создать шаблон с именем single-post_type.php внутри своей темы. Но некоторым из нас (я имею ввиду себя, разумеется) нужен был цикл из кастомных постов, вписаный в иерархию на уровне ядра WP.

Что я сделал:

global $wp_query;

if (isset($wp->query_vars['pagename'])) {

	switch($wp->query_vars['pagename']) {

		case "somepagename":
			$wp_query->is_404 = false;
			locate_template("templates/somepagename.php",true);
			exit;
			break;
	}

}

Этот фрагмент кода показывает результат работы файла somepagename.php, который расценивается как шаблон темы WP, и в нем можно использовать любые тэги шаблонов. locate_template() в данном случает – правильный способ замены шаблона страницы на нужный шаблон, потому что это нативная функция WP и имеет внутри себя все правильные фильтры, хуки и действия. Зачем использовать здесь pagename? Потому что всю, что не принадлежит к кодовым словам для отображения категорий, тэгов и прочего и не является именем одиночного поста, расценивается как имя страницы.

Это всё?

Нет. $wp_query->is_404 = false – только полумера. В нормальных браузерах этот код не создаст ошибок, я имею ввиду нормальных как Webkit – Safari и Chrome, которые не позволяют расширениям вытворять что вздумается. Проблема все же существует – мы устанавливаем 404-ю на false после того, как она на самом деле была передана браузеру в HTTP-заголовках, так что если WP не будет рассматривать ваш шаблон как 404-ю страницу, браузер может. И будет, особенно если это Internet Explorer с каким нибудь идиотским тулбаром от вашего любимого поисковика.

Обходной путь? Просто создайте страницу, пермалинк которой будет в точности совпадать с вашим somepagename. Ей не нужно имя или контент, все будет заменено содержимым вашего шаблона somepagename.php.

Ну теперь-то всё?

Почти. 404-я может по прежнему возникнуть, если системное имя (slug) кастомного поста будет использовано в качестве имени аргумента в любом GET (или даже POST) запросе внутри сайта для чего угодно, кроме непосредственного отображения поста этого типа.

Продолжение сказок о веб-деве следует.