由CF生成的URL好吧,您可以通过多种方式实现这一点。。。其中之一就是使用parse_request
过滤和修改它的行为,但它很容易搞糟一些事情。
另一种方法是使用save_post
操作并修改帖子post_name
, 所以WordPress会像正常一样工作,但是post_name
将根据自定义字段而不是标题生成。这就是我想要的解决方案。为什么?因为你可以使用WP函数来确保链接是唯一的。。。
下面是代码:
function change_post_name_on_save($post_ID, $post, $update ) {
global $wpdb;
$post = get_post( $post_ID );
$cf_post_name = wp_unique_post_slug( sanitize_title( \'s\' . get_post_field(\'foo\', $post_ID), $post_ID ), $post_ID, $post->post_status, $post->post_type, $post->post_parent );
if ( ! in_array( $post->post_status, array( \'publish\', \'trash\' ) ) ) {
// no changes for post that is already published or trashed
$wpdb->update( $wpdb->posts, array( \'post_name\' => $cf_post_name ), array( \'ID\' => $post_ID ) );
clean_post_cache( $post_ID );
} elseif ( \'publish\' == $post->post_status ) {
if ( $post->ID == $post->post_name ) {
// it was published just now
$wpdb->update( $wpdb->posts, array( \'post_name\' => $cf_post_name ), array( \'ID\' => $post_ID ) );
clean_post_cache( $post_ID );
}
}
}
add_action( \'save_post\', \'change_post_name_on_save\', 20, 3 );
它不是最漂亮的,因为ACF字段保存在帖子之后,所以您必须覆盖
post_name
帖子保存后。但它应该工作得很好。
根目录中的CPT,还有问题的第二部分:如何在没有CPT slug的情况下创建CPTs URL。。。
WordPress使用重写规则来解析请求。这意味着,如果请求与其中一条规则匹配,则将使用该规则对其进行解析。
页面规则是为捕获大多数与任何早期规则都不匹配的请求而制定的最后一条规则之一。所以,如果您添加没有任何slug的CPT,那么页面规则将不会启动。。。
解决这个问题的一种方法是用slug注册CPT,然后更改它们的链接和WPs行为。代码如下:
function register_mycpt() {
$arguments = array(
\'label\' => \'MyCPT\',
\'public\' => true,
\'hierarchical\' => false,
...
\'has_archive\' => false,
\'rewrite\' => true
);
register_post_type(\'mycpt\', $arguments);
}
add_action( \'init\', \'register_mycpt\' );
现在,这些帖子的URL如下所示:
http://example.com/mycpt/{post_name}/
但我们可以使用
post_type_link
过滤器:
function change_mycpt_post_type_link( $url, $post, $leavename ) {
if ( \'mycpt\' == $post->post_type ) {
$url = site_url(\'/\') . $post->post_name . \'/\';
}
return $url;
}
add_filter( \'post_type_link\', \'change_mycpt_post_type_link\', 10, 3 );
现在URL将是正确的,但是。。。他们不会工作的。它们将使用页面重写规则进行解析,并将导致404错误(因为没有包含此类URL的页面)。但我们也可以解决这个问题:
function try_mycpt_before_page_in_parse_request( $wp ) {
global $wpdb;
if ( is_admin() ) return;
if ( array_key_exists( \'name\', $wp->query_vars ) ) {
$post_name = $wp->query_vars[\'name\'];
$id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s ",
\'mycpt\', $post_name
) );
if ( $id ) {
$wp->query_vars[\'mycpt\'] = $post_name;
$wp->query_vars[\'post_type\'] = \'mycpt\';
}
}
}
add_action( \'parse_request\', \'try_mycpt_before_page_in_parse_request\' );