Как работает маршрутизация в WordPress?
Как работает основная маршрутизация в WordPress? Мне сложно понять... В MVC ваш URL выглядит как mycontroller/myaction, который сопоставляется с MyController->myaction()
В Drupal это выглядит как index.php?q=mycustomerpath/hello, что может быть сопоставлено с любой функцией, которая возвращает контент, "оформленный" в макет вашей темы.
Но в WordPress я совершенно не понимаю, как это работает... используется ?p=1, затем ?product=1 ... Я искал документацию по процессу маршрутизации, но не могу найти ничего подходящего (Google выдает только статьи о пользовательских маршрутах)... Я хочу сначала понять основы базовой маршрутизации.

В 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 с ним. Легко.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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