背景
我正在为学校建立课程目录,并试图创建友好的动态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
......其中“画廊”是静态名称,并显示画廊自定义帖子类型。
答案 0 :(得分:1)
经过大量调查,我找到了问题的答案。在这里。
这是在WordPress中创建真正的动态URL /段的方法。 URL与页面不对应。相反,该条的各个部分用于查找帖子ID,然后相应地呈现该帖子。
function pce_rewrite_rules ( ) {
add_rewrite_rule ( '^class/([^/]*)/([^/]*)/([^/]*)/?', 'index.php?post_type=section&catalog_name=$matches[1]&course_name=$matches[2]§ion_no=$matches[3]','top' ) ;
add_action ( 'init', 'pce_rewrite_rules', 10, 0 ) ;
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' );
使用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);
我希望它能对您有所帮助。如果没有,请告诉我您是如何建立关系的。