Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
WP Multi City
Мультигородская подсистема для WordPress: один сайт обслуживает несколько городов
по схеме /{city}/{path}/ с подстановкой контента, ссылок и шорткодов.
Версия: 1.0.0 — MVP завершён.
Требования
- WordPress 6.0+
- PHP 8.0+
- Advanced Custom Fields Pro
Установка
- Скачать zip последнего релиза: https://git.netranking.ru/bryzgalov/wp-multi-city/releases
- WP admin → Plugins → Add new → Upload (или распаковать в
wp-content/plugins/wp-multi-city/). - Активировать. Если ACF Pro не активен — увидите admin notice об ошибке зависимости.
Обновления приходят автоматически: плагин-update-checker опрашивает Gitea hourly. Force-check: WP admin → Plugins → «Check again».
Quick Start (5 минут)
- WP admin → Шорткоды → Города → создать term
tyumen,spb. - WP admin → WP Multi City → выставить
main_town_slug=spb. - WP admin → Шорткоды → Добавить пост:
- title:
Тарифы - ACF repeater
list_shortcode: row town=tyumen, text="Тюменский тариф". - Запомнить ID поста (например 42).
- title:
- Создать страницу с контентом
[shortcode_dmr id=42]. - Открыть
/tyumen/<slug-страницы>/→ увидеть «Тюменский тариф». Открыть/<slug-страницы>/без префикса → пусто (main_town=spb, не tyumen).
Hook API
Процедурные функции
| Функция | Возвращает | Назначение |
|---|---|---|
wpmc_current_town() |
?string |
town slug из текущего URL или null |
wpmc_get_term_by_slug($slug) |
?\WP_Term |
town-term по slug |
wpmc_alt_get_field($key, $post_id) |
mixed |
get_field с fallback на term meta |
wpmc_remove_domain_link($url) |
string |
strip home_url prefix |
wpmc_main_town_slug() |
?string |
slug из options page |
WP-фильтры от плагина
the_title/single_cat_title→do_shortcode(priority 9999, после Yoast SEO).home_url/post_link/acf/load_value→LinkFilter::add_town_prefix(auto-prefix URL текущим town).rest_url→RestUrlFilter::preserve_host(форсирует HTTPS +HTTP_HOST).
Bypass URL-фильтров
Когда нужно построить «канонический» URL без городского префикса:
$canonical = \WPMultiCity\Helpers::without_url_filters(
fn() => get_permalink($post_id)
);
Counter-based, поддерживает вложенные вызовы.
Migration guide (из темы washanyanya)
- В
wp-content/themes/washanyanya/functions.phpзакомментироватьrequire_once get_template_directory() . '/inc/town-functions.php';. - Активировать wp-multi-city.
- ACF Pro field group из темы → re-import в новую location (CPT
shortcode-town). - Заменить вызовы
current_town()наwpmc_current_town(). Либо прописать алиас в functions.php темы:if (function_exists('wpmc_current_town')) { function current_town(): ?string { return wpmc_current_town(); } } - Проверить:
/tyumen/about/отдаёт правильный page; меню префиксится;[shortcode_dmr]рендерит.
Testing
Automated (PHPUnit)
composer install
vendor/bin/phpunit
Expected: 104 tests, ~185 assertions green. Unit-level coverage via Brain Monkey
- Mockery + Patchwork — no real WordPress required; полный suite за <1 секунду.
Manual QA
Для end-to-end проверки против реального WordPress см. docs/QA-CHECKLIST.md —
13 секций (активация, admin UI, helpers, shortcode, router, page clones,
URL filters, REST URL).
CI
.gitea/workflows/test.yml запускает PHPUnit на каждый push в main и каждый PR.
Активируется автоматически после push в Gitea.
Roadmap MVP
| Этап | Содержание | Beads | Статус |
|---|---|---|---|
| S1 | Скелет (header, autoload, bootstrap) | cp-8ci | done |
| S2 | Taxonomy town + CPT shortcode-town + ACF list_shortcode |
cp-q7g | done |
| S3 | [shortcode_dmr id=N] + хелперы |
cp-arq | done |
| S4 | URL-роутер /{city}/{path}/ |
cp-83m | done |
| S5 | Глобальные фильтры (the_title/URL/rest_url) |
cp-i17 | done |
| S6 | CI workflow + manual QA checklist | cp-la7 | done |
| S7 | Gitea release + plugin-update-checker | cp-7cf | done |
Эпик: cp-cw4 — MVP CLOSED.
Источник
Плагин — переработка кастомной мультигородской подсистемы темы washanyanya
(1555 строк inc/town-functions.php) в переиспользуемый плагин для других проектов.
Лицензия
GPLv2 или новее.