这篇我们说首页的业务逻辑,首先我们看下首页的路由。

[index] => Array
        (
            [url] => /
            [widget] => Widget_Archive
            [action] => render
            [regx] => |^[/]?$|
            [format] => /
            [params] => Array
                (
                )

        )

由路由表可以看出首页的 url 为 https://iliuxu.cn/ 并且不带任何参数,由上一节我们可以得出结论,当路由表匹配到 / ,会实例化 Widget_Archive 类的 render 方法。

下面让我一步步揭开 Widget_Archive 的神秘面纱。

    public function render()
    {
        /** 处理静态链接跳转 */
        $this->checkPermalink();

        /** 添加Pingback */
        $this->response->setHeader('X-Pingback', $this->options->xmlRpcUrl);
        $validated = false;

        //~ 自定义模板
        if (!empty($this->_themeFile)) {
            if (file_exists($this->_themeDir . $this->_themeFile)) {
                $validated = true;
            }
        }

        if (!$validated && !empty($this->_archiveType)) {

            //~ 首先找具体路径, 比如 category/default.php
            if (!$validated && !empty($this->_archiveSlug)) {
                $themeFile = $this->_archiveType . '/' . $this->_archiveSlug . '.php';
                if (file_exists($this->_themeDir . $themeFile)) {
                    $this->_themeFile = $themeFile;
                    $validated = true;
                }
            }

            //~ 然后找归档类型路径, 比如 category.php
            if (!$validated) {
                $themeFile = $this->_archiveType . '.php';
                if (file_exists($this->_themeDir . $themeFile)) {
                    $this->_themeFile = $themeFile;
                    $validated = true;
                }
            }

            //针对attachment的hook
            if (!$validated && 'attachment' == $this->_archiveType) {
                if (file_exists($this->_themeDir . 'page.php')) {
                    $this->_themeFile = 'page.php';
                    $validated = true;
                } else if (file_exists($this->_themeDir . 'post.php')) {
                    $this->_themeFile = 'post.php';
                    $validated = true;
                }
            }

            //~ 最后找归档路径, 比如 archive.php 或者 single.php
            if (!$validated && 'index' != $this->_archiveType && 'front' != $this->_archiveType) {
                $themeFile = $this->_archiveSingle ? 'single.php' : 'archive.php';
                if (file_exists($this->_themeDir . $themeFile)) {
                    $this->_themeFile = $themeFile;
                    $validated = true;
                }
            }

            if (!$validated) {
                $themeFile = 'index.php';
                if (file_exists($this->_themeDir . $themeFile)) {
                    $this->_themeFile = $themeFile;
                    $validated = true;
                }
            }
        }

        /** 文件不存在 */
        if (!$validated) {
            Typecho_Common::error(500);
        }

        /** 挂接插件 */
        $this->pluginHandle()->beforeRender($this);

        /** 输出模板 */
        require_once $this->_themeDir . $this->_themeFile;

        /** 挂接插件 */
        $this->pluginHandle()->afterRender($this);
    }

该类的 render 方法主要实现了根据是否自定义模版(主题),然后去加载对应模版文件的功能,Widget_Archive 作为 Typecho_Widget 的子类,在理解该类的同时需要先理解 Typecho_Widget ,同时 Typecho_Widget 也是 typecho 重要的基类。