如何将WordPress自定义文章类型固定链接改为标题+自定义字段值
问题描述
我正在搭建流媒体网站,创建了名为watch的自定义文章类型(Custom Post Type),文章页面内设有eps_num自定义字段。当创建标题为Super Natural的新文章时,文章固定链接为www.website.com/watch/Super-Natural/,对应eps_num值为01;若创建同标题的新文章,默认固定链接为/watch/Super-Natural-1/,而该文章的eps_num值为05。我希望将固定链接修改为/watch/Super-Natural-05/,即固定链接由文章标题加上eps_num自定义字段值组成。
已尝试的代码
代码段1
add_filter( 'post_type_link', 'wpse_64285_external_permalink', 10, 2 ); function wpse_64285_external_permalink( $link, $post ) { $meta = get_post_meta( $post->ID, 'eps_eps-num', TRUE ); $url = esc_url( filter_var( $meta, FILTER_VALIDATE_URL ) ); return $url ? $url : $link; }
代码段2
add_filter( 'pt_cv_ctf_value', 'cpt_link_to_cfv', 100, 3 ); function cpt_link_to_cfv( $args, $key, $post ) { if ( $key == 'eps_eps-num' ) { $args = sprintf( '<a href="%s">%s</a>', get_permalink( $post ), $args ); } return $args; }
解决方案
要实现将watch类型文章的固定链接改为「标题-eps_num」的格式,需要通过post_type_link过滤器修改 permalink 结构,同时处理文章保存时的 slug 生成逻辑,确保自定义字段值被正确纳入:
步骤1:修改固定链接生成逻辑
添加以下代码到主题的functions.php文件或自定义插件中:
add_filter('post_type_link', 'custom_watch_permalink', 10, 2); function custom_watch_permalink($link, $post) { // 仅针对watch自定义文章类型处理 if ($post->post_type === 'watch') { // 获取eps_num自定义字段值,注意字段名要和实际一致 $eps_num = get_post_meta($post->ID, 'eps_num', true); // 如果存在eps_num值,替换permalink中的slug部分 if (!empty($eps_num)) { // 获取文章标题的slug形式 $slug = sanitize_title($post->post_title); // 构建新的permalink:watch/标题slug-eps_num/ $link = home_url('/watch/' . $slug . '-' . $eps_num . '/'); } } return $link; }
步骤2:处理文章保存时的slug生成
上述代码能修改显示的 permalink,但还需确保文章保存时,slug自动设置为「标题slug-eps_num」,避免WordPress自动添加默认序号(如-1)。添加以下代码:
add_action('save_post', 'set_custom_watch_slug', 10, 2); function set_custom_watch_slug($post_id, $post) { // 跳过自动保存、修订版本,仅针对watch类型文章 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $post->post_type !== 'watch' || $post->post_status === 'auto-draft') { return; } // 获取eps_num值 $eps_num = get_post_meta($post_id, 'eps_num', true); if (!empty($eps_num)) { $slug = sanitize_title($post->post_title) . '-' . $eps_num; // 检查slug是否已存在,避免冲突 $existing_post = get_page_by_path($slug, OBJECT, 'watch'); if (!$existing_post || $existing_post->ID === $post_id) { // 更新文章slug wp_update_post(array( 'ID' => $post_id, 'post_name' => $slug )); } } }
关键注意事项
- 字段名匹配:代码中使用的字段名是
eps_num,如果你的实际自定义字段名是eps_eps-num,请将代码中所有eps_num替换为eps_eps-num。 - 刷新固定链接规则:添加代码后,进入WordPress后台「设置-固定链接」页面,点击「保存更改」,确保新的permalink规则生效。
- slug冲突处理:若存在同标题同
eps_num的文章,需要额外添加冲突处理逻辑(如在slug后追加序号),建议保证同标题下eps_num唯一,避免重复。
内容的提问来源于stack exchange,提问作者Mohamed Omar
相关产品推荐
相关产品推荐

