搜索了一下,我想我现在可以帮你了。
1。注册 location taxonomy 以创建基础归档 slug:
function wpso36667674_register_location_taxonomy() {
$labels = [
'name' => _x('Locations', 'Taxonomy General Name', 'wpso'),
'singular_name' => _x('Location', 'Taxonomy Singular Name', 'wpso'),
'all_items' => __('All Locations', 'wpso'),
];
$args = [
'labels' => $labels,
'public' => true,
'hierarchical' => true,
'rewrite' => ['hierarchical' => true],
];
register_taxonomy('location', 'listing', $args);
}
add_action('init', 'wpso36667674_register_location_taxonomy', 0);
我们必须将 WordPress 自动生成的术语 slug 更改为净化术语名称,以便 URL 的结构看起来如您所愿:
function wpso36667674_filter_term_link($term_link, $term, $taxonomy) {
$term_link = rtrim($term_link, '/');
$pos = strrpos($term_link, '/');
$term_link = substr($term_link, 0, $pos + 1) . sanitize_title($term->name);
return $term_link;
}
add_filter('term_link', 'wpso36667674_filter_term_link', 0, 3);
注意:添加新词时不要手动输入词条,让WordPress为我们生成,否则我们将无法正确查询词条的帖子内容。原因是两个 URL:location/usa/ohio/cleveland 和 location/usa/idaho/cleveland 给了我们相同的帖子,因为 WordPress 只使用cleveland 作为查询帖子内容的术语,而不关心父术语。
2。像这样注册listing帖子类型:
function wpso36667674_register_listing_post_type() {
$labels = [
'name' => _x('Listings', 'Taxonomy General Name', 'wpso'),
'singular_name' => _x('Listing', 'Taxonomy Singular Name', 'wpso'),
'all_items' => __('All Listings', 'wpse'),
];
$args = [
'labels' => $labels,
'public' => true,
'menu_icon' => 'dashicons-location-alt',
'menu_position' => 6,
'supports' => ['title', 'editor', 'thumbnail', 'custom-fields'],
'taxonomies' => ['location'],
'rewrite' => ['slug' => '%country%/%state%/%city%/%zip%'],
];
register_post_type('listing', $args);
}
add_action('init', 'wpso36667674_register_listing_post_type', 0);
我们不确定列表是否包含 state|city|zip,因此我们必须使用替代 (%country%/%state%/%city%/%zip%)。然后用每个列表元数据替换它(根据我使用 WordPress 的经验,您应该在每个列表中存储位置数据):
function wpso36667674_filter_post_link($post_link, $post, $leave_name = false, $sample = false) {
$zip = get_post_meta($post->ID, 'geolocation_postcode', true);
$city = get_post_meta($post->ID, 'geolocation_city_short', true);
$state = get_post_meta($post->ID, 'geolocation_state_short', true);
$country = get_post_meta($post->ID, 'geolocation_country_short', true);
$post_link = str_replace('%zip%', $zip, $post_link);
$post_link = str_replace('%city%', $city, $post_link);
$post_link = str_replace('%state%', $state, $post_link);
$post_link = str_replace('%country%', $country, $post_link);
$post_link = preg_replace('/[^:](\/{2,})/', '/', $post_link); // Remove multiple forward slashes except http://.
return $post_link;
}
add_filter('post_type_link', 'wpso36667674_filter_post_link', 0, 4);
注意:如果您使用大写短名称,则在修改 URL 结构时必须将其转换为小写。
3。添加重写规则以使我们的自定义 URL 正常工作。
// Add rewrite rules for location taxonomy.
function wpso36667674_add_location_rewrite_rules() {
add_rewrite_rule('^location/([^/]+)/?$', 'index.php?taxonomy=location&term=$matches[1]', 'top');
add_rewrite_rule('^location/([^/]+)/([^/]+)/?$', 'index.php?taxonomy=location&term=$matches[2]', 'top');
add_rewrite_rule('^location/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?taxonomy=location&term=$matches[3]', 'top');
}
add_action('init', 'wpso36667674_add_location_rewrite_rules', 0);
// Add rewrite rules for listings.
function wpso36667674_add_listing_rewrite_rules() {
add_rewrite_rule('^usa/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[1]', 'top');
add_rewrite_rule('^usa/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[2]', 'top');
add_rewrite_rule('^usa/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[3]', 'top');
add_rewrite_rule('^usa/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[4]', 'top');
add_rewrite_rule('^mexico/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[1]', 'top');
add_rewrite_rule('^mexico/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[2]', 'top');
add_rewrite_rule('^mexico/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[3]', 'top');
add_rewrite_rule('^mexico/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[4]', 'top');
add_rewrite_rule('^canada/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[1]', 'top');
add_rewrite_rule('^canada/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[2]', 'top');
add_rewrite_rule('^canada/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[3]', 'top');
add_rewrite_rule('^canada/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=listing&name=$matches[4]', 'top');
}
add_action('init', 'wpso36667674_add_listing_rewrite_rules', 0);
4。返回正确术语的 slug:
正如我所说,通过在永久链接中将usa/idaho/cleveland-idaho 更改为usa/idaho/cleveland,usa/idaho/cleveland 的查询帖子与usa/ohio/cleveland 相同。所以我们必须帮助 WordPress 知道什么是用于查询帖子内容的正确术语 slug:
function wpso36667674_modify_requested_url($query) {
if ( $query->query_vars['taxonomy'] === 'location' ) {
$slugs = array_filter( explode('/', $query->request) );
$term = array_pop($slugs) . '-' . array_pop($slugs);
if ( get_term_by('slug', $term, 'location') ) {
$query->query_vars['term'] = $term;
}
}
}
add_action('parse_request', 'wpso36667674_modify_requested_url');
感谢@Jevuska 建议使用parse_request。
5。为每个存档位置创建自定义模板:
感谢WordPress Template Hierarchy,我们可以轻松搞定。
例子:
对于location/usa/ohio,模板为taxonomy-location-ohio.php。
但请记住,我们必须使用由 WordPress 生成的实际术语的 slug,而不是我们在 URL 中修改的内容。
例子:
如果在爱达荷州的克利夫兰之前添加俄亥俄州的克利夫兰,则第一个术语 slug 是 cleveland,第二个将是 cleveland-idaho。
那么,第一个模板是taxonomy-location-cleveland.php,第二个模板是taxonomy-location-cleveland-idaho.php。
就是这样!您可以直接放入functions.php 文件中的所有代码。记得刷新永久链接设置。