一些Typecho开发笔记

2022-5-16 18:45| 发布者: Hocassian| 查看: 76| 评论: 0|原作者: 三无计划的博客

摘要:
C:\Users\Administrator\Downloads\2019-10-13-21-42-29-124521788764000-无文字 三无计划-采集的数据-后羿采集器.html

发布时间

Oct 18, 2018

标题链接

https://blog.imalan.cn/archives/169/

标题

一些 Typecho 开发笔记

word-count

+ 1883 字

导语

某些经验性质的东西不写下来很快就会忘,所以有了这一篇备忘。

正文

最近做了两个主题,一个是 Typecho-Theme-RAW,另一个就是现在使用的这个,Type­cho-Theme-Q。RAW 是我的 Type­cho 主题第一作,象征意义比较大一点,主题质量各方面只能算差强人意吧。Q 的起源是因为我觉得 Boot­strap 有点意思,边看文档边写就写出来了,由于有写 RAW 时积累的经验加持,完成得很快。某些经验性质的东西不写下来很快就会忘,所以有了这一篇备忘。

以下部分内容来自 QQ 爹博客等大佬的博文,在此先行感谢。

Typecho 配置

TYPECHO_DEBUG

可在 Type­cho 根目录下 config.inc.php 中添加以下代码来开启 DE­BUG 模式。

define('__TYPECHO_DEBUG__', true);

这个模式下会打印更多的报错信息,某些普通情况直接 500 处理的错误在这里会打印出错误原因与调用堆栈等,很有用。

TYPECHO_GRAVATR_PREFIX

这个常量可以修改 GRA­VATAR 头像链接的前缀,方便使用国内镜像来加快速度。

define('__TYPECHO_GRAVATR_PREFIX__', 'https://gravatar.cat.net/avatar');

需要注意的是要生效的话需要在主题中使用 Type­cho 提供的方法来获取头像链接。

主题层面修改 Typecho 设置

在 PJAX 中评论失效的问题需要关闭主题的反垃圾保护,在主题中可以自动做到这一点。在主题目录下 functions.php 中创建如下代码即可。

function themeInit($archive){
    Helper::options()->commentsAntiSpam = false;
}

Type­cho 系统设置均可使用 Helper::options() 函数获取,权限蛮高的。另:themeInit() 函数完成了主题初始化,创建表之类的操作可以在这个函数中完成。

主题开发

自定义渲染方式

分别创建 categorypagepost 文件夹,在其中创建 分类缩略名.php页面slug.php文章cid.php 即可覆盖默认的渲染方式来为某分类、页面、文章创建自定义渲染方式。

主题设置面板

在主题根目录下创建 functions.php,在其中定义函数 themeConfig($form)

function themeConfig($form) {
    //基本设置
    $notice = new Typecho_Widget_Helper_Form_Element_Textarea('notice', NULL, NULL, _t('网站公告'), _t('网站公告'));
    $form->addInput($notice);
    $banner = new Typecho_Widget_Helper_Form_Element_Text('banner', NULL, NULL, _t('网站公告'), _t('网站公告'));
    $form->addInput($banner);
}

类似这样就可以添加 Textarea 或者 Text 类型的输入框。其中的内容在主题中可以通过以下方式来访问。

$this->options->ValueName

文章自定义字段面板

在主题根目录下创建 functions.php,在其中定义函数

function themeFields(Typecho_Widget_Helper_Layout $layout) {
    $thumb = new Typecho_Widget_Helper_Form_Element_Textarea('banner', NULL, NULL, '文章主图', '输入图片URL,该图片会用于主页文章列表的显示');
    $layout->addItem($thumb);
    $showTOC=new Typecho_Widget_Helper_Form_Element_Select('showTOC',array('0'=>'不显示目录','1'=>'显示目录'),'0','文章目录','是否显示文章目录');
    $layout->addItem($showTOC);
}

与上面相似,这样就可以为自定义字段创建友好的输入方式。这与手动添加自定义字段是等效的,但是可以提高使用体验。

自定义评论输出方式

创建 comments.php 文件,re­quire 在 functions.php 中,然后就可以在其中重载输出评论的方式。

Typecho 内建函数

$this->header();

这个函数要在 head 标签中调用,负责输出 RSS、Ping­back 等信息,还涉及输出插件要在 head 中输出的内容。与上面的类似,不过一般在 footer 标签后调用:

$this->footer();

获取所有设置:

Helper::options();

获取某插件设置:

Helper::options()->plugin($pluginName);

常用代码片段

博客内容统计

<?php Typecho_Widget::widget('Widget_Stat')->to($stat); ?>
<li>文章总数:<?php $stat->publishedPostsNum() ?></li>
<li>分类总数:<?php $stat->categoriesNum() ?></li>
<li>评论总数:<?php $stat->publishedCommentsNum() ?></li>
<li>页面总数:<?php $stat->publishedPagesNum() ?></li>

输出当前文章为第几篇

$this->sequence

最近评论

$this->widget('Widget_Comments_Recent','ignoreAuthor=true&pageSize=10')->to($comments);
<?php while($comments->next()): ?>
    <?php $comments->gravatar(50,''); ?>
    <a href="<?php $comments->permalink(); ?>"><?php $comments->excerpt($num, '...'); ?></a>
<?php endwhile; ?>

其中 ignoreAuthor=true 可以过滤掉博主自己的评论。pageSize 为输出数量。

Gravatar 头像链接

Typecho_Common::gravatarUrl($mail, $size, '', '', true);

可以根据邮箱地址给出头像链接。

输出所有独立页面

$this->widget('Widget_Contents_Page_List')->parse('<li><a href="{permalink}" target="_self">{title}</a></li>');

parse 方法可以非常方便地格式化输出所有的独立页面,太帅了。

文章、评论分页

$this->pageNav('上一页', '下一页', 0, '', 'wrapClass=hidden&prevClass=prev&nextClass=next');

判断插件是否可用

这是一个小坑。只要启用过插件,即使已经禁用了插件,class_exsist() 仍然会返回 true,所以应该如下检验:

/**
 * 判断插件是否存在并启用
 *
 * @return boolean
 */
function isPluginAvailable($name) {
    if (class_exists($name.'_Plugin')){
        $plugins = Typecho_Plugin::export();
        $plugins = $plugins['activated'];
        return is_array($plugins) && array_key_exists($name, $plugins);
    }
    return false;
}

校验请求是否来自手机

/**
 * 手机识别
 *
 * @return boolean
 */
function isPhone(){
    $ua=strtolower($_SERVER["HTTP_USER_AGENT"]);
    $devices=array("Android", 'iPhone', 'iPod', 'Phone');
    foreach ($devices as $device) {
        if(strpos($ua, strtolower($device))){
            return true;
        }
    }
    return false;
}

校验请求是否来自移动设备

/**
 * 移动端判定
 *
 * @return bool
 */
public static function isMobile(){
    if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])){
        return TRUE;
    }

    if (isset ($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array ('mobile','nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap'
            );
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))){
            return TRUE;
        }
    }
    if (isset ($_SERVER['HTTP_ACCEPT'])){
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== FALSE) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === FALSE || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))){
            return TRUE;
        }
    }
    return FALSE;
}

输出完备的文章标题

一般是处于 SEO 之用

/**
 * 导出标题
 *
 * @return void
 */
function title(Widget_Archive $archive){
    $archive->archiveTitle(array(
        'category'  =>  _t('分类 %s 下的文章'),
        'search'    =>  _t('包含关键字 %s 的文章'),
        'tag'       =>  _t('标签 %s 下的文章'),
        'author'    =>  _t('%s 发布的文章')
    ), '', ' - ');
    Helper::options()->title();
}

面包屑导航

用以输出当前位置相对主页的路由。

<?php if ($this->is('index')): ?><!-- 页面为首页时 -->
    文章列表 &raquo; 第&nbsp;<?php echo $this->_currentPage; ?>&nbsp;页
<?php elseif ($this->is('post')): ?><!-- 页面为文章单页时 -->
    文章 &raquo; <?php $this->title() ?>
<?php else: ?><!-- 页面为其他页时 -->
<?php $this->archiveTitle(array(
    'category'  =>  _t('分类 "%s" 下的文章'),
    'search'    =>  _t('包含关键字 "%s" 的文章'),
    'tag'       =>  _t('标签 "%s" 下的文章'),
    'author'    =>  _t('%s 发布的文章')
), '', ''); ?>
<?php endif; ?>

某些可以简化工作量的函数

$this->options->themeUrl('/some/path/'); //输出相对主题目录的路径
Helper::options()->pluginUrl; //获取插件目录
Helper::options()->index('/some/path/'); //输出相对博客根目录的路径

数据库相关

根据 CID 调用文章

$db = Typecho_Db::get();
$row = $db->fetchRow($db->select()->from('table.contents')->where('cid = ?', $cid));

$row 为 Ar­ray,包括了文章本题的许多字段,包括 title、创建日期等。

获得某文章的某自定义字段

$row = $db->fetchAll($db->select()->from('table.fields')->where('cid = ?', $cid)->where('name = ?', $fieldName));
$field=$row[0]['str_value'];

数据库相关属于比较高级的用法了,虽然在某些时候不得不用,但是最好还是使用 Type­cho 提供的更原生的方法。更多:Typecho 数据库常用 API

暂时就这些,后续想到再添加。

作者

熊猫小 A


路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部