typecho 1.2.1 给标签添加description说明文字

之前写过一篇为typecho标签添加说明字段的方法,对应的是typecho1.1版本,目前typecho的稳定版本是1.2.1, 因为服务器php版本较低,一直没有去尝试新版。这几天用小皮面板搭建了一个本地的php环境,终于是正经尝试了一下新版本,新版的组织架构变化不大,代码写法上普遍采用了新的通过use导入命名空间的方式,所以如果想为1.2.1版本的标签添加说明,我们还是需要1.2.1版本的对应文件,老版本的文件无法通用。

对应文件的地址

typecho/var/Widget/Metas/Tag/Edit.php

Metas文件夹内另有一个命名为Category的目录,顾名思义,用于处理目录信息。typecho把目录信息与tag信息都放在一张表格里,所以他们处理的方式也极其相似。

完整代码

<?php

namespace Widget\Metas\Tag;

use Typecho\Common;
use Typecho\Db\Exception;
use Typecho\Widget\Helper\Form;
use Widget\Base\Metas;
use Widget\ActionInterface;
use Widget\Notice;

if (!defined('__TYPECHO_ROOT_DIR__')) {
    exit;
}

/**
 * 标签编辑组件
 *
 * @author qining
 * @category typecho
 * @package Widget
 * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
 * @license GNU General Public License 2.0
 */
class Edit extends Metas implements ActionInterface
{
    /**
     * 入口函数
     */
    public function execute()
    {
        /** 编辑以上权限 */
        $this->user->pass('editor');
    }

    /**
     * 判断标签是否存在
     *
     * @param integer $mid 标签主键
     * @return boolean
     * @throws Exception
     */
    public function tagExists(int $mid): bool
    {
        $tag = $this->db->fetchRow($this->db->select()
            ->from('table.metas')
            ->where('type = ?', 'tag')
            ->where('mid = ?', $mid)->limit(1));

        return (bool)$tag;
    }

    /**
     * 判断标签名称是否存在
     *
     * @param string $name 标签名称
     * @return boolean
     * @throws Exception
     */
    public function nameExists(string $name): bool
    {
        $select = $this->db->select()
            ->from('table.metas')
            ->where('type = ?', 'tag')
            ->where('name = ?', $name)
            ->limit(1);

        if ($this->request->mid) {
            $select->where('mid <> ?', $this->request->filter('int')->mid);
        }

        $tag = $this->db->fetchRow($select);
        return !$tag;
    }

    /**
     * 判断标签名转换到缩略名后是否合法
     *
     * @param string $name 标签名
     * @return boolean
     */
    public function nameToSlug(string $name): bool
    {
        if (empty($this->request->slug)) {
            $slug = Common::slugName($name);
            if (empty($slug) || !$this->slugExists($name)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断标签缩略名是否存在
     *
     * @param string $slug 缩略名
     * @return boolean
     * @throws Exception
     */
    public function slugExists(string $slug): bool
    {
        $select = $this->db->select()
            ->from('table.metas')
            ->where('type = ?', 'tag')
            ->where('slug = ?', Common::slugName($slug))
            ->limit(1);

        if ($this->request->mid) {
            $select->where('mid <> ?', $this->request->mid);
        }

        $tag = $this->db->fetchRow($select);
        return !$tag;
    }

    /**
     * 插入标签
     *
     * @throws Exception
     */
    public function insertTag()
    {
        if ($this->form('insert')->validate()) {
            $this->response->goBack();
        }

        /** 取出数据 */
        $tag = $this->request->from('name', 'description', 'slug');
        $tag['type'] = 'tag';
        $tag['slug'] = Common::slugName(empty($tag['slug']) ? $tag['name'] : $tag['slug']);

        /** 插入数据 */
        $tag['mid'] = $this->insert($tag);
        $this->push($tag);

        /** 设置高亮 */
        Notice::alloc()->highlight($this->theId);

        /** 提示信息 */
        Notice::alloc()->set(
            _t('标签 <a href="%s">%s</a> 已经被增加', $this->permalink, $this->name),
            'success'
        );

        /** 转向原页 */
        $this->response->redirect(Common::url('manage-tags.php', $this->options->adminUrl));
    }

    /**
     * 生成表单
     *
     * @param string|null $action 表单动作
     * @return Form
     * @throws Exception
     */
    public function form(?string $action = null): Form
    {
        /** 构建表格 */
        $form = new Form($this->security->getIndex('/action/metas-tag-edit'), Form::POST_METHOD);

        /** 标签名称 */
        $name = new Form\Element\Text(
            'name',
            null,
            null,
            _t('标签名称') . ' *',
            _t('这是标签在站点中显示的名称.可以使用中文,如 "地球".')
        );
        $form->addInput($name);

        /** 标签缩略名 */
        $slug = new Form\Element\Text(
            'slug',
            null,
            null,
            _t('标签缩略名'),
            _t('标签缩略名用于创建友好的链接形式, 如果留空则默认使用标签名称.')
        );
        $form->addInput($slug);

        /** 标签描述 */
        $description = new Form\Element\Text(
            'description',
            null,
            null,
            _t('标签描述'),
            _t('此字段用于给标签添加一段说明文字, 在有的主题中它也会被显示在页面上.')
        );
        $form->addInput($description);

        /** 标签动作 */
        $do = new Form\Element\Hidden('do');
        $form->addInput($do);

        /** 标签主键 */
        $mid = new Form\Element\Hidden('mid');
        $form->addInput($mid);

        /** 提交按钮 */
        $submit = new Form\Element\Submit();
        $submit->input->setAttribute('class', 'btn primary');
        $form->addItem($submit);

        if (isset($this->request->mid) && 'insert' != $action) {
            /** 更新模式 */
            $meta = $this->db->fetchRow($this->select()
                ->where('mid = ?', $this->request->mid)
                ->where('type = ?', 'tag')->limit(1));

            if (!$meta) {
                $this->response->redirect(Common::url('manage-tags.php', $this->options->adminUrl));
            }

            $name->value($meta['name']);
            $slug->value($meta['slug']);
            $description->value($meta['description']);
            $do->value('update');
            $mid->value($meta['mid']);
            $submit->value(_t('编辑标签'));
            $_action = 'update';
        } else {
            $do->value('insert');
            $submit->value(_t('增加标签'));
            $_action = 'insert';
        }

        if (empty($action)) {
            $action = $_action;
        }

        /** 给表单增加规则 */
        if ('insert' == $action || 'update' == $action) {
            $name->addRule('required', _t('必须填写标签名称'));
            $name->addRule([$this, 'nameExists'], _t('标签名称已经存在'));
            $name->addRule([$this, 'nameToSlug'], _t('标签名称无法被转换为缩略名'));
            $name->addRule('xssCheck', _t('请不要标签名称中使用特殊字符'));
            $slug->addRule([$this, 'slugExists'], _t('缩略名已经存在'));
            $slug->addRule('xssCheck', _t('请不要在缩略名中使用特殊字符'));
        }

        if ('update' == $action) {
            $mid->addRule('required', _t('标签主键不存在'));
            $mid->addRule([$this, 'tagExists'], _t('标签不存在'));
        }

        return $form;
    }

    /**
     * 更新标签
     *
     * @throws Exception
     */
    public function updateTag()
    {
        if ($this->form('update')->validate()) {
            $this->response->goBack();
        }

        /** 取出数据 */
        $tag = $this->request->from('name', 'slug', 'description', 'mid');
        $tag['type'] = 'tag';
        $tag['slug'] = Common::slugName(empty($tag['slug']) ? $tag['name'] : $tag['slug']);

        /** 更新数据 */
        $this->update($tag, $this->db->sql()->where('mid = ?', $this->request->filter('int')->mid));
        $this->push($tag);

        /** 设置高亮 */
        Notice::alloc()->highlight($this->theId);

        /** 提示信息 */
        Notice::alloc()->set(
            _t('标签 <a href="%s">%s</a> 已经被更新', $this->permalink, $this->name),
            'success'
        );

        /** 转向原页 */
        $this->response->redirect(Common::url('manage-tags.php', $this->options->adminUrl));
    }

    /**
     * 删除标签
     *
     * @throws Exception
     */
    public function deleteTag()
    {
        $tags = $this->request->filter('int')->getArray('mid');
        $deleteCount = 0;

        if ($tags && is_array($tags)) {
            foreach ($tags as $tag) {
                if ($this->delete($this->db->sql()->where('mid = ?', $tag))) {
                    $this->db->query($this->db->delete('table.relationships')->where('mid = ?', $tag));
                    $deleteCount++;
                }
            }
        }

        /** 提示信息 */
        Notice::alloc()->set(
            $deleteCount > 0 ? _t('标签已经删除') : _t('没有标签被删除'),
            $deleteCount > 0 ? 'success' : 'notice'
        );

        /** 转向原页 */
        $this->response->redirect(Common::url('manage-tags.php', $this->options->adminUrl));
    }

    /**
     * 合并标签
     *
     * @throws Exception
     */
    public function mergeTag()
    {
        if (empty($this->request->merge)) {
            Notice::alloc()->set(_t('请填写需要合并到的标签'), 'notice');
            $this->response->goBack();
        }

        $merge = $this->scanTags($this->request->merge);
        if (empty($merge)) {
            Notice::alloc()->set(_t('合并到的标签名不合法'), 'error');
            $this->response->goBack();
        }

        $tags = $this->request->filter('int')->getArray('mid');

        if ($tags) {
            $this->merge($merge, 'tag', $tags);

            /** 提示信息 */
            Notice::alloc()->set(_t('标签已经合并'), 'success');
        } else {
            Notice::alloc()->set(_t('没有选择任何标签'), 'notice');
        }

        /** 转向原页 */
        $this->response->redirect(Common::url('manage-tags.php', $this->options->adminUrl));
    }

    /**
     * 刷新标签
     *
     * @access public
     * @return void
     * @throws Exception
     */
    public function refreshTag()
    {
        $tags = $this->request->filter('int')->getArray('mid');
        if ($tags) {
            foreach ($tags as $tag) {
                $this->refreshCountByTypeAndStatus($tag, 'post', 'publish');
            }

            // 自动清理标签
            $this->clearTags();

            Notice::alloc()->set(_t('标签刷新已经完成'), 'success');
        } else {
            Notice::alloc()->set(_t('没有选择任何标签'), 'notice');
        }

        /** 转向原页 */
        $this->response->goBack();
    }

    /**
     * 入口函数,绑定事件
     *
     * @access public
     * @return void
     * @throws Exception
     */
    public function action()
    {
        $this->security->protect();
        $this->on($this->request->is('do=insert'))->insertTag();
        $this->on($this->request->is('do=update'))->updateTag();
        $this->on($this->request->is('do=delete'))->deleteTag();
        $this->on($this->request->is('do=merge'))->mergeTag();
        $this->on($this->request->is('do=refresh'))->refreshTag();
        $this->response->redirect($this->options->adminUrl);
    }
}

文件下载

typecho 1.2.1 标签添加description

标签: typecho

移动端可扫我直达哦~

推荐阅读

thumbnail 2025-06-08

typecho前台ajax登录与错误处理

尝试了在主题前台做一个登录框,登陆的功能是实现了,有一个小小的不便,就是如果输错了密码,因为页面又跳回了首页,所以弹出式登录框又被隐藏了,登录成功与否不够明显,二次登录的场合操作也较繁琐,所以想实现前台以ajax的方式登录。实现aja...

建站相关 typecho

thumbnail 2025-06-08

聊聊html里的head部分

HTML文档的<head>部分是一个容器,用于包含文档的元数据(metadata)和链接到外部资源的信息,这些内容不会直接显示在网页上,但对网页的功能和表现至关重要。主要元素和功能1. 基础元素<title>:...

建站相关 typecho

thumbnail 2025-06-04

typecho前端实现站点语言的切换

前端修改的数据能及时反馈到后端,那当然需要一个前后端都可以无障碍读取的东西,所以最初是想要用localstorage,但发现php无法直接读取其值,所以就换成了cookie。前端通过js来设置参数值:document.cookie='...

建站相关 typecho

thumbnail 2025-06-02

typecho 主题中的模板与模块的概念

模板是 typecho 主题中一个重要的概念,我们说过typecho的极简主题可以只存在 index.php 这一个文件,但需要展现分类页的时候,typecho事实上会先去寻找名为 category.php 的分类页模板,文章页当然也...

建站相关 typecho

thumbnail 2025-06-02

typecho的几种常见的文章列表调用

处理好了header与面包屑,接下来就按照自己的需求自由发挥了,先放一个分类列表,再挑出一个喜欢的标签,自定义一个该标签下内容展示模块。Typecho 提供了多种文章循环方式,以下是常用的几种方法:标准文章循环<?php whi...

建站相关 typecho

thumbnail 2025-06-02

在typecho里实现面包屑导航

什么是面包屑导航面包屑导航是一种网站导航方式,通常在网站顶部显示,大多会放在站点header的下方,用于显示用户当前位置。 面包屑导航由导航元素构成,每个元素代表一个网站导航项,各个元素通常包含对应链接,供用户跳转。面包屑导航示例首页...

建站相关 typecho

thumbnail 2025-05-29

关于typecho中的路由知识

路由(Routing)是博客系统中将URL地址映射到具体处理逻辑的机制,它决定了当用户访问某个网址时,系统应该执行什么操作、显示什么内容。typecho站点一般都会开启伪静态,伪静态通过URL重写将"漂亮"的URL映射到实际的文件路径...

建站相关 typecho

thumbnail 2025-05-29

Typecho 模板中的翻译函数 _t 与 _e

在 Typecho 模板开发中,_t 和 _e 是用于国际化处理的函数,核心区别在于输出方式:"_t" 函数‌‌功能‌:获取翻译后的字符串但不直接输出,需结合 echo 使用。‌示例‌:<?php echo _t('欢迎语');...

建站相关 typecho

thumbnail 2025-05-26

typecho文章自定义字段的删除与修改

涉及数据库的操作,务必请提前做好备份!提前做好备份!!做好备份!!!小鸟数据的当前主题的缩略图字段命名为augPostThumb,这几天在尝试完善一下原有主题,下载了原站的数据库导入了测试站用于测试页面效果,测试主题的缩略图相关字段拟...

建站相关 typecho

thumbnail 2025-05-26

typecho的文章自定义字段的知识笔记

在typecho中,除了可以自定义设置项之外,我们也可以给文章自定义一些额外的字段,比如给文章编辑界面添加一个缩略图选项,或者增加一个keywords输入框,用来修改编辑当前内容页的关键词信息。// 主题设置 function th...

建站相关 typecho