wordpress – 如何根据语言重写自定义帖子类型slugs?

我正在使用WordPress构建一个网站,使用它更像CMS,然后是博客平台.我充分利用了自定义帖子类型和自定义分类法.最后但并非最不重要的是,我使用WPML插件使其成为多语言.

在CPT声明期间,我将字符串和slugs包装在gettext中,以便在WPML中准备它们.

CPT声明的一个例子如下:

register_post_type('rooms',
    array(
        'label' => __('Rooms','valletta'),
        'description' => __('','valletta'),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'capability_type' => 'post',
        'hierarchical' => true,
        'rewrite' => array('slug' => __('rooms','valletta')),
        'query_var' => true,
        'exclude_from_search' => false,
        'menu_position' => 25,
        'supports' => array('title','editor','excerpt','custom-fields','comments',),
        'taxonomies' => array('features','typology',),
        'labels' => array (
            'name' => __('Rooms','valletta'),
            'singular_name' => __('room','valletta'),
            'menu_name' => __('Rooms','valletta'),
            'add_new' => __('Add room','valletta'),
            'add_new_item' => __('Add New room','valletta'),
            'edit' => __('Edit','valletta'),
            'edit_item' => __('Edit room','valletta'),
            'new_item' => __('New room','valletta'),
            'view' => __('View room','valletta'),
            'view_item' => __('View room','valletta'),
            'search_items' => __('Search Rooms','valletta'),
            'not_found' => __('No Rooms Found','valletta'),
            'not_found_in_trash' => __('No Rooms Found in Trash','valletta'),
            'parent' => __('Parent room','valletta'),
        )
    )
);

正如你所看到的,我也包裹了slug术语,这对我来说非常有意义.我想要实现的是当用户访问意大利语的“标准”网站时,通过/ camere / nome-camera /到达房间CPT页面,而英语用户则通过/ rooms / room-name /获得它.这对于意大利语言来说很顺利,WPML正确翻译了英文版本的slug,所以如果我在意大利网站上查看房间CPT并且我切换到英文版本,WordPress被带到/ rooms /唯一的问题就是它显示404.

我检查了WPML网站,他们承认slug翻译仍然是一项正在进行中的工作,并且是一个可以在下一版插件中发布的功能.好没关系.

我正在努力实现的目标是在WPML更新插件时使用黑客.我的想法是在我的.htaccess中有一些自定义重写规则,并对这些CPT页面进行URL重写.我认为我可以删除slug翻译,以便为两种语言都有一个slug然后有一个重写规则,当有人输入翻译的slug时,取而代之的是“标准”,但至少内容是正确的,并且:a)用户不会注意到任何东西,因为浏览器不会重定向页面,只是重写URL而b)WP没有任何变化(或者它确实??).

所以问题是:我怎么能做到这一切?删除slug转换很好,只是在WPML后端删除,但我对重写规则等不太满意所以我正在寻找帮助我实现目标的人,并最终展示出更好的方法来实现目标我需要(如果我的想法有意义,自然会得到反馈).

抱歉,如果我错过了什么.如果您需要更多信息我会在这里给他们.

最佳答案 基本上,我认为在每个页面加载上运行flush_rewrite_rules()会让你按照你想要的方式本地化页面slug,但是这是一个非常糟糕的解决方案,因为它也会在每个页面加载时写入.htaccess文件,这会极大地减慢事情的速度一旦有多个用户访问该网站,可能会给出非常奇怪的结果.看看
documentation,看来你可以提供false作为第一个参数,它禁用.htaccess的写入,但这仍然不是一个好的解决方案,因为文档还说明了以下内容:

Important: Flushing the rewrite rules is an expensive operation, there
are tutorials and examples that suggest executing it on the ‘init’
hook. This is bad practice. Instead you should flush rewrite rules on
the activation hook of a plugin, or when you know that the rewrite
rules need to be changed ( e.g. the addition of a new taxonomy or post
type in your code ).

每次我自己遇到这个问题时,我最终都使用了适用于这两种语言的permlink结构,但这也不是一个很好的解决方案.

一个好的起点可能是检查/wp-includes/rewrite.php并查看是否可以通过过滤器覆盖给定帖子类型的永久链接,并根据用户语言设置返回一个slug.另一种选择可能是尝试为每种语言添加第二个固定链接,以便自定义帖子类型中的每个帖子都可以在register_post_type中指定的固定链接以及您在其他地方指定的固定链接中使用.您可以使用WP_Rewrite或向您添加一些mod_rewrite指令.htaccess来执行此操作.在后一种情况下,这样的事情可能会起作用:

$data = 'Rewrit­eRule ^/localized-type-name/(.*)$/type-name/$1 [R,NC,L]';
// You might want to do a little more work on the actual rewrite rule, it's very much from the top of my head so it might not even work
insert_with_markers( ABSPATH . '/.htaccess', 'NAME OF YOUR MARKER', $data );
$wp_rewrite->flush_rules();

更新:您可能想要查看this thread.

点赞