В общих чертах:
1. Конфигурируете сервер чтобы обрабатывал example.ru и *.example.ru как один и тот же WP-сайт
2. В wp-config.php устанавливаете урлы сайта с помощью констант (они имеют приоритет над значениями из БД), а значения этих констант устанавливаете динамически на ходу, в зависимости от запрашиваемого адреса:
define( 'WP_HOME', $_SERVER['SERVER_NAME'] );
define( 'WP_SITEURL', $_SERVER['SERVER_NAME'] );
3. В том же конфиге добавляете для удобства еще одну константу, скажем, SUBDOMAIN. Берем $_SERVER['SERVER_NAME'], достаем из него имя субдомена и кладем в эту константу.
4. Далее, в нужных местах берете значение этой константы и действуете по обстоятельствам. Например, хукаетесь в фильтр the_title и модифицируете название, исходя из значения константы.
5. С sitemap, возможно, придется повозиться чуть дольше. Но каких-то особых проблем быть не должно.
6. Возможно, в процессе отладки вылезут какие-то еще мелкие нюансы, но вряд ли что-то серьезное.
UPDATE:
Обдумывал идею, пришло в голову вот еще что - надо уменьшить повторение кода в тех местах, где данные будут модифицироваться в зависимости от значения константы SUBDOMAIN. Я бы засетапил какой-нибудь массив, в котором ключами будут выступать как раз значения поддоменов, а значениями массива - необходимые данные. Где его хранить, в БД или в конфиге - не принципиально. Что-то типа:
$data = [
'moskva' => [
'name' => 'Москва',
'term_id' => 11, // ID термина таксономии cities, которая может использоваться для группировки контента, это позволит на "подсайтах" показывать только релевантный контент
'title_suffix' => ' в Москве и области', // динамическая часть тайтла сайта / страниц
...
],
'spb' => [
...
],
...
];
Ну и получать доступ к этим данным:
$title = $title . $data[ SUBDOMAIN ]['title_suffix'];