分析 `get_author_posts_url()` 函数的源码,它是如何生成作者文章页链接的?

各位观众,晚上好!我是你们的老朋友,今天咱们来聊聊WordPress里一个不起眼,但又很重要的函数:get_author_posts_url()。这玩意儿专职负责生成作者文章列表页面的链接,用人话说,就是点作者名字,能看到他/她写的所有文章的那个页面。

咱们今天的讲座,就围绕这个函数,深入浅出地扒一扒它的源码,看看它是怎么变魔术,把作者ID变成一个漂亮的URL的。

一、 源码初探:没啥神秘的,都是套路

首先,我们先来看看get_author_posts_url()的源码(以WordPress最新版本为例,可能会略有差异,但核心逻辑不变)。

/**
 * Retrieves the URL for an author page.
 *
 * @since 2.1.0
 *
 * @param int|WP_User $author_id User ID or WP_User object.
 * @param string      $author_nicename Optional. User nicename. Defaults to the
 *                                     user nicename of the author specified in
 *                                     $author_id.
 * @return string The URL to the author page for the user specified.
 */
function get_author_posts_url( $author_id, $author_nicename = '' ) {
    $author_id = (int) $author_id;
    $link      = '';

    if ( ! $author_id ) {
        return $link;
    }

    $author = get_userdata( $author_id );

    if ( ! $author ) {
        return $link;
    }

    if ( empty( $author_nicename ) ) {
        $author_nicename = $author->user_nicename;
    }

    $author_nicename = rawurlencode( $author_nicename );

    $author_rewrite_slug = get_option( 'author_rewrite_slug' );

    if ( empty( $author_rewrite_slug ) ) {
        $author_rewrite_slug = 'author';
    }

    if ( get_option( 'permalink_structure' ) ) {
        if ( is_front_page() && is_home() ) {
            $link = trailingslashit( home_url( $author_rewrite_slug . '/' . $author_nicename ) );
        } else {
            $link = trailingslashit( home_url( user_trailingslashit( $author_rewrite_slug . '/' . $author_nicename, 'author' ) ) );
        }
    } else {
        $link = add_query_arg( 'author', $author_id, home_url() );
    }

    /**
     * Filters the URL for an author page.
     *
     * @since 2.1.0
     *
     * @param string $link          The URL to the author page.
     * @param int    $author_id     The author ID.
     * @param string $author_nicename The author nicename.
     */
    $link = apply_filters( 'author_link', $link, $author_id, $author_nicename );

    return $link;
}

是不是觉得有点眼花缭乱?别怕,我们把它拆开揉碎了,一点点分析。

二、源码庖丁解牛:一步一个脚印

  1. 参数校验与准备:防止猪队友捣乱

    $author_id = (int) $author_id;
    $link      = '';
    
    if ( ! $author_id ) {
        return $link;
    }
    
    $author = get_userdata( $author_id );
    
    if ( ! $author ) {
        return $link;
    }
    • $author_id = (int) $author_id;: 强制把$author_id转换成整数,防止传入乱七八糟的东西。
    • $link = '';: 初始化一个空字符串,作为最终返回的URL。
    • if ( ! $author_id ) { return $link; }: 如果$author_id是空的(比如0),直接返回空字符串,省的后面瞎忙活。
    • $author = get_userdata( $author_id );: 通过get_userdata()函数,根据$author_id获取作者的详细信息(比如昵称、邮箱等等),返回一个WP_User对象。
    • if ( ! $author ) { return $link; }: 如果get_userdata()没找到对应的作者,也直接返回空字符串。

    这一段代码的作用就是:确保传入的作者ID有效,并且能够找到对应的作者信息。 如果不行,就直接放弃,返回一个空URL,避免程序出错。

  2. 获取作者别名 (Author Nicename): 给作者起个好听的名字

    if ( empty( $author_nicename ) ) {
        $author_nicename = $author->user_nicename;
    }
    
    $author_nicename = rawurlencode( $author_nicename );
    • if ( empty( $author_nicename ) ) { $author_nicename = $author->user_nicename; }: 如果调用get_author_posts_url()的时候,没有手动指定$author_nicename,就从WP_User对象中获取作者的user_nicename属性。 user_nicename通常是用户注册时填写的昵称,经过处理后可以安全地用在URL中。
    • $author_nicename = rawurlencode( $author_nicename );: 对$author_nicename进行URL编码,确保它在URL中是安全的。 比如把空格变成%20,把中文变成一堆乱码(别怕,浏览器会正确解码的)。

    这一段代码的作用是:获取作者的别名,并进行URL编码。 作者别名是URL中代表作者身份的关键部分。

  3. 获取作者别名前缀 (Author Rewrite Slug): 给作者加个前缀

    $author_rewrite_slug = get_option( 'author_rewrite_slug' );
    
    if ( empty( $author_rewrite_slug ) ) {
        $author_rewrite_slug = 'author';
    }
    • $author_rewrite_slug = get_option( 'author_rewrite_slug' );: 从WordPress的选项表中,获取author_rewrite_slug这个选项的值。 这个选项允许你自定义作者页面的URL前缀。
    • if ( empty( $author_rewrite_slug ) ) { $author_rewrite_slug = 'author'; }: 如果author_rewrite_slug选项为空,就使用默认值author

    这一段代码的作用是:获取作者别名的前缀。 默认情况下,作者页面的URL是example.com/author/作者别名,这里的author就是前缀。 你可以在WordPress后台的“设置” -> “固定链接”中修改这个前缀。

  4. 生成URL:根据固定链接设置,选择不同的生成方式

    if ( get_option( 'permalink_structure' ) ) {
        if ( is_front_page() && is_home() ) {
            $link = trailingslashit( home_url( $author_rewrite_slug . '/' . $author_nicename ) );
        } else {
            $link = trailingslashit( home_url( user_trailingslashit( $author_rewrite_slug . '/' . $author_nicename, 'author' ) ) );
        }
    } else {
        $link = add_query_arg( 'author', $author_id, home_url() );
    }

    这部分是整个函数的核心,它根据WordPress的固定链接设置,选择不同的方式来生成URL。

    • if ( get_option( 'permalink_structure' ) ): 判断是否启用了固定链接。 固定链接是指URL中不包含?和参数的URL,比如example.com/author/john。如果没有启用固定链接,URL会是example.com/?author=1这种形式。

      • 如果启用了固定链接 ( permalink_structure 为真):

        • if ( is_front_page() && is_home() ): 判断当前页面是否是首页,并且首页显示的是文章列表。 这种情况比较特殊,需要特殊处理。
          • $link = trailingslashit( home_url( $author_rewrite_slug . '/' . $author_nicename ) );: 直接拼接URL,比如example.com/author/john/home_url()函数返回网站的根URL,trailingslashit()函数在URL末尾添加一个斜杠。
        • else: 如果不是首页,就使用更通用的方式生成URL。
          • $link = trailingslashit( home_url( user_trailingslashit( $author_rewrite_slug . '/' . $author_nicename, 'author' ) ) );: 同样是拼接URL,但是多了一个user_trailingslashit()函数。 这个函数的作用是:根据用户的设置,决定是否在URL末尾添加斜杠。 有些用户喜欢在URL末尾加上斜杠,有些不喜欢。 这个函数会尊重用户的选择。
      • 如果没有启用固定链接 ( permalink_structure 为假):

        • $link = add_query_arg( 'author', $author_id, home_url() );: 使用add_query_arg()函数,把author参数添加到URL中。 比如example.com/?author=1

    这段代码的作用是:根据固定链接设置,生成作者页面的URL。 如果启用了固定链接,URL会更漂亮、更易读。 如果没有启用固定链接,URL会包含?和参数。

  5. 应用过滤器 (Apply Filters): 给URL加点特效

    /**
     * Filters the URL for an author page.
     *
     * @since 2.1.0
     *
     * @param string $link          The URL to the author page.
     * @param int    $author_id     The author ID.
     * @param string $author_nicename The author nicename.
     */
    $link = apply_filters( 'author_link', $link, $author_id, $author_nicename );
    • $link = apply_filters( 'author_link', $link, $author_id, $author_nicename );: 使用apply_filters()函数,对生成的URL进行过滤。 author_link是一个过滤器钩子,允许其他插件或主题修改作者页面的URL。

    这段代码的作用是:允许其他插件或主题修改作者页面的URL。 这是一种扩展WordPress功能的常用方式。 比如,你可以使用一个插件,把作者页面的URL改成example.com/writer/john

  6. 返回URL:大功告成,收工!

    return $link;
    • return $link;: 返回最终生成的URL。

    这段代码的作用是:返回作者页面的URL。

三、实战演练:代码说话,胜过千言万语

为了更好地理解get_author_posts_url()函数,我们来做几个小实验。

实验一:获取作者ID为1的作者页面URL

$author_id = 1;
$author_url = get_author_posts_url( $author_id );

echo '作者ID为' . $author_id . '的作者页面URL是:' . $author_url;

这段代码会输出作者ID为1的作者页面URL。 URL的具体形式取决于你的固定链接设置。

  • 如果启用了固定链接,并且author_rewrite_slug选项为默认值author,并且作者的user_nicenameadmin,那么输出的URL可能是: example.com/author/admin/
  • 如果没有启用固定链接,那么输出的URL可能是: example.com/?author=1

实验二:自定义作者别名

$author_id = 1;
$author_nicename = 'superman'; // 自定义作者别名
$author_url = get_author_posts_url( $author_id, $author_nicename );

echo '作者ID为' . $author_id . ',别名为' . $author_nicename . '的作者页面URL是:' . $author_url;

这段代码会输出作者ID为1,别名为superman的作者页面URL。

  • 如果启用了固定链接,并且author_rewrite_slug选项为默认值author,那么输出的URL可能是: example.com/author/superman/
  • 如果没有启用固定链接,那么输出的URL仍然是: example.com/?author=1 (因为没有启用固定链接,自定义别名不起作用)

实验三:使用过滤器修改作者页面URL

function my_custom_author_link( $link, $author_id, $author_nicename ) {
    return home_url( 'writer/' . $author_nicename );
}

add_filter( 'author_link', 'my_custom_author_link', 10, 3 );

$author_id = 1;
$author_url = get_author_posts_url( $author_id );

echo '作者ID为' . $author_id . '的作者页面URL是:' . $author_url;

remove_filter( 'author_link', 'my_custom_author_link', 10 ); // 移除过滤器,避免影响其他地方

这段代码使用author_link过滤器,把作者页面的URL改成example.com/writer/作者别名

  • 如果启用了固定链接,并且作者的user_nicenameadmin,那么输出的URL可能是: example.com/writer/admin
  • 如果没有启用固定链接,那么输出的URL可能是: example.com/writer/admin (即使没有启用固定链接,过滤器仍然会生效)

四、总结:小函数,大智慧

get_author_posts_url()函数虽然看起来简单,但它却包含了WordPress生成URL的很多核心概念:

  • 固定链接: 决定了URL的结构。
  • 选项表: 存储了网站的配置信息,比如author_rewrite_slug
  • 过滤器: 允许其他插件或主题修改URL。
  • URL编码: 确保URL是安全的。

通过分析这个函数,我们可以更深入地理解WordPress的URL生成机制,从而更好地开发WordPress主题和插件。

五、课后作业:挑战一下,更上一层楼

  1. 修改author_rewrite_slug选项,看看作者页面的URL会发生什么变化。
  2. 编写一个插件,使用author_link过滤器,实现自定义作者页面的URL。
  3. 研究一下user_trailingslashit()函数,看看它是如何决定是否在URL末尾添加斜杠的。

今天的讲座就到这里,希望大家有所收获!下次有机会,我们再聊聊WordPress的其他有趣话题。 祝大家编程愉快!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注