更改自定义帖子类型的固定链接结构

时间:2016-02-01 作者:3ky

我有两种自定义帖子类型:softwarehardware. 出于搜索引擎优化的原因,我希望拥有softwarehardware 页面如下:

https://domain.com/custom-post-name/
但默认情况下,WordPress会在其上添加post type slug,如:

https://domain.com/post-type-slug/custom-post-name/
我已经用following script 这将替换字符串。现在,可以使用上面描述的URL访问单个页面,并且Google搜索控制台可以找到两个内容完全相同的页面,这对SEO不好。有没有可能改变permalink的完整结构并去掉定制的post类型slug?

register_post_type( \'hardware\',
    array (
        \'labels\' => $labels,
        \'has_archive\' => true,
        \'public\' => true,
        \'supports\' => array( \'title\', \'editor\', \'excerpt\', \'custom-fields\', \'thumbnail\' ),
        \'taxonomies\' => array( \'hardware-post_tag\', \'hardware-category\' ),
        \'exclude_from_search\' => false,
        \'capability_type\' => \'post\',
        \'rewrite\' => array( \'slug\' => \'hardware\' ),
    )
);
<小时>

4 个回复
SO网友:Mikhail

请注意上述答案的一个重要方面:

虽然它从一开始就可以正常工作,但它会导致性能问题。所有这些代码都将被调用init 钩子,这样每次页面加载都会导致它运行flush_rules() 时间很贵。

因此,建议仅在激活主题\\插件时调用刷新规则。您还可以使用add_permastruct 无需访问的功能global $wp_rewrite

最终改进的解决方案是:

add_action(\'init\', \'my_custom_rewrite\'); 
function my_custom_rewrite() {

    add_permastruct(\'hardware\', \'/%customname%/\', false);
    add_permastruct(\'produkt\', \'/%customname%/\', false);
}

add_filter( \'post_type_link\', \'my_custom_permalinks\', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
      return str_replace( \'%customname%/\', $post->post_name, $permalink );
}

 /* in case for plugin */
register_activation_hook(__FILE__,\'my_custom_plugin_activate\');
function my_custom_plugin_activate() {
    flush_rewrite_rules();
}


/* in case of custom Theme in Functions.php */
add_action(\'after_switch_theme\', \'mytheme_setup\');
function mytheme_setup () {
    flush_rewrite_rules();
}

SO网友:WoodrowShigeru

我设法用{$field_no_prefix}_save_pre 具有post_name.

/**
 * Customize permalinks.
 *
 * @param string $post_name
 *
 * @return string
 *   Returns a name-SKU combo for products, if all components are available.
 */
function my_custom_permalinks( $post_name ) {

    if (
        ($_POST[\'post_type\'] !== \'product\')
    ||  ($_POST[\'post_status\'] === \'auto-draft\')
    ) {
        return $post_name;
    }

    $post_name = sanitize_title_with_dashes(
        { modify $_POST[\'post_title\'] as you please }
    );

    return $post_name;
}
add_filter(\'name_save_pre\', \'my_custom_permalinks\', 1, 1);

SO网友:3ky

已解决

使用$wp_rewrite 您可以添加新的永久链接结构

add_action(\'init\', \'my_custom_rewrite\');
function my_custom_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_permastruct(\'hardware\', \'/%customname%/\', false);
    $wp_rewrite->add_permastruct(\'produkt\', \'/%customname%/\', false);
    $wp_rewrite->flush_rules();
}
然后将自定义标记替换为str_replace 筛选链接url时

add_filter( \'post_type_link\', \'my_custom_permalinks\', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
    return str_replace( \'%customname%/\', $post->post_name, $permalink );
}
NOTE: if you use this function the way is written (removing the post type slug from permalink) you can expect bad issues cause there is no control if you make a custom post permalink the same as a page or standard post

SO网友:joshjellel

任何遇到这个问题的人,都会遇到与;以下脚本“;问题中提到的链接,下面是脚本courtesy of the Wayback Machine, 更正了我认为是代码中的错误:

/**
 * Remove the slug from published post permalinks. Only affect our CPT though.
 */
function vipx_remove_cpt_slug( $post_link, $post, $leavename ) {
    if ( ! in_array( $post->post_type, array( \'your_post_type\' ) ) || \'publish\' != $post->post_status )
        return $post_link;
    $post_link = str_replace( \'/\' . $post->post_type . \'/\', \'/\', $post_link );
    return $post_link;
}
add_filter( \'post_type_link\', \'vipx_remove_cpt_slug\', 10, 3 );

function vipx_parse_request_tricksy( $query ) {
    // Only noop the main query
    if ( ! $query->is_main_query() )
        return;
    // Only noop our very specific rewrite rule match
    if ( 2 != count( $query->query )
        || ! isset( $query->query[\'page\'] ) )
        return;
    // \'name\' will be set if post permalinks are just post_name, otherwise the page rule will match
    if ( ! empty( $query->query[\'name\'] ) )
        $query->set( \'post_type\', array( \'post\', \'your_post_type\', \'page\' ) );
}
add_action( \'pre_get_posts\', \'vipx_parse_request_tricksy\' );
随着Mikhail对3ky自身解决方案的修订,如果像我一样,您对它不是很清楚,我发现有必要实现vipx_parse_request_tricksy() 功能和相应的操作。但是vipx_remove_cpt_slug() 函数复制了什么my_custom_permalinks() 是的,所以两个都不必选一个?

相关推荐

Force pretty permalinks?

我正在构建一个插件,该插件将用于单个站点,并依赖于add_rewrite_rule 要工作,需要打开永久链接。打开它们并不困难,因为它只是一个站点,但我担心其中一个管理员可能会在不知道自己在做什么的情况下关闭它,并破坏该站点。如何以编程方式强制保持漂亮的永久链接?