花哨的URL结构,条件内容和搜索 - 使用CPT,自定义字段和分类

时间:2016-04-16 17:56:26

标签: wordpress wordpress-theming permalinks custom-fields custom-taxonomy

我们正在3个国家/地区建立汽车相关业务目录 - 美国,加拿大和墨西哥。

我创建了一个自定义帖子类型'列表'并尝试继续以下。

对于各种SEO目的,我们需要特定的URL结构如下:

1)个人列表页

没什么太花哨的 - domain.com/usa/listing-slug

2)每州档案

没什么太好看的 - domain.com/usa/texas

3)每个城市的档案

这个更有意思,我们需要以下结构:

  • domain.com/usa/cleveland/oh
  • domain.com/usa/cleveland/nd

第一个是俄亥俄州克利夫兰的档案馆,另一个是内华达州克利夫兰的档案馆。

4)每ZIP存档

非常平常 - domain.com/usa/05657

5)混合位置类别档案

  • domain.com/usa/cleveland/oh/car-parts
  • domain.com/usa/ohio/car-parts
  • domain.com/usa/05657/car-parts

6)以上所有存档页面的自定义内容(模板),可能是ZIP

我们试图模仿this website

如果你检查一下,我们可以说,俄亥俄州克里夫兰市和内华达州克里夫兰市的相同例子:http://www.familydaysout.com/kids-things-to-do-usa/cleveland/ohhttp://www.familydaysout.com/kids-things-to-do-usa/cleveland/nd你会明白我的意思 - 这些页面有开头的自定义内容(描述)。

以上是每个城市的自定义内容示例。对于每状态http://www.familydaysout.com/kids-things-to-do-usa/ohio和混合存在相同的情况: http://www.familydaysout.com/kids-things-to-do-usa/ohio/major-theme-parks http://www.familydaysout.com/kids-things-to-do-usa/cleveland/oh/major-theme-parks http://www.familydaysout.com/kids-things-to-do-usa/5601/major-theme-parks

我在添加新商家信息时可以自动填充位置数据,因此当我粘贴完整地址时,例如" 21200 Saint Clair Avenue Euclid,Ohio 44117"保存我明白了:

automatically populated custom fields

如您所见,国家,州,城市和邮政都在那里。类别(汽车零件)也作为列表类别。

现在我如何使用这些值来构建档案的URL和页面/模板?我应该自动将自定义字段值转换为自定义分类法并从那里开始吗?我知道我可以使用https://codex.wordpress.org/Plugin_API/Action_Reference/save_posthttps://codex.wordpress.org/Function_Reference/wp_set_object_terms

执行此操作

我知道自定义分类法可以有描述,我知道如何输出这些描述。除此之外,分类法可以是等级的,所以我可以将俄亥俄州和内华达州作为父母,每个克利夫兰作为他们的孩子。

所以,我设法收集并存储所有信息位,但不知道如何开始操作它们以实现上述模型。

Q1 :我应该在哪里存储位置数据(国家,州,城市,邮政编码),以便能够在URL中使用它,如上所述?自定义字段或分类术语?

Q2 :如何按照我为其自定义模板的方式构建存档页面/模板?

任何其他有用的提示都将受到高度赞赏。

3 个答案:

答案 0 :(得分:5)

搜索后,我想我现在可以帮到你。

1。注册location分类以创建基本存档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);

警告:在添加新字词时不要手动输入字词'slug,让WordPress为我们生成它,否则我们将无法正确查询字词的帖子内容。原因是两个网址:location/usa/ohio/clevelandlocation/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);

我们不确定该列表是否具有州| zip | 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。返回正确的术语'slugs:

正如我所说,在永久链接中将usa/idaho/cleveland-idaho更改为usa/idaho/clevelandusa/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生成的实际术语'slugs,而不是我们在URL中修改的那些。

示例:

如果俄亥俄州的克利夫兰在爱达荷州的克利夫兰之前被加入,那么第一个的slug是cleveland,第二个是cleveland-idaho

然后,第一个模板为taxonomy-location-cleveland.php,第二个模板为taxonomy-location-cleveland-idaho.php

这就是全部!您可以将所有代码直接放在functions.php文件中。请记住也要刷新永久链接设置。

答案 1 :(得分:0)

根据您的要求,您可以通过创建如下所述的类别来实现此目的:

  

domain.com/usa/cleveland/ohdomain.com/usa/cleveland/nd

  1. 俄亥俄州克利夫兰(/ usa / cleveland / oh)
  2. 内华达州克利夫兰(/ usa / cleveland / nd)
  3. 所以创建一个父类别为" USA"然后是儿童类别"克利夫兰"并且在这一个以下的儿童类别中,"俄亥俄州"和它的slu is一样,"哦"。

    所以层次结构应该是USA->Cleveland->Ohio,而slug应该是usa->cleveland->oh

    同样,USA->Cleveland->Nevada和slugs为usa->cleveland->nd

    现在,对于要在URL上显示的帖子:

    1. domain.com/category/usa =提供他们" USA"类别
    2. domain.com/category/usa/cleveland/ =提供他们"克利夫兰" 类别
    3. domain.com/category/usa/cleveland/oh =提供他们"俄亥俄州"     类
    4. 现在您只需要从网址中删除category即可。因此,请在位于根文件夹中的.htaccess文件中编写以下代码。

      RewriteRule . /wordpress/index.php [L]
      

答案 2 :(得分:0)

我认为有两种方法可以解决您的问题 第一个是使用mod_rewrite传输建议的格式化URL以关联模板php文件,并以您希望的方式处理您的请求。 对于以下链接可能会有所帮助。谷歌更多https://www.addedbytes.com/articles/for-beginners/url-rewriting-for-beginners/

第二种方法是遵循wordpress页面模板层次结构并相应地创建模板页面并在模板php中处理类似的请求。有关详细说明,请参阅https://www.smashingmagazine.com/2015/06/wordpress-custom-page-templates/

和快速页面模板层次结构,以了解将针对特定网址执行哪个页面模板,请参阅https://media-mediatemple.netdna-ssl.com/wp-content/uploads/2015/05/01-wp-template-hierarchy-opt.jpg