rewrite某个CPT的URL
Ben
我用acf pro在我的https://xuandao.la这个网站上创建了一个叫做item的custom post type。我现在创建了一个新的post,这个post的URL类似这样:https://xuandao.la/item/xxxx/,而xxxx就是我这篇post的title。
我能不能让这个post的URL直接变成https://xuandao.la/item/1234/,而1234就是我这篇post的unique ID。
另外,我并不想在settings > permalinks那里把URL设置成“Numeric”,我还是想保持“post name”的设置
ChatGPT
要在WordPress中为特定的自定义文章类型保持“post name”的永久链接设置,同时将某个自定义文章类型的URL结构改为使用文章ID(如https://xuandao.la/item/1234/
),你可以通过添加一些自定义代码到你的主题的functions.php
文件或通过创建一个小插件来实现。下面是如何做到这一点的步骤:
第一步:为自定义文章类型添加自定义URL结构
你需要使用register_post_type
函数中的rewrite
参数为你的自定义文章类型(在这个案例中是item
)指定一个自定义的URL结构。但是,由于你想要使用文章ID而不是文章名,这一步可能需要一点不同的处理。
首先,确保当你注册item
这个自定义文章类型时,使用了合适的rewrite
规则。如果你已经注册了这个文章类型,找到注册代码的地方并确保添加了rewrite
参数。如果这是ACF PRO通过某种方式自动生成的,你可能需要通过代码手动添加一个过滤器来调整URL结构。
第二步:添加重写规则
接下来,你需要添加一个重写规则,将/item/1234/
这样的URL映射到正确的文章上。这可以通过add_rewrite_rule
函数实现。
function custom_rewrite_rule() { add_rewrite_rule('^item/([0-9]+)/?$', 'index.php?post_type=item&p=$matches[1]', 'top'); } add_action('init', 'custom_rewrite_rule');
这段代码会捕获形如/item/1234/
的URL,并将其重写为指向ID为1234的item
文章类型的文章。
第三步:刷新重写规则
在添加或修改重写规则后,你需要刷新WordPress的重写规则。这可以通过访问WordPress后台的“设置 > 固定链接”页面并点击“保存更改”按钮来实现,无需更改任何设置。这个操作会刷新重写规则,确保你的自定义规则生效。
注意事项
- 这种方法不会影响你在“设置 > 固定链接”中选择的永久链接结构,因为它只影响
item
自定义文章类型的URL结构。 - 确保在修改代码或添加新规则后测试你的网站,以确保所有东西都按预期工作,包括其他文章类型的永久链接没有被意外改变。
- 如果你的网站已经在线运营,改变URL结构可能会影响SEO和现有用户的书签。考虑设置适当的301重定向,从旧的URL结构重定向到新的结构。
这些步骤应该能够帮助你实现所需的URL结构,同时保持其他文章类型的“post name”永久链接设置不变。如果你在实施过程中遇到任何问题,请随时询问。
Ben
在你提供的第一步中,我注册item的确是通过acf pro来生成的
ChatGPT
如果你是通过ACF Pro来创建自定义文章类型(CPT)item
,那么直接在ACF Pro的界面中修改URL结构可能不是一个选项,因为ACF Pro主要关注自定义字段的管理而不是URL重写。因此,调整URL结构主要依赖于WordPress的重写规则和可能的一些附加代码。
既然item
CPT是通过ACF Pro生成的,你将需要通过添加自定义代码到你的主题的functions.php
文件或创建一个简单的插件来手动添加和管理重写规则,以实现使用文章ID作为URL的需求。
按照前面的说明,你应该已经有了添加自定义重写规则的基础。这里是一个稍微详细一点的步骤,专注于如何实现这个目标,不需要在ACF Pro中直接修改任何设置:
确保自定义文章类型正确注册
首先,确认item
自定义文章类型已经被注册。由于这是通过ACF Pro完成的,你不需要手动注册CPT,但是你需要知道CPT的slug
或标识符(在这个例案例中似乎是item
)。
添加自定义重写规则
然后,使用add_rewrite_rule
函数添加一个自定义的重写规则,就像之前提到的。这个规则将会告诉WordPress如何解析那些使用文章ID作为URL一部分的链接:
function custom_rewrite_rule() { add_rewrite_rule('^item/([0-9]+)/?$', 'index.php?post_type=item&p=$matches[1]', 'top'); } add_action('init', 'custom_rewrite_rule');
刷新重写规则
在添加了重写规则之后,通过在WordPress后台访问“设置”>“固定链接”并简单地点击“保存更改”按钮来刷新重写规则,即使你没有做任何修改。这会确保你的新规则被加入并生效。
验证
创建一个新的item
类型的文章,确保它有一个唯一的ID,然后尝试访问像https://xuandao.la/item/1234/
这样的URL,其中1234
是你的文章ID。如果一切设置正确,这应该会显示你通过ID指定的文章。
由于ACF Pro不直接涉及到URL重写,这些步骤主要通过WordPress本身的功能来实现你的需求。如果你有任何问题或需要进一步的帮助,请随时告诉我!
Ben
明白。但我不是太清楚你说的“你应该已经有了添加自定义重写规则的基础”具体是什么?或者我应该怎么知道我是否已经添加自定义重写规则的基础?
ChatGPT
当我提到“你应该已经有了添加自定义重写规则的基础”,我的意思是,根据之前的交流,我假设你对WordPress的基本操作有一定的了解,包括如何添加代码到你的网站(例如,编辑functions.php
文件或创建自定义插件)。这里的“基础”指的是这些基本的WordPress操作和管理技能,而不是指你已经具备特定的技术知识或已经实施了某些特定的功能。
如果你不确定是否已经添加了自定义重写规则或如何检查现有的重写规则,这里有几个步骤可以帮助你理解和检查:
了解WordPress重写规则
WordPress使用一套内部的重写规则来解析URL并决定展示哪个页面或文章。这些规则告诉WordPress如何将友好的URL(例如/item/1234/
)转换成它能理解的查询参数(例如index.php?post_type=item&p=1234
)。
检查是否已经添加自定义重写规则
- 通过代码添加:最直接的方式是检查你的主题的
functions.php
文件或任何自定义插件文件,看看是否有使用add_rewrite_rule
函数的代码。如果你之前没有手动添加过相关代码,那么可能还没有添加自定义重写规则。 - 使用插件检查:有一些插件可以帮助你查看和管理WordPress的重写规则,例如”Rewrite Rules Inspector”。这样的插件可以让你直观地看到所有当前生效的重写规则,并帮助你确定是否已经有了针对
item
自定义文章类型的规则。
添加自定义重写规则
如果你确定之前没有添加过自定义重写规则,可以按照之前提供的指导添加。基本步骤包括:
- 编写重写规则代码:使用
add_rewrite_rule
函数来定义你的自定义URL结构和它应该如何解析。 - 将代码添加到你的网站:最常见的做法是将这些代码添加到你的主题的
functions.php
文件中。如果你对修改主题文件不太放心,另一个好方法是创建一个简单的自定义插件来放置这些代码。 - 刷新重写规则:在WordPress后台的“设置”>“固定链接”页面点击“保存更改”按钮,即使你没有更改任何设置。这会刷新重写规则,确保你的新规则被添加到系统中并开始生效。
希望这能帮助你更好地理解WordPress的重写规则以及如何添加自定义重写规则。如果你在实施过程中遇到任何具体问题,随时回来询问。
Ben
你提供的方法奏效了,具体来说就是:当我访问 https://xuandao.la/item/1234/这样的URL,其中1234是我的文章ID,这个链接能够成功显示我通过ID指定的文章。
不过在wordpress后台,以及wordpress所生成的页面中,URL还是https://xuandao.la/item/xxxx/,我能不能用一种方式,直接让wordpress就不提供或完全不使用 https://xuandao.la/item/xxxx/ ,而全部使用https://xuandao.la/item/xxxx/ ?
ChatGPT
要让WordPress在后台以及自动生成的页面中使用基于文章ID的URL(例如https://xuandao.la/item/1234/
),而不是基于文章标题的URL(例如https://xuandao.la/item/xxxx/
),你需要修改WordPress生成文章链接的方式。这通常涉及到post_type_link
过滤器,该过滤器允许你自定义自定义文章类型的永久链接。
以下是一个示例代码,展示了如何为item
自定义文章类型实现这一点。你需要将此代码添加到你的主题的functions.php
文件中,或创建一个简单的插件来包含它。
function custom_post_type_link( $post_link, $post, $leavename, $sample ) { // 确保这个修改只应用于我们的自定义文章类型 'item' if ( $post->post_type == 'item' && ! in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft', 'future' ) ) ) { $post_link = home_url( '/item/' . $post->ID . '/' ); } return $post_link; } add_filter( 'post_type_link', 'custom_post_type_link', 10, 4 );
这段代码会拦截任何尝试生成item
自定义文章类型链接的请求,并将链接格式改为使用文章ID。这意味着无论是在WordPress后台还是在前端显示的链接,都将使用新的基于ID的格式。
注意事项
- 性能考虑:使用文章ID作为URL的一部分通常对性能影响不大,但确保你的网站在做出这样的更改后仍然响应迅速。
- SEO和用户体验:从SEO角度来看,友好的URL(通常包含文章标题或关键字)可能对页面排名有积极影响。确保考虑这一点和可能对用户体验的影响。
- 现有链接:如果你的网站已经有基于文章标题的URL被索引或分享,突然改变URL结构可能会导致404错误。考虑实施适当的301重定向,从旧URL重定向到新URL。
- 刷新永久链接:在添加或修改这段代码后,记得去WordPress后台的“设置 > 固定链接”页面,点击“保存更改”按钮以刷新永久链接结构。
通过实施这个过滤器,你应该能够让WordPress在所有场合都使用基于文章ID的URL结构,而不是基于文章标题的结构。这将帮助保持链接的一致性并按照你的要求进行定制。如果你有任何问题或需要进一步的帮助,请随时提问。
Ben
你上面提供的function custom_post_type_link,可以放在你更早一些时候提供的function custom_rewrite_rule 后面吗?
ChatGPT
是的,你可以将custom_post_type_link
函数放在之前提供的custom_rewrite_rule
函数后面。通常情况下,这两个函数都可以添加到你的主题的functions.php
文件或者一个自定义插件中。这两个函数处理不同的部分:custom_rewrite_rule
负责定义URL重写规则,而custom_post_type_link
负责修改自定义文章类型的永久链接结构。将它们放在一起可以确保URL重写和永久链接生成的逻辑是一致的。
下面是将两个函数一起使用的示例,展示了如何在同一个文件中组织它们:
// 添加自定义重写规则 function custom_rewrite_rule() { add_rewrite_rule('^item/([0-9]+)/?$', 'index.php?post_type=item&p=$matches[1]', 'top'); } add_action('init', 'custom_rewrite_rule'); // 修改自定义文章类型的永久链接 function custom_post_type_link( $post_link, $post, $leavename, $sample ) { if ( $post->post_type == 'item' && ! in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft', 'future' ) ) ) { $post_link = home_url( '/item/' . $post->ID . '/' ); } return $post_link; } add_filter( 'post_type_link', 'custom_post_type_link', 10, 4 );
注意事项:
- 在添加这些代码之后,记得刷新WordPress的重写规则。这可以通过访问WordPress后台的“设置” > “固定链接”页面并点击“保存更改”按钮来完成,即使你没有更改任何设置。
- 测试你的网站以确保所有东西都按预期工作,特别是新的URL结构和已有内容的链接。
- 考虑到SEO和用户体验,如果你更改了现有内容的URL结构,确保设置适当的301重定向,以避免404错误并保持搜索引擎优化。
将这些代码添加到你的网站后,你应该能够实现之前讨论的URL结构更改,使得所有item
类型的文章都使用基于ID的URL结构,而不是基于文章标题的URL结构。如果在实施过程中遇到任何问题,或者需要进一步的帮助,请随时提问。
Ben
非常好,it works.
我想请你帮我逐行解释一下function custom_post_type_link,也就是你写的“修改自定义文章类型的永久链接”的代码
ChatGPT
当然,我很乐意逐行解释custom_post_type_link
函数的代码,这将帮助你更好地理解它是如何工作的:
function custom_post_type_link( $post_link, $post, $leavename, $sample ) {
这一行定义了一个名为custom_post_type_link
的函数,它接收四个参数:
$post_link
:原始的文章永久链接(URL)。$post
:当前处理的WP_Post
对象,包含了文章的所有信息。$leavename
:一个布尔值,指示是否保留文章名字的占位符(在某些特定的URL结构中使用)。$sample
:一个布尔值,指示生成的链接是否为示例链接。
if ( $post->post_type == 'item' && ! in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft', 'future' ) ) ) {
这一行是一个条件判断语句,它检查当前文章是否属于item
自定义文章类型,且文章的状态不是草稿(draft
)、待审(pending
)、自动草稿(auto-draft
)或定时发布(future
)。这是为了确保只修改item
类型并且状态为发布或类似状态文章的URL。
$post_link = home_url( '/item/' . $post->ID . '/' );
如果上面的条件满足,这一行将$post_link
变量修改为新的URL。它使用home_url()
函数构建基于首页URL的新链接,然后添加/item/
路径和文章的ID,最后以斜杠(/
)结尾。这就是将原始的基于文章标题的URL修改为基于文章ID的URL的核心代码部分。
} return $post_link; }
这个代码块的结尾包含一个闭合的大括号,表示条件判断的结束。然后,修改后的$post_link
(或者如果条件不满足,则为原始的$post_link
)被返回。这确保了无论如何函数都会返回一个URL,如果文章不是item
类型或处于排除的状态之一,则返回的是没有修改的原始URL。
add_filter( 'post_type_link', 'custom_post_type_link', 10, 4 );
最后,这行代码将custom_post_type_link
函数挂钩到post_type_link
过滤器上,这意味着每当WordPress尝试生成任何文章类型的永久链接时,都会调用这个函数。10
是函数被调用的优先级,4
是函数接收的参数数量。
总结来说,这个函数的作用是检查每个生成的文章URL,如果这个文章是item
类型且处于一个适合被公开访问的状态,它就会将这个文章的URL修改为一个基于文章ID的格式。这样,无论是在后台列表还是前端页面中,所有item
类型文章的链接都会是这种新的、基于ID的格式。
Ben
你太专业了,谢谢你
ChatGPT
非常感谢你的赞扬!很高兴能帮到你。如果你有任何其他问题,无论是WordPress相关的或其他任何问题,都请随时提问。祝你在项目上取得成功!
发表回复