IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Typecho通过插件实现构建自定义设置页

    Veen Zhao发表于 2023-08-28 18:53:00
    love 0

      在开发typecho主题的时候,typecho本身已经提供了封装好的设置项类,常见的例如有:Checkbox、Radio、Select、Text、Textarea等等。我们很方便的就能通过调用相关类来添加主题设置项,这也是最常见的一种方式。虽然够用,但这也带来了一些局限性,相比较于Wordpress,灵活度还是不够高。

      为了解决上述问题,我们可以通过配合插件来从底层自己创建自定义的设置项页面。大致流程有:

    1. 通过插件添加相关路由
    2. 创建自定义的设置项表
    3. 封装相关数据库语句
    4. 创建全局变量以便于读取设置项

      下面详细叙述各个流程:

    创建插件并添加路由

      创建一个插件目录,例如"YourPlugin",并在该目录下创建一个"Plugin.php"文件。接着就是添加插件基本方法以及需要继承的类,可以参考官方的HelloWorld插件来写。

      在activate()方法中,使用Helper中的addRoute添加路由:

    const widgetName = 'TypechoPlugin\Furry\Router';
    // 激活插件方法,如果激活失败,直接抛出异常
    public static function activate()
    {
        Helper::addRoute('furry_options','/furry/options', self::widgetName, 'furryOptionsPageFunc');
        Helper::addRoute('furry_options_api','/furry/api/options', self::widgetName, 'furryOptionsApiFunc');
    }

      这里我添加了/furry/options以及/furry/api/options两个路由。前者用来承接设置页的路由,后者用来加载数据库中的设置项,以json形式返回给前端。

      记得在Action中实现furryOptionsPageFunc以及furryOptionsApiFunc两个方法,如果对于这一块不是很明白的可以参考Typecho的插件开发教程,网上有很多例子。这里我提供furryOptionsPageFunc的例子:

    // 渲染设置页
    public function furryOptionsPageFunc()
    {
        if (User::alloc()->hasLogin()) {
            include_once 'options/index.php';
        } else {
            Helper::options()->response->redirect('/admin/login.php');
        }
    }

      当用户登录时,访问/furry/options会加载options文件夹中的index.php。否则就会重定向到登录页面,这是一个简单的 鉴权。

    创建相关数据表

      通过上面的分析,我们还知道,需要创建一张表,专门用来存放设置的数据,同样的,可以使用Typecho提供的数据库操作类来实现,对Typecho数据库Api不熟悉的可以参考我的另一篇文章: Typecho数据库常用API 。我这里给出我的例子:

    // 创建设置表
    private static function createFurryOptionsTable()
    {
        $db = Db::get();
        $prefix = $db->getPrefix();
        $tableName = $prefix . 'furry_options';
        if (!$db->fetchRow("SHOW TABLES LIKE '$tableName'")) {
            $db->query('CREATE TABLE `' . $tableName . '` (
            `name` varchar(100) NOT NULL COMMENT \'设置名\',
            `type` varchar(20) NOT NULL COMMENT \'所属分类名\',
            `value` text COMMENT \'设置值\',
            PRIMARY KEY (`name`)
        )');
        }
    }

      在插件激活时,可以调用这个方法,就会创建一张表:
    lm0lxlmz.png
      包括name设置名、type所属分类名、value设置值三个字段。这样,后面我们就可以存储自己的设置项了,即使切换主题也不会丢失,因为保存在了数据库中。

    初始化设置项

      表有了,下一步就是往里面写入数据。这里我们可以用一个数组来作为初始化的数据。接着用循环语句通过insert方法来插入数据,我这里举个例子:

    // 初始化options数据
    private static function initOptions()
    {
        $arr = [
            // 全局设置
            ["type" => "global", "name" => "AuthKey", "value" => ""],
            ["type" => "global", "name" => "BuildSiteTime", "value" => ""],
            ["type" => "global", "name" => "Favicon", "value" => ""],
            ["type" => "global", "name" => "ICP", "value" => ""],
            ["type" => "global", "name" => "Police", "value" => ""],
            // 旁侧边栏
            ["type" => "sidebar", "name" => "LeftSide", "value" => "true"],
            ["type" => "sidebar", "name" => "RightSide", "value" => "true"],
        ];
        $db = Db::get();
        $prefix = $db->getPrefix();
        $tableName = $prefix . 'furry_options';
        foreach ($arr as $item) {
            $insert = $db->insert($tableName)->rows($item);
            $db->query($insert);
        }
    }

      同样的,也是在插件激活的时候执行,就会得到初试的所有数据啦:
    lm0mvuim.png

    查询设置项并在主题中使用

      前三小节都是在插件中完成,这里,我们就需要返回主题文件夹中操作了。我们都知道,在Typecho中,themeInit函数是一个用于主题开发的钩子函数。它在每次加载主题时被调用,可以用来执行一些初始化操作和自定义功能。所以我们可以将这一步放入初始化函数中执行。也就是查询设置项并保存到全局变量中。

      在functions.php中添加下面的函数来读取设置项,并定义一个全局变量用于保存:

    // 设置项全局变量
    function furryThemeOptions()
    {
        $db = Db::get();
        $prefix = $db->getPrefix();
        $tableName = $prefix . 'furry_options';
        $results = $db->fetchAll($db->select()->from($tableName));
        $newArray = array();
        foreach ($results as $item) {
            $newArray[$item['name']] = $item['value'];
        }
        @define('__FurryOptions__', $newArray);
    }

      然后记得将这个函数在themeInit函数中调用。这样,在主题模板文件中,就可以这样使用:

    <aside class="col-span-3 px-8">
        <!--加载设置项开始-->
        <?php echo __FurryOptions__['AuthKey'] ?>
        <!--加载设置项结束-->
        <?php $this->need('inc/left/left.php'); ?>
    </aside>

    总结

      至此,就完成了通过插件实现构建自定义设置页的教程,至于设置页的UI都可以通过自己的想法实现,甚至采用目前流行的前后端分离的方式去构建设置页。这样就能将现代前端的生态对接到typecho的管理当中。



沪ICP备19023445号-2号
友情链接