WordPress中的动态网址

时间:2019-03-04 00:21:49

标签: php wordpress custom-wordpress-pages

背景

我正在为学校建立课程目录,并试图创建友好的动态URL。它具有三种自定义帖子类型:

  • 目录。
  • 课程。该帖子类型包含标题,课程编号和课程说明。
  • 部分。该帖子类型包含费用,开始和结束日期和时间等。例如,可能有两个部分供初学者使用,一个在星期四上午,一个在星期一晚上,由两个不同的老师教授。

课程与部分之间存在一对多的关系。查看部分时,它会显示父课程的课程名称,课程编号和课程说明。它还显示该部分的费用,开始和结束日期和时间等。

部分的当前URL是这样:

http://website.org/section/section-slug/

我希望是这样:

http://website.org/class/spring-2019/drawing-for-beginners/01/

......,其中“类”是“虚拟”文件夹/合成前缀 ...其中“ 2019年春季”对应于“目录”自定义帖子类型 ...其中“初学者绘画”对应于父级“课程”自定义帖子类型的子弹 ...其中“ 01”对应于课程的部分。

WordPress应该显示与这些条件匹配的栏目类型。

研究

我已经阅读了很多有关Rewrite API和Endpoints API的文章。我能找到最接近我要完成的主题的最佳文章是this one。可悲的是,页面上的示例代码对我不起作用,导致“重定向过多”。如果需要,我可以提供有关哪个部分不起作用的更多详细信息。我也读过this article on Make WordPress Plugins,但它不涉及动态查找。

我要完成的任务

http://website.org/class/spring-2019/drawing-for-beginners/01/

当将虚拟URL提供给WordPress时,我需要系统执行查询以查找编号为“ 01”且属于“ spring-2019”目录且其父课程中有slug的部分“初学者绘画”。该查询不是一个挑战,它是执行该代码并返回正确的模板(适用于分页)所需的所有挂钩。我不确定是需要创建端点还是可以摆脱添加重写规则的麻烦。

有人可以提供一些指导吗?

-

作为“奖励”,我也在努力做到这一点:

http://website.org/class/spring-2019/drawing-for-beginners/01/faculty_name

......,其中“ faculty_name”是动态的,是教该节的人员的姓名(并对应于“ faculty”自定义帖子类型)。

http://website.org/class/spring-2019/drawing-for-beginners/01/gallery

......其中“画廊”是静态名称,并显示画廊自定义帖子类型。

2 个答案:

答案 0 :(得分:1)

经过大量调查,我找到了问题的答案。在这里。

这是在WordPress中创建真正的动态URL /段的方法。 URL与页面不对应。相反,该条的各个部分用于查找帖子ID,然后相应地呈现该帖子。

步骤1:添加重写规则

function pce_rewrite_rules ( ) {
  add_rewrite_rule ( '^class/([^/]*)/([^/]*)/([^/]*)/?', 'index.php?post_type=section&catalog_name=$matches[1]&course_name=$matches[2]&section_no=$matches[3]','top' ) ;
add_action ( 'init', 'pce_rewrite_rules', 10, 0 ) ;

第2步:注册查询变量

function pce_register_query_vars ( $vars ) {
    $vars[] = 'course_name';
    $vars[] = 'catalog_name';
    $vars[] = 'section_no';

    return $vars;
}
add_filter ( 'query_vars', 'pce_register_query_vars' );

步骤3:修改WP查询

使用pre_get_posts修改主查询。但是您必须在查询中强制使用一些变量,以便WordPress加载所需的模板。为了找到我需要手动设置的变量,我使用了WP插件(查询监视器)来检查WP查询的内容,并对要“复制”的帖子类型使用了var_dump

function pce_dynamic_section_lookup ( $wp ) {

    if ( is_admin() || ! $wp->is_main_query() ){
        return;
    }

    if ( $wp->is_main_query() ) {
        // Only defined if we're looking at a "fake" URL.
        // Example: http://pce.local/class/spring-2019/handmade-books/01/
        if ( get_query_var ('course_name' ) ) {
            // These are some of the variables I needed to set manually.
            $wp->query_vars['post_type'] = 'section' ;
            $wp->query_vars['is_single'] = true ;
            $wp->query_vars['is_singular'] = true;
            $wp->query_vars['is_archive'] = false;

            $course_name = get_query_var ('course_name' ) ;
            $catalog_name = get_query_var ('catalog_name' ) ;
            $section_no = get_query_var ('section_no' ) ;

            // More code is here to look up the post ID I need.

            // Set the post ID here. This makes the magic happen.
            $wp->query_vars['p'] = $post_id ;

            // This also makes the magic happen. It forces the template I need to be selected.
            $wp->is_single = true ;
            $wp->is_singular = true ;
            $wp->is_archive = false ;
            $wp->is_post_type_archive = false ;
        }
    }
}
add_action ( 'pre_get_posts', 'pce_dynamic_section_lookup', 0, 2 ) ;

我有一个帖子使用了原始网址:

http://pce.local/section/handmade-books-01/

现在我可以在此URL上加载它(并且它加载它不会转发它):

http://pce.local/class/spring-2019/handmade-books/01/

我需要这样做,因为将来的目录中将添加多个部分,并且我想保持URL友好。在夏季,如果提供课程,它将是...

http://pce.local/class/summer-2019/handmade-books/01/

而不是...

http://pce.local/section/handmade-books-01-2/

或WordPress分配的任何笨拙的。只有几个部分没什么大不了,但将来还会有几个。

答案 1 :(得分:0)

如果我理解不错,这可能会对您有所帮助。 我不确定你是如何建立关系的,但是我会把我通常使用的代码。可以说目录课程也有关系。

function add_rewrite_rules( $wp_rewrite )
{

    $section_rules = array(
        'class/(.+?)/?$' => 'index.php?post_type=post&name='. $wp_rewrite->preg_index(1),
    );

    $wp_rewrite->rules = $section_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules'); 

function change_section_links($post_link, $id=0){

    $courses = new WP_Query( array(
        'post_type' => 'course',
        'post__in' => get_post_meta( $catalog_id, '_course', true ),
    ) );

    if ( $courses-> have_posts() ) { while ( $courses->have_posts() ) {
          $courses->the_post();
          $catalog_name = get_the_title();  
        }

    $sections = new WP_Query( array(
        'post_type' => 'section',
        'post__in' => get_post_meta( $course_id, '_section', true ),
    ) );

        if ( $sections-> have_posts() ) { while ( $sections->have_posts() ) {
                  $sections->the_post();
                  $course_name = get_the_title();  
            }

    $post = get_post($id);

    if( is_object($post) && $post->post_type == 'section'){
        return home_url('/class/'. $catalog_name. '/'. $course_name. '/'. $post->post_name.'/');
    }

    return $post_link;
}
add_filter('post_link', 'change_section_links', 1, 3);

我希望它能对您有所帮助。如果没有,请告诉我您是如何建立关系的。