Что такое ошибка 400 bad request и как ее исправить

Основные ошибки nginx и их устранение

502 Bad Gateway

Ошибка означает, что NGINX не может получить ответ от одного из сервисов на сервере. Довольно часто эта ошибка появляется, когда NGINX работает в связке с Apache, Varnish, Memcached или иным сервисом, а также обрабатывает запросы PHP-FPM.
Как правило, проблема возникает из-за отключенного сервиса (в этом случае нужно проверить состояние напарника и при необходимости перезапустить его) либо, если они находятся на разных серверах, проверить пинг между ними, так как, возможно, отсутствует связь между ними.
Также, для PHP-FPM нужно проверить права доступа к сокету.
Для этого убедитесь, что в прописаны правильные права

listen = /tmp/php5-fpm.sock 
listen.group = www-data
listen.owner = www-data

504 Gateway Time-out

Ошибка означает, что nginx долгое время не может получить ответ от какого-то сервиса. Такое происходит, если Apache, с которым NGINX работает в связке, отдаёт ответ слишком медленно.
Проблему можно устранить с помощью увеличения времени таймаута.
При работе в связке NGINX+Apache в конфигурационный файл можно внести изменения:

server { 
... 
   send_timeout 800;
   proxy_send_timeout 800;
   proxy_connect_timeout 800;  
   proxy_read_timeout 800;  
... 
}

Тут мы выставили ожидание таймаута в 800 секунд.

Upstream timed out (110: Connection timed out) while reading response header from upstream

Причиной может быть сложная и потому долгая обработка php в работе PHP-FPM.
Здесь тоже можно увеличить время ожидания таймаута

location ~ \.php$ { 
   include fastcgi_params;
   fastcgi_index index.php; 
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
   fastcgi_pass unix:/tmp/php5-fpm.sock;  
   fastcgi_read_timeout 800;
}

800 секунд на ожидание ответа от бекенда.

Это лишь временные меры, так как при увеличении нагрузки на сайт ошибка снова станет появляться. Устраните узкие места, оптимизируйте работу скриптов php

413 Request Entity Too Large

Ошибка означает, что вы пытались загрузить слишком большой файл. В настройках nginx по умолчанию стоит ограничение в 1Mb.
Для устранения ошибки в nginx.conf нужно найти строку

client_max_body_size 1m;

и заменить значение на нужное. Например, мы увеличим размер загружаемых файлов до

client_max_body_size 100m;

Также, можно отключить проверку размера тела ответа полностью значением ноль:

client_max_body_size 0;

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

После каждого внесённого изменения в конфигурационный файл необходимо перезагружать nginx

304 Not Modified не устанавливается

Если возникает проблема с правильным отображением ответного заголовка сервера , то проблема, скорее всего, в пунктах:

  • В секции конкретного сайта включен (Подробнее в документации). По умолчанию, ssi отключен, но некоторые хостеры и ISPManager любят его прописывать в дефолтную конфигурацию сайта включенным. Его нужно обязательно отключить, закомментировав или удалив эту строку;
  • if_modified_since установить в , то есть на уровне или конкретного прописать:

Правильность ответа можно проверить с помощью:

  • Консоли разработчика браузера (F12) в разделе (не забываем перезагружать страницу);
  • Или сторонних сервисов, например last-modified.com.

Создание дополнительных полей для пользовательских типов записей

Механизм дополнительных полей (метабоксов) использует встроенную в WordPress систему дополнительных полей. Это помогает добавлять поля, предназначенные исключительно для пользовательских типов записей, не используя в редакторе пользовательских полей по умолчанию.

Шаг 1: Регистрируем пользовательскую функцию

Откройте файл Movie-Reviews.php и добавьте следующий код перед тегом закрытия. Этот код регистрирует функцию, которая будет вызываться при посещении панели администратора WordPress.

Шаг 2: Выполняем пользовательскую функцию

Добавьте выполнение функции , которая регистрирует дополнительные поля и связывает их с пользовательским типом записи .

В данном случае функция  используется для добавления дополнительных полей к пользовательскому типу записей. Об атрибутах:

  • необходимый атрибут для HTML  
  • текст, которые будет виден в заголовке дополнительного поля
  • функция обратного вызова которая отображает содержимое дополнительных полей
  • имя пользовательского типа записи, где будут отображаться дополнительные поля
  • определяет где на странице будет показан блок редактирования
  • определяет приоритет отображаемых полей

Шаг 3: Выполняем функцию 

Этот код выводит содержимое дополнительных полей. Здесь используется объектная переменная, которая содержит информацию о каждом из показанных на панели редактирования кинообзоров. Используя этот объект мы получили ID записи и использовали его, чтобы сделать запрос в базу данных для получения имени режиссера и рейтинга, что в свою очередь выведется в полях на экране. При добавлении новой записи, функция  возвратит пустую строку, и в итоге дополнительные поля будут пустыми.

Шаг 5: Выполняем функцию 

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

Шаг 6: Отключаем стандартные пользовательские поля

Создавая пользовательский тип записи, мы задали функцию . Удалите элемент  из массива , поскольку он нам больше не понадобиться. Теперь, если вы сохраните файл и откроете панель редактирования Movie Reviews, вы увидите два поля в дополнительных полях: Movie Author и Movie Rating. Вы можете добавить другие элементы тем же способом.

Регистрация на сайте SinoTrack

После всех произведённых настроек наш гаджет уже можно использовать, но чтобы отслеживать его нахождение/передвижение в реальном времени или просматривать на карте трек, нужно зарегистрировать GPS-трекер в одном из соответствующих сервисов. Выбрать для регистрации можно тот ресурс, который вам больше понравится, мы же будем использовать сайт от производителя — SinoTrack.

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

Изначально мы должны написать сообщение или электронное письмо в саму компанию SinoTrack. Проще всего для этого связаться с продавцом, у которого вы приобретали GPS-трекер, если он является официальным представителем производителя. Текст письма не принципиален, главное — передать суть, надо попросить представителя компании создать для вас аккаунт на сайте. При этом вовсе не обязательно, как многие думают, передавать сотруднику компании ID вашего трекера, указанный на корпусе устройства. Вот примерное содержание письма, которого будет вполне достаточно:

В ответ обычно в течение 1-2 дней вам будет прислан логин и пароль для входа в свой аккаунт на сайте СиноТрек.

Теперь мы можем зайти на сайт (в браузере должна быть активирована поддержка Flash, то есть должен быть установлен Adobe Flash Player), ввести в окне авторизации регистрационные данные, которые нам прислал продавец, и нажать на кнопку Submit.

После входа на сайт первым делом советуем вам сменить стандартный пароль, который был вам прислан.

Возьмите себе за правило каждый раз, когда аккаунт вам регистрирует кто-то кроме вас, при первом же входе менять пароль на свой, отличный от стандартного

Чтобы изменить пароль, нажимаем на свой логин в правом верхнем углу окна браузера и в открывшемся окне в поля Password и RePassword вводим новый пароль. Остальные параметры можете менять на своё усмотрение. После чего внизу окошка нажимаем на кнопку Modify. Пароль изменён.

Можно приступить к основному действию, а именно — добавить в аккаунт на SinoTrack трекер по ID.
В верхней строке навигации переходим на вкладку User Center, затем среди появившихся закладок активируем Asset Manage. Под закладками нажимаем кнопку Add, откроется окно добавления устройства. Обязательные поля отмечены звёздочкой:

Asset Name — вводим сюда произвольное имя устройства, которое будет отображаться на сайте и на карте. При необходимости поле можно будет отредактировать позднее;

SimCard No. — сюда вводим номер телефона, по которому мы обращаемся к сим-карте, вставленной в GPS-трекер. При необходимости поле можно будет отредактировать позднее;

Device ID — здесь вводим ID устройства, идентификационный номер, указанный на корпусе трекера

Обращаем ваше внимание, что вводить нужно не IMEI, наклейку с которым также можно найти на корпусе, а именно цифровой код, обозначенный как ID. Позже это поле отредактировать не удастся

В случае ошибки придётся создать новую запись.

Внизу окошка нажимаем кнопку Ok. Устройство добавлено.

Теперь вы может отслеживать местоположение устройства и статус датчика включенного зажигания (о подключении соответствующего провода поговорим ниже) в онлайн режиме через браузер.

При желании можно скачать приложение от официального разработчика на мобильное устройство и также работать с трекером на своём смартфоне.

Ищем проблему на стороне сервера

Если что-то происходит на стороне ресурса, то это редко заканчивается ошибкой 400. Но все-таки есть несколько сценариев, при которых клиента обвиняют в сбое зря, а настоящая вина лежит на сервере. 

Проверяем требования к HTTP-заголовкам

Пока настраиваешь сайт, несложно допустить ошибку или даже парочку. Возможно, требования к HTTP-заголовком указаны некорректно, и сервер ожидает запросы с ошибками, которые по объективным причинам не может распознать адекватно. Тогда администратору стоит перепроверить ожидаемые заголовки на своем сайте или в приложении. 

Удаляем свежие обновления и плагины

Иногда ошибка 400 Bad Request появляется после обновления CMS или установки новых плагинов. Если у вас она появилась из-за этого, то наиболее логичное решение — откатиться до более ранней версии CMS и удалить все новые плагины. 

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

Проверяем состояние базы данных

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

Исправляем ошибки в коде и скриптах

Ничего из вышеперечисленного не помогло? Тогда осталось проверить свой код и работающие скрипты. Лучше провести дебаггинг вручную и не надеяться на помощь компьютера. Сделать копию приложения или сайта, потом пошагово проверить каждый отрезок кода в поисках ошибок. 

В крайнем случае придется кричать «полундра» и звать на помощь техподдержку хостинга. Возможно, возникли сложности на их стороне. Тогда вообще ничего не надо будет делать. Просто ждать, пока все исправят за вас. 

На этом все. Основные причины появления 400 Bad Request разобрали. Как ее лечить — тоже. Теперь дело за вами. Пользуйтесь полученной информацией, чтобы больше не пришлось мучиться в попытках зайти на нужный ресурс.

Запускаем функцию

Пока что, эта функция ничего не делает. Чтобы она заработала, вам нужно сделать одну из трёх вещей:

  1. Подцепить её к существующему хуку действий в вашей теме.
  2. Добавить хук действий в вашу тему, используя и подцепив её туда.
  3. Добавить название функции в вашу тему туда, где вы хотите вывести этот список.

Для второго и третьего варианта, если вы работаете со сторонней темой, вам придётся создать дочернюю тему и редактировать её. Ещё вы можете создать файл шаблона single-tutsplus_product.php и добавить хук или функцию в него, или просто добавить это в single.php. Если вы подцепили её через файл шаблона для типа содержимого, то вы можете удалить проверку .

Я использую тему Suki из каталога плагинов WordPress. У неё в файле single.php есть данный хук:

Хук находится прямо под содержимым, именно там, где я хочу вывести мой список. Поэтому я цепляю мою функцию к этому хуку действий:

Когда вы это сделаете, сохраните ваш плагин и добавьте несколько продуктов и терминов таксономии.

NginX выдает ошибку HTTP 499 через 60 секунд, несмотря на конфигурацию. (PHP и AWS)

В конце прошлой недели я заметил проблему на одном из моих средних экземпляров AWS, где Nginx всегда возвращает ответ HTTP 499, если запрос занимает более 60 секунд. Запрошенная страница представляет собой скрипт PHP

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

Я пробовал изменять настройки PHP, настройки PHP-FPM и настройки Nginx. Вы можете увидеть вопрос, который я поднял на форумах NginX в пятницу ( http://forum.nginx.org/read.php?9,237692 ), хотя он не получил ответа, поэтому я надеюсь, что я смогу найти ответьте здесь, прежде чем я вынужден вернуться к Apache, который, как я знаю, работает.

Это не та же проблема, что и ошибки HTTP 500 в других записях.

Я смог реплицировать проблему с помощью нового экземпляра micro AWS NginX с использованием PHP 5.4.11.

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

Вам нужно будет запустить новый экземпляр AWS Micro (поэтому он бесплатный) с помощью AMI ami-c1aaabb5

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

Как только вы настроитесь, вам просто нужно создать образец файла PHP, который я тестирую, с которым

Сохраните это в webroot, а затем проверьте. Если вы запустите скрипт из командной строки, используя php или php-cgi, он будет работать. Если вы получите доступ к скрипту через веб-страницу и закроете журнал доступа /var/log/nginx/example.access.log , вы заметите, что получите ответ HTTP 1.1 499 через 60 секунд.

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

Обновите PHP FPM Config, чтобы включить внешние файлы конфигурации

Создайте новую конфигурацию PHP-FPM для переопределения таймаута запроса

Измените некоторые глобальные настройки, чтобы обеспечить интервал аварийного перезапуска 2 минуты

Затем мы изменим некоторые параметры PHP.INI, снова используя отдельные файлы

Как вы можете видеть, это увеличивает тайм-аут сокета до 3 минут и помогает регистрировать ошибки.

Наконец, я отредактирую некоторые параметры NginX, чтобы увеличить тайм-аут той стороны

Сначала я редактирую файл /etc/nginx/nginx.conf и добавляю его в директиву http fastcgi_read_timeout 300;

Затем я редактирую файл / etc / nginx / sites-enabled / example, который мы создали ранее (см. Запись pastebin), и добавьте следующие параметры в директиву сервера

Наконец, я добавляю следующее в раздел

.php $ сервера dir

Прежде чем повторять сценарий, запустите nginx и php-fpm, чтобы убедиться, что новые настройки были подняты. Затем я пытаюсь получить доступ к странице и все еще получаю запись HTTP / 1.1 499 в файле NginX example.error.log.

Итак, где я иду не так? Это просто работает на apache, когда я устанавливаю максимальное время выполнения PHP до 2 минут.

Я вижу, что настройки PHP были подобраны, запустив phpinfo () с веб-страницы. Я просто не понимаю, я действительно думаю, что слишком много было увеличено, так как это должно было просто потребовать изменения max_execution_time PHP, default_socket_timeout, а также fastcgi_read_timeout от NginX только в директиве location-> server .

Решение проблем с ошибкой 503 администратором веб-ресурса

При возникновении ошибки 503 Service Unavailable в любом ее проявлении администратор web-ресурса в первую очередь должен разобраться в причине ее появления. Игнорирование данной процедуры по принципу «само пройдет» может привести к тому, что сайт понесет глобальные потери в объеме пользовательского трафика и, как следствие, конверсии. Посетители, регулярно сталкивающиеся с проблемами доступа к определенному ресурсу, очень быстро занесут его в «игнор».

В зависимости от конкретного тарифного плана хостинга каждый сайт имеет ограничения по одновременной обработке запросов, поступающих на сервер от конечных пользователей. Более простые запросы браузеров обрабатываются практически мгновенно, сложные ожидают очереди в порядке их поступления. Количество отложенных запросов лимитировано, при превышении нормы каждый следующий отклоняется. В этом случае посетитель сайта видит на экране сообщение с кодировкой error 503.

Наиболее частые причины возникновения ошибки 503 на стороне сервера

  1. При получении запроса от пользователя конкретная страница сайта не может установить соединение с базой данных MySQL.
  2. Некорректная работа плагинов и расширений из-за внутренних ошибок или конфликта между собой.
  3. Использование недорого хостинга и маломощного сервера приводит к тому, что оборудование не справляется с обработкой входящего трафика.
  4. Ресурсоемкие скрипты создают дополнительную нагрузку на сервер.
  5. Задействован почтовый сервис, выполняющий автоматическую рассылку сообщений в большом объеме.
  6. Соединение с удаленным сервером может привести к замедлению обработки запросов.
  7. Передача файлов большого объема при помощи PHP-скрипта.
  8. Значительное количество нерабочих модулей конкретной CMS.

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

Как избежать появления ошибок 503

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

Уменьшение нагрузки на базу данных можно добиться следующими способами:

  • Регулярное обновление CMS, которое позволяет оптимизировать работу движка, уменьшить количество багов.
  • Установка защиты от ботов и парсеров, которые часто запускаются вашими конкурентами, чтобы создать дополнительную нагрузку на ресурс и тем самым вывести его частично или полностью из строя.
  • Уменьшение размера и, если это возможно, количества графических файлов на сайте, а также «тяжелых» таблиц.
  • Ввод ограничений на количество одновременных участников в чате.

Оптимизация работы скриптов

  • Отключите все лишние плагины и дополнения, кроме тех, которые реально необходимы для бесперебойной работы сайта (кэширование, оптимизация базы данных, создание бэкапов, сжатие изображений).
  • Осуществляйте передачу файлов большого объема через FTP, т.к. использование других способов передачи данных приводит к созданию отдельного процесса.
  • Осуществляйте массовую почтовую рассылку в моменты отсутствия пиковой нагрузки на сайт, например, ночью или ранним утром.
  • При использовании удаленного сервера минимизируйте время ответа и оптимизируйте канал соединения.
  • Проверьте наличие проблемных запросов к базе MySQL в файле mysql-slow.log.

Дополнительную нагрузку на сервер, приводящую к появлению ошибки 503, могут создать DDoS-атаки. Защита от них с помощью фильтрации относится к отдельной теме обсуждения.

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

Параметры массива $args

number
(целое число) количество элементов, которые нужно вывести, по умолчанию выводятся все.

offset
(целое число) сколько элементов нужно пропустить, то есть если offset=2, то начинаем с третьего.

include
(целое число|строка|массив) укажите ID элементов, которые нужно вывести, можно указать число, числа через запятую в виде строки или одномерный массив чисел, например так:

$categories = get_terms('category', 'include=1');

или так:

$categories = get_terms('category', 'include=1,4');

или даже так:

$args = array(
    'include' => array(1,4)
);
$categories = get_terms('category', $args);

Если вы хотите исключить какие-то элементы, не пытайтесь использовать минус перед числом, просто смотрите следующий параметр.

exclude
(целое число|строка|массив) укажите ID элементов, которые нужно исключить.

orderby
(строка) сортировать по:

  • id — по ID элементов (по умолчанию),
  • count — по количеству постов,
  • name — по имени,
  • slug — по ярлыку,
  • term_group — по значениям колонки term_group в таблице wp_terms базы данных,
  • none — без сортировки;

order
(строка) порядок сортировки.

  • ASC — по возрастанию (по умолчанию),
  • DESC — по убыванию;

hide_empty
(логическое) нужно ли добавлять в результат также и пустые (без постов) рубрики/метки/элементы таксономий:

  • — не нужно (по умолчанию),
  • — нужно;

fields
(строка) в каком виде выводить результат:

  • all — массив объектов элементов таксономий (по умолчанию), после print_r() он будет выглядеть так:

    $categories = get_terms('category');
    print_r($categories);
    /*
    Результат:
    Array (  => stdClass Object (  => 1  => Заметки  => notes  => 0  => 0  => 1  => category  =>  => 0  => 7 )  => stdClass Object (  => 4  => Новости  => news  => 0  => 0  => 4  => category  =>  => 0  => 2 )  => stdClass Object (  => 11  => Обновления  => updates  => 0  => 0  => 11  => category  =>  => 4  => 1 ) )
    */
  • ids — массив составленный из ID элементов, вот как он будет выглядеть, если пропустить его через функцию :

    $categories = get_terms('category', 'fields=ids');
    print_r($categories);
    /*
    Результат:
    Array (  => 1  => 4  => 11 )
    */
  • names — возвращает массив наименований, например:

    $categories = get_terms('category', 'fields=names');
    print_r($categories);
    /*
    Результат:
    Array (  => Новости  => Заметки )
    */
  • count — (с версии 3.2) возвращает количество всех элементов таксономии, вне зависимости от других параметров. Для этих целей вы также можете использовать wp_count_terms().

    $categories = get_terms('category', 'fields=count');
    echo $categories;
    /*
    Результат:
    4
    */
  • id=>parent — ассоциативный массив состоящих из ID элементов и ID их родителей, если родительского элемента не существует, то возвращается 0, пример:

    $categories = get_terms('category', 'fields=id=>parent');
    print_r($categories);
    /*
    Результат:
    Array (  => 0  => 0  => 4 )
    */

slug
(строка) возвращает элементы, ярлыки которых совпадают с заданным значением.

hierarchical
(логическое) нужно ли включить в результат родительские элементы, даже если в них нет постов?

  • 1 — нужно (по умолчанию),
  • 0 — не нужно;

name__like
(строка) возвращает только те элементы, названия которых начинаются с заданного значения (без чувствительности в регистру), например:

// выведем через пробел все метки, начинающиеся с буквы "н"
$tags = get_terms('post_tag', 'name__like=н');
foreach($tags as $tag){
    echo $tag->name . ' ';
}

search
(строка) возвращает только те элементы, названия которых содержат заданное значение (без чувствительности в регистру).

pad_counts
(логическое) влияет только на числовые значения количества постов в родительских элементах.

  • 1 — количество постов родительского элемента суммируется с количеством постов дочерних элементов,
  • 0 — не суммируется (по умолчанию);

get
(строка)

all — вывести все элементы, вне зависимости от параметров offset, hide_empty, child_of (по умолчанию — пустая строка)

child_of
(целое число) вывести все элементы таксономии, которые являются дочерними для элемента с указанным ID вне зависимости от уровня вложенности.

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

cache_domain
(строка) (с версии 3.2) если вы планируете использовать get_terms с указанными параметрами несколько раз, укажите в качестве значения cache_domain уникальную фразу, чтобы задействовать кэш (по умолчанию — «core»).

Создаем фильтры для настраиваемой таксономии

Здесь мы увидим, как настраиваемая таксономия (в нашем случае — это категории) может быть использована в качестве дополнительного фильтра при составлении списка CPT в секции администрирования WordPress, чтобы администраторы могли отобразить элементы CPT, принадлежащие к конкретной категории.

Шаг 1. Регистрация функции

Откройте файл плагина и добавьте в него следующий код для регистрации функции. Эта функция будет вызвана, когда WordPress будет готовиться к отображению выпадающего списка с результатами фильтрации контента.

add_action( 'restrict_manage_posts', 'my_filter_list' );

Шаг 2. Внедрение функции

function my_filter_list() {
    $screen = get_current_screen();
    global $wp_query;
    if ( $screen->post_type == 'movie_reviews' ) {
        wp_dropdown_categories( array(
            'show_option_all' => 'Show All Movie Genres',
            'taxonomy' => 'movie_reviews_movie_genre',
            'name' => 'movie_reviews_movie_genre',
            'orderby' => 'name',
            'selected' => ( isset( $wp_query->query ) ? $wp_query->query : '' ),
            'hierarchical' => false,
            'depth' => 3,
            'show_count' => false,
            'hide_empty' => true,
        ) );
    }
}

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

Аргументы orderby, show_count, hide_empty, depth и другие определяют сортировку, отображение счетчиков числа постов в каждой категории, скрывают не связанные с ними категории, определяют максимальную глубину для отображения в иерархической структуре категорий.

Шаг 3. Отображение фильтрованных результатов

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

add_filter( 'parse_query','perform_filtering' );

Шаг 4. Внедрение функции отображения контента

function perform_filtering( $query ) {
    $qv = &$query->query_vars;
    if ( ( $qv ) && is_numeric( $qv ) ) {
        $term = get_term_by( 'id', $qv, 'movie_reviews_movie_genre' );
        $qv = $term->slug;
    }
}

Функция perform_filtering получает объект запроса на конкретный пост от WordPress, а затем переводит запрос и отображает контент согласно набору переменных, содержащихся в теле объекта. Также на данном этапе происходит верификация того, является ли параметр Movie Genre частью запрашиваемых переменных, и только потом происходит выполнение запроса. Теперь вы сможете использовать фильтр для отображения кинофильмов по жанрам:

Создание запроса

Переходим к самому интересному. Нам нужно написать функцию, которая будет получать термины таксономии для продукта, а затем выводить список постов, которые также содержат этот термин.

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

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

Получение списка терминов или добавление их в массив

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

Добавьте это:

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

Это извлекает фрагмент каждого термина и добавляет его в массив .

Выполняем запрос

Теперь, нам надо задать аргументы запроса. Это будет внутри условия , так как мы не хотим, чтобы он выполнялся при отсутствии терминов таксономии. Добавьте это в ваш код:

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

Теперь запустим запрос с этими аргументами:

Это выведет элемент с заголовком и список со ссылками на каждый пост. Если пожелаете, можете вывести это по-другому; можете добавить отрывок или изображение.

Как избежать ошибок

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

Последнее по порядку, но не по значимости: Создаем страницу архива

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

Шаг 1. Создаем для архива путь для перехода и вызова

Откройте файл плагина Movie-Reviews.php и добавьте выделенный цветом код в функцию include_template_function:

function include_template_function( $template_path ) {
    if ( get_post_type() == 'movie_reviews' ) {
        if ( is_single() ) {
            // checks if the file exists in the theme first,
            // otherwise serve the file from the plugin
            if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) ) {
                $template_path = $theme_file;
            } else {
                $template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
            }
        }
        elseif ( is_archive() ) {
            if ( $theme_file = locate_template( array ( 'archive-movie_reviews.php' ) ) ) {
                $template_path = $theme_file;
            } else { $template_path = plugin_dir_path( __FILE__ ) . '/archive-movie_reviews.php';
            }
        }
    }
    return $template_path;
}

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

Шаг 2. Создаем шаблон архива

Сохраните и закройте файл плагина и затем создайте новый файл под названием archive-movie_reviews.php. Вставьте в него следующий код:

<?php get_header(); ?>
<section id="primary">
    <div id="content" role="main" style="width: 70%">
    <?php if ( have_posts() ) : ?>
        <header class="page-header">
            <h1 class="page-title">Movie Reviews</h1>
        </header>
        <table>
            <!-- Display table headers -->
            <tr>
                <th style="width: 200px"><strong>Title</strong></th>
                <th><strong>Director</strong></th>
            </tr>
            <!-- Start the Loop -->
            <?php while ( have_posts() ) : the_post(); ?>
                <!-- Display review title and author -->
                <tr>
                    <td><a href="<?php the_permalink(); ?>">
                    <?php the_title(); ?></a></td>
                    <td><?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?></td>
                </tr>
            <?php endwhile; ?>
            <!-- Display page navigation -->
        </table>
        <?php global $wp_query;
        if ( isset( $wp_query->max_num_pages ) && $wp_query->max_num_pages > 1 ) { ?>
            <nav id="<?php echo $nav_id; ?>">
                <div class="nav-previous"><?php next_posts_link( '<span class="meta-nav">&larr;</span> Older reviews'); ?></div>
                <div class="nav-next"><?php previous_posts_link( 'Newer reviews <span class= "meta-nav">&rarr;</span>' ); ?></div>
            </nav>
        <?php };
    endif; ?>
    </div>
</section>
<br /><br />
<?php get_footer(); ?>

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

Мы также использовали объект wp_query, в котором содержатся данные об исполняемом в данный момент запросе в порядке рендеринга требуемых элементов и содержимого страницы. Функция get_post_meta использовалась для получения данных из настраиваемых полей.

Шаг 3. Что получилось в итоге

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

Выводим отсортированные по имени рубрики в виде выпадающего списка

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

// вытаскиваем все рубрики в массив $categories, описание параметров функции смотрите чуть ниже
$categories = get_terms('category', 'orderby=name&hide_empty=0');
 
// если рубрики, соответствующие заданным параметрам, существуют,
if($categories){
 
    // тогда создаем выпадающий список из них
    echo '<select>';
 
    // обращаемся к каждому объекту массива (в данном случае рубрика)
    foreach ($categories as $cat){
 
        // выводим элемент списка, где атрибут value равен ID рубрики, а $cat->name - название рубрики
        echo "<option value='{$cat->term_id}'>{$cat->name}</option>";
    }
    echo '</select>';
}

Вот что у меня получилось в результате выполнения этого кода на тестовом сайте:

Слева — сам список (открытый), а справа его HTML-код.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: