Как работает маршрутизация в WordPress?

12 апр. 2014 г., 10:46:59
Просмотры: 55.2K
Голосов: 24

Как работает основная маршрутизация в WordPress? Мне сложно понять... В MVC ваш URL выглядит как mycontroller/myaction, который сопоставляется с MyController->myaction()

В Drupal это выглядит как index.php?q=mycustomerpath/hello, что может быть сопоставлено с любой функцией, которая возвращает контент, "оформленный" в макет вашей темы.

Но в WordPress я совершенно не понимаю, как это работает... используется ?p=1, затем ?product=1 ... Я искал документацию по процессу маршрутизации, но не могу найти ничего подходящего (Google выдает только статьи о пользовательских маршрутах)... Я хочу сначала понять основы базовой маршрутизации.

7
Комментарии

Копаясь в коде, я вижу, что при каждом запросе вызывается query_posts? Почему, черт возьми, нужно запрашивать записи каждый раз? Разве не бывает случаев, когда вам на самом деле не нужно отображать записи??

yeahman yeahman
12 апр. 2014 г. 10:49:17

Контент в WordPress сохраняется как записи. Поэтому, когда вам нужно отобразить контент, вам необходимо сделать запрос

Sisir Sisir
12 апр. 2014 г. 11:36:55

Могу я предложить вам почитать про "the loop" (цикл) — это концепция, которую нужно понять, чтобы разобраться, как работает WordPress. По сути, "the loop" отображает массив записей, который является результатом query_posts. Для неадминистративных URL-запросов WordPress предназначен для отображения только записей, и требуется дополнительное программирование, чтобы показать что-то кроме записи. Запросы к админке работают иначе и не используют "the loop", показывая другие элементы, не связанные с записями.

User User
12 апр. 2014 г. 11:52:01

ок, но этот подход немного странный и не очень гибкий, если честно

yeahman yeahman
12 апр. 2014 г. 13:07:12

скажем, я хочу отобразить контактную форму... мне нужно поместить мой HTML в тип контента страницы? Я все еще пытаюсь найти, куда поместить логику обработки отправки формы... (в page.php темы? очень некрасивый подход)

yeahman yeahman
12 апр. 2014 г. 13:08:50

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

Otto Otto
12 апр. 2014 г. 13:09:59

В качестве альтернативы, если вы создаёте тему для себя и не хотите заморачиваться с созданием переносимого плагина, вы можете сделать "Шаблон страницы" в своей теме, поместив в него ваш код, затем создать новую страницу и указать ей использовать этот специальный шаблон. Шаблоны — это PHP, они могут делать всё что угодно.

Otto Otto
12 апр. 2014 г. 13:14:41
Показать остальные 2 комментариев
Все ответы на вопрос 1
19
36

В WordPress URL-адреса не сопоставляются с маршрутами. Они сопоставляются с запросами к базе данных.

При использовании WordPress в режиме "стандартных" постоянных ссылок (permalinks) у вас есть набор переменных в основном URL-запросе, таких как ?p=1 или ?page=234 и так далее. Также есть ?s=search и многие другие.

Если вы используете "человекопонятные" (pretty) постоянные ссылки, то создается большой набор правил, называемых "правилами перезаписи" (rewrite rules), которые напрямую сопоставляют различные шаблоны URL с тем же набором параметров URL. Таким образом, URL вида /2014/04/12/example будет сопоставлен с ?year=2014&month=04&day=12&postname=example или аналогичным. Поэтому следующее относится и к ним, после выполнения этого сопоставления.

Эти переменные по сути управляют основным экземпляром класса WP_Query. Класс WP_Query содержит всю информацию, которая формирует запрос к базе данных для получения "записей" (posts). Различные параметры, передаваемые в него, определяют, какой запрос будет построен и какие данные будут получены.

Дело в том, что всё, что может быть отображено в WordPress, по сути является "записью". Блог — это серия записей в обратном хронологическом порядке. "Страница" (page) — это статичная запись с определенным именем. "Пользовательский тип записи" (custom post type) — это именно то, что звучит в названии, "запись" с пользовательским типом, который вы определяете. Все основные запросы для отображения чего-либо в WordPress получают некоторое подмножество записей из таблицы wp_posts.

WP_Query — это то, что выполняет эту задачу. А параметры из URL передаются напрямую в этот основной запрос и используются там.

Тема (theme) затем определяет, какой шаблон использовать, основываясь на результате запроса. Если вы запросили /category/example, это преобразуется в ?category_name=example, что означает, что основной массив $wp_query->query_vars получит эту информацию, и WP_Query извлечет последние X записей для категории "example", а также установит флаг is_category в true.

После этого запустится template-loader, увидит, что is_category() возвращает true, и решит выбрать шаблон категории, поэтому он будет искать category-example.php, а затем перейдет к category.php и так далее, в соответствии с Иерархией шаблонов (Template Hierarchy).

Таким образом, вопрос, если вы хотите изменить работу URL, прост: вы хотите изменить URL или то, на что они сопоставляются? Потому что URL не сопоставляются с функциями, они сопоставляются с параметрами, которые управляют запросом. Если вы хотите, чтобы URL изменял основной запрос, то это немного другой процесс, чем если бы вы хотели, чтобы специальный URL выполнял какой-то другой специальный код.

И чтобы ответить на ваш конкретный вопрос в комментариях: "Разве нет случаев, когда вы на самом деле не хотите отображать записи?" Нет, таких случаев нет. Всё является записью. Весь контент хранится в записях. Если вы хотите хранить контент в другом месте и сделать его другим, то вы можете это сделать, но это сложнее, потому что, честно говоря, это обычно не требуется. Если у вас есть специальный контент, создайте пользовательский тип записи, сохраните ваш контент как запись этого типа, сопоставьте шаблон URL с ним. Легко.

12 апр. 2014 г. 13:08:56
Комментарии

Я понимаю, что всё должно быть представлено в виде записей (через пользовательские типы записей и т.д.), очень похоже на кастомные типы в Drupal 6... но влияет ли это на производительность, когда все материалы сайта хранятся в одной таблице posts? Drupal 7 решил эту проблему, введя тип сущности (entity type), так что вам не нужно создавать кастомный тип и хранить всё в таблице node, а можно использовать собственную таблицу сущностей, которая всё ещё может использовать преимущества фреймворка Drupal. Надеюсь, WordPress внедрит подобный подход в будущем. Спасибо за подробное объяснение.

yeahman yeahman
12 апр. 2014 г. 13:14:07

Полагаю, если я хочу сопоставить URL с моей собственной функцией/темой, мне поможет WP Router?

yeahman yeahman
12 апр. 2014 г. 13:15:08

Добавление полноценной системы маршрутизации обычно не требуется. Есть более простые способы. Основа WordPress — это отображение контента, созданного пользователями, который хранится в таблице posts. Если вы хотите отображать контент, который не создан пользователями, то обычно это делается в теме или плагине. Существуют сотни (тысячи) хуков действий, фильтров и других способов для кода переопределять различные части процесса по мере генерации страницы. А с такими вещами, как шорткоды, вставка пользовательского HTML в контент относительно проста.

Otto Otto
12 апр. 2014 г. 13:19:21

как добавить пользовательский html/php в созданный мной тип записи? без необходимости изменять single.php темы или создавать single-mycustompost.php (не очень переносимый подход)

yeahman yeahman
12 апр. 2014 г. 13:24:26

Шорткоды. http://codex.wordpress.org/Shortcode_API

Otto Otto
12 апр. 2014 г. 13:54:11

@yeahman: Я скорее не согласен с некоторыми вашими оценками WordPress - немного странный и не очень гибкий, очень некрасивый подход, не очень переносимый подход. Хотя встроенная логика WordPress не подходит для всех видов сайтов, я считаю её гораздо более гибкой, переносимой и элегантной, чем вы можете оценить, поработав с ней совсем недолго. Если вы наберётесь больше опыта, думаю, вы обнаружите, что можете сделать гораздо больше, чем вам кажется. Вам действительно нужно понять действия, фильтры, шорткоды, виджеты... прежде чем вы сможете дать справедливую оценку.

User User
12 апр. 2014 г. 16:03:06

Я вижу из одного из ваших предыдущих вопросов, что вы используете плагин Pods. Это хороший пример гибкости WordPress. Pods не использует встроенную логику WordPress — запрос постов и их отображение с помощью цикла. Вместо этого он заменяет её своей собственной логикой. Это возможно благодаря тому, что действия WordPress позволяют легко изменять стандартное поведение системы. При этом вы всё ещё можете использовать все возможности огромной экосистемы, построенной вокруг WordPress.

User User
12 апр. 2014 г. 16:31:21

Я ещё не использовал PODS... Причина, по которой я рассматривал такой фреймворк, как PODS, в том, что WordPress «из коробки» не очень подходит для веб-разработки. Я понимаю, что изначально WordPress создавался только для блогов, но к версии 3.0, мне кажется, он должен был стать более удобным для веб-разработки. Drupal — хороший пример того, о чём я говорю... Начинал как CMS, но эволюционировал в CMF (Content Management Framework — вероятно, самый мощный из существующих).

yeahman yeahman
12 апр. 2014 г. 16:42:24

Если вашему сайту требуется кастомное программирование на большинстве страниц, то, возможно, WordPress — не лучший выбор. Мне лично нравится подход concrete5, но я считаю WordPress более жизнеспособным из-за его огромной экосистемы — у него, вероятно, самое большое количество плагинов (конечно, некоторые из них просто мусор). Безусловно, логика «цикла» выдаёт его блоговое происхождение, но WordPress эволюционировал и стал гораздо более функциональным, хотя и не является универсальным фреймворком. Если ваши требования не соответствуют логике «цикла», вам, вероятно, лучше выбрать что-то другое.

User User
12 апр. 2014 г. 17:36:13

@yeahman: Если ты считаешь, что Drupal лучше подходит для конкретного случая, тогда используй Drupal. Это всё свободное ПО. Используй то, что лучше соответствует твоим потребностям. WordPress от этого ни капельки не расстроится. Ну серьёзно, если бы ты делал вики, я бы тоже не советовал для этого WordPress. :)

Otto Otto
12 апр. 2014 г. 21:48:43

лол, я как раз работаю над проектом на WordPress, так что Drupal мне не нужен... лол но для WP действительно есть сложные плагины вроде WooCommerce, BuddyPress, которые популярны и не ограничиваются просто страницами с контентом/записями... но если покопаться в коде BuddyPress, видно, что пришлось изрядно похимичить, чтобы добиться этого. Надеюсь, плагин WP Router решит мою проблему с дефолтной маршрутизацией WP.

yeahman yeahman
12 апр. 2014 г. 23:04:30

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

yeahman yeahman
7 нояб. 2015 г. 19:47:41

и, к сожалению, я уже столкнулся с взломами на 3 сайтах WordPress... так что это тоже не очень безопасно...

yeahman yeahman
7 нояб. 2015 г. 19:48:53

Почти все взломы происходят из-за небезопасного сервера или кода плагинов/тем. Ядро WordPress абсолютно безопасно.

Otto Otto
7 нояб. 2015 г. 21:31:33

возможно, да. Но утверждать, что ядро WordPress абсолютно безопасно — это некоторое преувеличение... Патчи безопасности и обновления существуют не просто так.

yeahman yeahman
8 нояб. 2015 г. 10:31:19

Привет @Otto и всем остальным.

Теперь, когда есть WP REST API, я предполагаю, что существует своего рода роутер? Не могли бы вы обновить свой ответ для версии 4.7?

MrMesees MrMesees
15 дек. 2016 г. 07:23:09

Нет. Почему вы решили, что что-то изменилось? Такой функциональности по-прежнему нет. Это просто конечная точка в URL.

Otto Otto
17 дек. 2016 г. 09:38:18

С момента моего последнего комментария я поработал с WordPress больше, и у меня было взломано несколько сайтов; даже те, на которых не было дополнительных сторонних плагинов. Пришлось создавать скрипты для поиска взломанных файлов, их очистки и устанавливать Wordfence Security для мониторинга.

yeahman yeahman
4 февр. 2017 г. 09:47:06

Для тех, кто интересуется, где устанавливается запрос, ищите wp(); в файле wp-blog-header.php

8ctopus 8ctopus
2 нояб. 2023 г. 09:20:00
Показать остальные 14 комментариев