typecho模板文件结构说明

文件名 作用 必须
style.css 主题样式文件 否
screenshot.png 主题缩略图 否
index.php 首页以及说明文件 是
404.php 404页面文件 否
archive.php 通用(分类、搜索、标签、作者)页面文件 否
category.php 分类页面文件 否
search.php 搜索页面文件 否
tag.php 标签页面文件 否
author.php 作者页面文件 否
comments.php 评论页面文件 否
footer.php 底部页面文件 否
functions.php 主题函数文件 否
header.php 头部页面文件 否
page.php 独立页面文件 否
post.php 日志页面文件 否
sidebar.php 侧边栏页面文件 否

PS:如果archive.php不存在,index.php也会作为通用页面,实现archive.php的工作。


模板制作快速入门

模板的制作并非难事,只要你写好了HTML和CSS,嵌套模板就非常简单了,你无需了解标签的内部结构,你只要会使用,模板就能迅速完成。这篇文章只简单的介绍了常用标签的使用方法,希望能带你进入模板的世界。^_^
本篇文章以Typecho都默认模板为例,您可以打开默认模板default边看边学习。该模板所在的路径为 /usr/themes/default
进入该目录后,我们可以看到有许多文件,别犯愁,我们将在下文一一介绍,所有在当前目录下的文件都能在后台的模板编辑页面进行编辑。

index.PHP

模板信息

我们先从主文件说起,打开这个文件,首先看到的是注释:

/**
 * 这是typecho系统的一套默认皮肤。你可以在<a href="http://typecho.org">typecho的官方网站</a>获得更多关于此皮肤的信息
 * 
 * @package Typecho Default Theme 
 * @author typecho
 * @version 1.0.0
 * @link http://typecho.org
 */

这是模板信息存放的地方,它将在后台都模板选择页显示。前两行是简短的介绍,每个“*”表示一个段落。@package 表示模板名,@author 表示作者名,@version 是模板的版本号,@link 是作者的网站连接。

紧挨着注释下方的 include('header.php'),在结尾处也会看到 include('sidebar.php') 和 include('footer.php')。这些语句用来调用模板的其它模块。header故名思议是页首,sidebar是侧栏,footer是页脚。

显示文章

<?php while($this->next()): ?>
    <div class="post">
    <h2 class="entry_title"><a href="<?php $this->permalink() ?>"><?php $this->title() ?></a></h2>
    <div class="entry_data">
        Published by <a href="<?php $this->author->permalink(); ?>"><?php $this->author(); ?></a> on <?php $this->date('F j, Y'); ?> in <?php $this->category(','); ?>.
        <?php $this->commentsNum('%d Comments'); ?>.
    </div>
    <div class="entry_text">
        <?php $this->content('Continue Reading...'); ?>
    </div>
    </div>
<?php endwhile; ?>

进入文章循环,输出文章,剥开html代码,一句一句介绍

<?php $this->permalink() ?>     文章所在的连接
<?php $this->title() ?>     文章标题
<?php $this->author(); ?>     文章作者
<?php $this->author->permalink(); ?>     文章作者地址
<?php $this->date('F j, Y'); ?>     文章的发布日期,格式可参考PHP日期格式
<?php $this->category(','); ?>     文章所在分类
<?php $this->commentsNum('%d Comments'); ?>     文章评论数及连接
<?php $this->content('Continue Reading...'); ?>     文章内容,其中的“Continue Reading…”是显示摘要时隐藏部分的邀请连接

好了,文章显示结束,别忘了结束循环。

文章分页

<?php $this->pageNav(); ?>

文章输出结束后别忘了增加分页,至此,index.php的常见内容结束,应该不糊涂吧。

header.php

编码

打开这个文件,见到的第一个php代码就是:

<meta http-equiv="content-type" content="text/html; charset=<?php $this->options->charset(); ?>" />

调用默认的编码,现在最经常用的大都是utf-8吧。所以我通常是直接写成utf-8,省去php处理时间。

页面标题

<title><?php $this->options->title(); ?><?php $this->archiveTitle(); ?></title>

通常情况下直接复制使用,如果你没有时间的话。

导入样式

<link rel="stylesheet" type="text/css" media="all" href="<?php $this->options->themeUrl('style.css'); ?>" />

其中style.css是样式文件相对模板目录的路径和文件名。

其它HTML头部信息

<?php $this->header(); ?>

自定义头部信息输出

在默认的模板中,头部信息的输出的结果是这样的

<meta name="description" content="Just So So ..." />
<meta name="keywords" content="typecho,php,blog" />
<meta name="generator" content="Typecho 0.8/10.8.15" />
<meta name="template" content="default" />
<link rel="pingback" href=".../action/xmlrpc" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href=".../action/xmlrpc?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href=".../action/xmlrpc?wlw" />
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href=".../feed/" />
<link rel="alternate" type="application/rdf+xml" title="RSS 1.0" href=".../feed/rss/" />
<link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href=".../feed/atom/" />

加上你要设置的参数即可,比如:

<?php $this->header('keywords=&generator=&template=&pingback=&xmlrpc=&wlw='); ?>

以上代码即可过滤关键词、程序、模板名称、文章引用、离线写作等信息的输出,具体效果如下。

<meta name="description" content="..." />
<link rel="alternate" type="applicationrss+xml" title="RSS 2.0" href=".../feed/" />
<link rel="alternate" type="application/rdf+xml" title="RSS 1.0" href=".../feed/rss/" />
<link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href=".../feed/atom/" />

操作参数及方法说明

keywords:关键词
description:描述、摘要
rss1:feed rss1.0
rss2:feed rss2.0
atom:feed atom
generator:程序版本等
template:模板名称
pingback:文章引用
xmlrpc:离线写作
wlw:m$的离线写作工具
commentReply:评论回复

等号(=)为空则不输出该项目,各个参数之间使用 “&” 连接。 如果需要自定义rss地址,只填上 rss2=feed订阅地址 即可。

页面导航

<ul class="clearfix" id="nav_menu">
    <li><a href="<?php $this->options->siteUrl(); ?>">Home</a></li>
    <?php $this->widget('Widget_Contents_Page_List')
               ->parse('<li><a href="{permalink}">{title}</a></li>'); ?>
</ul>

本处使用了无序列的页面列表,其中{permalink}是页面的地址,{title}是页面的标题

网站名称

<h1><a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a></h1>
<span><?php $this->options->description() ?></span>

<?php $this->options->siteUrl(); ?>     网站的首页地址
<?php $this->options->title() ?>     网站名称
<?php $this->options->description() ?>     网站的一些简短描述、介绍

站内搜索

<form method="post" action="">
    <div><input type="text" name="s" class="text" size="32" /> <input type="submit" class="submit" value="Search" /></div>
</form>

当你的文章很多很多,这个搜索就必不可少。

sidebar.php

最新文章列表

<ul>
    <?php $this->widget('Widget_Contents_Post_Recent')
               ->parse('<li><a href="{permalink}">{title}</a></li>'); ?>
</ul>

获取最新的10篇文章标题,得到的html是

<ul>
    <li><a href="http://example.com/2008/12/31/sample-post-one">文章1的标题</a></li>
    <li><a href="http://example.com/2008/12/31/sample-post-two">文章2的标题</a></li>
    <!-- 省略n个重复 -->
    <li><a href="http://example.com/2008/12/31/sample-post-ten">文章10的标题</a></li>
</ul>

最新回复列表

<ul>
    <?php $this->widget('Widget_Comments_Recent')->to($comments); ?>
    <?php while($comments->next()): ?>
        <li><?php $comments->author(false); ?>: <a href="<?php $comments->permalink(); ?>"><?php $comments->excerpt(10, '[...]'); ?></a></li>
    <?php endwhile; ?>
</ul>

获取最新的10个回复,得到的html是

<ul>
    <li>回复人名字: <a href="http://example.com/2008/12/31/sample-post#comments-12">回复的内容[...]</a></li>
    <li>回复人名字: <a href="http://example.com/2008/12/31/sample-post#comments-11">回复的内容[...]</a></li>
    <!-- 省略n个重复 -->
</ul>

其中<?php $comments->excerpt(10, '[...]'); ?>,“10”代表要回复内容截取的字的个数,“[…]”代表省略的意思,你可以自行修改。

文章分类列表

<ul>
    <?php $this->widget('Widget_Metas_Category_List')
               ->parse('<li><a href="{permalink}">{name}</a> ({count})</li>'); ?>
</ul>

输出:

<ul>
    <li><a href="http://example.com/category/uncategories">Uncategories</a>(10)</li>
    <li><a href="http://example.com/category/category-1">Category-1</a>(2)</li>
</ul>

其中{count}是获取该分类下的文章数目。

按月归档

<ul>
    <?php $this->widget('Widget_Contents_Post_Date', 'type=month&format=F Y')
               ->parse('<li><a href="{permalink}">{date}</a></li>'); ?>
</ul>

输出:

<ul>
    <li><a href="http://example.com/2008/11">November 2008</a></li>
    <li><a href="http://example.com/2008/10">October 2008</a></li>
</ul>

其它连接

<ul>
    <?php if($this->user->hasLogin()): ?>
        <li class="last"><a href="<?php $this->options->index('Logout.do'); ?>">Logout (<?php $this->user->screenName(); ?>)</a></li>
    <?php else: ?>
        <li class="last"><a href="<?php $this->options->adminUrl('login.php'); ?>">Login</a></li>
    <?php endif; ?>
</ul>

这些是可有可无的,只是为了方便登录登出。

footer.php

RSS地址

页脚文件,推荐大家把一些较大的js放在这个文件中最后载入,不会影响阅读。看看我们的footer要讲解些什么?

<a href="<?php $this->options->feedUrl(); ?>">Entries (RSS)</a> <!-- 文章的RSS地址连接 -->
<a href="<?php $this->options->commentsFeedUrl(); ?>">Comments (RSS)</a>. <!-- 评论的RSS地址连接 -->

现在,你已完成了75%的嵌套,休息一下,后面的会轻松许多 :-D

post.php

post页和index是差不多的,但是我们还是要说一下不同之处。

Tag 标签

Tags: <?php $this->tags(',', true, 'none'); ?>

这是获取当前单篇文章的标签,用“,”符号隔开。

调用评论页

<?php include('comments.php'); ?>

comments.php

评论列表

<h4><?php $this->commentsNum('No Response', 'One Response to"' . $this->title . '"', '%d Responses to "' . $this->title . '"'); ?></h4>
<ol id="comment_list">
    <?php $this->comments()->to($comments); ?>
        <?php while($comments->next()): ?>
    <li id="<?php $comments->theId(); ?>">
        <div class="comment_data">
                <?php echo $comments->sequence(); ?>. 
                <strong><?php $comments->author(); ?></strong>
                on <?php $comments->date('F jS, Y'); ?> at <?php $comments->date('h:i a'); ?>
            </div>
        <div class="comment_body"><?php $comments->content(); ?></div>
    </li>
    <?php endwhile; ?>
</ol>

还是循环输出评论:

<?php $comments->theId(); ?>     每个评论的唯一ID
<?php $comments->sequence(); ?>     评论所在楼层
<?php $comments->responseUrl(); ?>     回复地址
<?php $comments->responseId(); ?>     回复框ID
<?php $comments->trackbackUrl(); ?>     trackback地址
<?php $comments->author(); ?>     评论者的名字
<?php $comments->date('F jS, Y'); ?>     评论日期
<?php $comments->date('h:i a'); ?>     评论时间
<?php $comments->content(); ?>     评论内容

结束循环。我们用有序列表

    ,因为评论的发表是有先后顺序的。

    评论输入表单

    <!-- 判断设置是否允许对当前文章进行评论 -->
    <?php if($this->allow('comment')): ?>
    
        <h4 id="response">Leave a Reply</h4>
    
        <!-- 输入表单开始 -->
        <form method="post" action="<?php $this->commentUrl() ?>" id="comment_form">
    
            <!-- 如果当前用户已经登录 -->
            <?php if($this->user->hasLogin()): ?>
                <!-- 显示当前登录用户的用户名以及登出连接 -->
                <p>Logged in as <a href="<?php $this->options->adminUrl(); ?>"><?php $this->user->screenName(); ?></a>. 
                <a href="<?php $this->options->index('Logout.do'); ?>" title="Logout">Logout &raquo;</a></p>
    
            <!-- 若当前用户未登录 -->
            <?php else: ?>
                <!-- 要求输入名字、邮箱、网址 -->
            <p><input type="text" name="author" class="text" size="35" value="<?php $this->remember('author'); ?>" /><label>Name (Required)</label></p>
            <p><input type="text" name="mail" class="text" size="35" value="<?php $this->remember('mail'); ?>" /><label>E-mail (Required *will not be published)</label></p>
            <p><input type="text" name="url" class="text" size="35" value="<?php $this->remember('url'); ?>" /><label>Website</label></p>
            <?php endif; ?>
    
            <!-- 输入要回复的内容 -->
         <p><textarea rows="10" cols="50" name="text"><?php $this->remember('text'); ?></textarea></p>
         <p><input type="submit" value="Submit Comment" class="submit" /></p>
        </form>
    <?php endif; ?>

    很多情况下并不对评论文件进行修改,可以直接拿来使用写入相应的css。

    其它文件

    page.php 页面的显示方式,通常情况下和 single.php 无差别
    archive.php 显示某分类下的文章列表、搜索结果列表显示时调用的文件

    神奇的is语法

    typecho可以使用is语法判断很多东西,比如

    $this->is('index');
    $this->is('archive');
    $this->is('single');
    $this->is('page');
    $this->is('post');
    $this->is('category');
    $this->is('tag');

    甚至是

    $this->is('category', 'default');
    $this->is('page', 'start');
    $this->is('post', 1);

    需要注意的是,后面的参数是分类、页面的缩略名 写法

    <?php if ($this->is('post')) : ?>
        这里就是内容了
    <?php endif; ?>

    自定义页面title显示方式

    官方默认模板的title(html中的)如下:</p> <pre><code><?php $this->options->title(); ?><?php $this->archiveTitle(); ?></code></pre> <p>输出结果:站点名称 » 页面标题</p> <p>让我们来分解一下其中的语句,前一句大家都很明白,显示站点名称嘛,那后一句呢?其实后一句的标题包含三个参数:</p> <pre><code><?php $this->archiveTitle($split, $before, $end); ?> 参数名称 默认值 简介 $split &raquo; 多级菜单间的分隔符,如:2009 » 12 $before &raquo; title 前显示的字符 $end title 后显示的字符</code></pre> <p>这回清楚了吧?下面来自定义一个:</p> <pre><code><?php $this->archiveTitle('','',' - '); ?><?php $this->options->title(); ?></code></pre> <p>输出结果:页面标题 - 站点名称</p> <h2><a name="cl-34"></a>页面面包屑</h2> <p>什么是面包屑? 面包屑通常用来展示页面在站点中的位置,使访客不会迷失方向,如:Home » Journal » Hello World<br /> 在blog中,我们看看会有哪些路径出现:</p> <pre><code>首页 » 最新文章 首页 » 分类名称 » 文章标题 首页 » 归档年份 » 归档月份 首页 » 页面名称 首页 » 分类名称 首页 » 标签名称 首页 » 搜索关键词或其他信息</code></pre> <p>实际上title中的内容可以直接移植到我们的面包屑中,在看下面的代码之前,也许你需要先温习神奇的is语法。</p> <pre><code><div class="crumbs_patch"> <a href="<?php $this->options->siteUrl(); ?>">Home</a> &raquo;</li> <?php if ($this->is('index')): ?><!-- 页面为首页时 --> Latest Post <?php elseif ($this->is('post')): ?><!-- 页面为文章单页时 --> <?php $this->category(); ?> &raquo; <?php $this->title() ?> <?php else: ?><!-- 页面为其他页时 --> <?php $this->archiveTitle(' &raquo; ','',''); ?> <?php endif; ?> </div></code></pre> <p>将上面的代码放在需要显示的页面,例如index.php、post.php,抑或是header.php页面,保存后就可以查看结果,当然别忘了自定义样式哦。</p> <h2><a name="cl-35"></a>分离文章的评论和引用通告</h2> <p>打开模板的 comments.php 文件,找到通篇的核心语句:</p> <pre><code><?php $this->comments()->to($comments); ?></code></pre> <p>这条语句控制着评论的类型,他的参数如下:</p> <pre><code>语句 注释 <?php $this→comments()→to($comments); ?> 显示全部(默认) <?php $this→comments('comment')→to($comments); ?> 只显示 comment <?php $this→comments('trackback')→to($trackbacks); ?> 只显示 trackback <?php $this→comments('pingback')→to($pingbacks); ?> 只显示 pingback</code></pre> <p>为了分开,我们开始对 comments.php 做如下修改,首先只显示评论:</p> <pre><code><?php $this->comments('comment')->to($comments); ?><!-- 关键 --> <?php if ($comments->have()) : ?> <ol> <?php while ($comments->next()) : ?> <li id="<?php $comments->theId() ?>"> <div class="comment_data"> <?php $comments->gravatar(32, '', '', 'avatar'); ?> <span><?php $comments->author() ?></span> Says:<br /> <?php $comments->date('F jS, Y'); ?> at <?php $comments->date('h:i a'); ?> </div> <div class="comment_text"><?php $comments->content() ?></div> </li> <?php endwhile; ?> </ol> <?php endif; ?></code></pre> <p>然后输出 pingback,pingback 并不需要那么多的展示内容,假设只展示标题和日期:</p> <pre><code><?php $this->comments('pingback')->to($pingbacks); ?><!-- 关键 --> <?php if ($pingbacks->have()) : ?> <h3>Pingbacks</h3> <ol> <?php while ($pingbacks->next()) : ?> <li id="<?php $pingbacks->theId() ?>"> <?php $pingbacks->author() ?> <?php $pingbacks->date('F jS, Y'); ?> </li> <?php endwhile; ?> </ol> <?php endif; ?></code></pre> <p>如果你要显示 trackback,也可以按如上的修改。typecho 模板语法很多是通用的,所以当你遇到不清楚的问题时,可以自己试着拼凑一下,就会有惊喜哦。</p> <h2><a name="cl-36"></a>调用相关文章</h2> <p>刚开始用 typecho 的时候,都还不熟悉,有些功能都还不知道如何使用。这里,简单的介绍一下如何使用相关文章功能,方便刚接触 typecho 的朋友修改模板。 相关文章功能<br /> 用文本编辑器或网站后台的外观打开你所要修改的模板的文件夹中的post.php文件:</p> <pre><code><?php $this->related(5)->to($relatedPosts); ?> <ul> <?php while ($relatedPosts->next()): ?> <li><a href="<?php $relatedPosts->permalink(); ?>" title="<?php $relatedPosts->title(); ?>"><?php $relatedPosts->title(); ?></a></li> <?php endwhile; ?> </ul></code></pre> <p>将以上内容粘贴至你想加入相关文章的位置(例如我放在文章结束的位置),最后保存即可。</p> <h3><a name="cl-37"></a>相关文章函数说明</h3> <p>调用方法</p> <pre><code>$this->related($limits, $type);</code></pre> <p>这个函数有两个参数:</p> <pre><code>参数名称 说明 $limits 默认值为 5,表示显示的相关文章数量 $type 默认值为 NULL,表示文章的相关方式,只接受 author。当 $type 为 author 时,根据用户显示相关文章;为其他值时,根据标签显示相关文章。 ##调用某一分类下的文章 比如想某地方调用mid=1那个分类的文章列表..怎么使用呢? 例如: 分类id=1 分类id=2 文章1.. 文章1.. 文章2.. 文章2.. 文章3.. 文章3.. 文章4.. 文章4..</code></pre> <p>你可以这样调用</p> <pre><code><?php $this->widget('Widget_Archive@myCustomCategory', 'type=category', 'mid=1')->to($categoryPosts); ?></code></pre> <p>然后操作$categoryPosts这个变量即可</p> <h2><a name="cl-38"></a>分类描述</h2> <p>获取分类描述</p> <pre><code><?php echo $this->getDescription(); ?></code></pre> <p>鼠标悬停时显示分类描述</p> <pre><code><?php $this->widget('Widget_Metas_Category_List') ->parse('<li><a href="{permalink}" title="{description}">{name}</a> ({count})</li>'); ?></code></pre> <p>更多的信息可以查看Archive.php</p> <h2><a name="cl-39"></a>自定义模板</h2> <p>Typecho 自定义模板,一是自定义首页模板;二是自定义页面模板;这两者方法不同,下面具体说明。<br /> 自定义首页模板<br /> 在当前模板目录下面建你需要的文件(例如:home.php),然后再文件的开头加上如下代码(需在 package 后面加上 index)就算是自定义了好了一个首页;</p> <pre><code><?php /** * 自定义首页模板 * * @package index */</code></pre> <p>然后进入后台的『设置』-『文章』页面,选择“站点首页”中的“直接调用[home.php]模板文件”,保存即可。<br /> 自定义页面(page)模板<br /> 只需要在当前模板目录下面建你需要的文件,然后再文件的开头加上如下代码(需在 package 后面加上 custom)就算是自定义了好了一个页面,可以自定义多个页面;</p> <pre><code><?php /** * 自定义页面模板 * * @package custom */</code></pre> <p>其中 @package custom 是必须的,然后进入 typecho 后台在『创建页面』的【展开高级选项】里就可以看到<br /> 自定义分类模板</p> <h3><a name="cl-40"></a>方法一</h3> <p>直接在当前模板目录下建立一个名为 category 的目录,然后在里面放上以你需要单独做模板分类的缩略名为文件名的 php 文件,比如 default.php,这样,在访问缩略名为default的分类时,它会自动调用这个模板。</p> <h3><a name="cl-41"></a>方法二</h3> <p>在模板文件中使用 is 语法判断页面</p> <pre><code><?php if ($this->is('category', 'default')): ?> //默认分类模板 <?php endif; ?> <?php if ($this->is('category', 'category2')): ?> //分类2模板 <?php endif; ?></code></pre> <h3><a name="cl-42"></a>自定义页面列表显示条数</h3> <p>模板目录下建立一个名为 functions.php 的文件 然后里面写一个函数(示例是控制 jobs 分类下的文章列表显示条数为 10 条)</p> <pre><code>function themeInit($archive) { if ($archive->is('category', 'jobs')) { $archive->parameter->pageSize = 10; // 自定义条数 } }</code></pre> <h2><a name="cl-43"></a>自定义404页面</h2> <p>使用自定义的404页面非常简单,只需要如下两步</p> <p>自己制作一个HTML页面,把它命名为404.php<br /> 把这个页面放到你当前的模板目录下</p> <h3><a name="cl-44"></a>自定义错误页面</h3> <p>如果你厌倦了千篇一律的typecho报错页面,你可以通过以下简单的方法来使用自己的报错页面</p> <p>随便创建一个php文件(有两个变量你可以在这个php里直接使用,分别为$code和$message,它们分别代表错误代码和错误信息)<br /> 把它传到你服务器的某个路径<br /> 打开config.inc.php,加入一行</p> <pre><code>define('__TYPECHO_EXCEPTION_FILE__', '你的文件路径');</code></pre> <p>后面的报错就会显示你的页面了</p> <h2><a name="cl-45"></a>自定义评论列表区域</h2> <h3><a name="cl-46"></a>一、自定义单条评论的HTML代码</h3> <p>在自定义评论前,我们得先设计好单条评论的 HTML 代码结构,如:</p> <pre><code><li id="li-comment-520" class="comment-body comment-parent comment-odd"> <div id="comment-520"> <div class="comment-author"> <img class="avatar" src="avatar.png" alt="" width="40" height="40"> <cite class="fn"><a href="评论者主页">评论者名字</a></cite> </div> <div class="comment-meta"> <a href="评论地址">评论时间</a> <span class="comment-reply">回复按钮</span> </div> <p>我是评论内容</p> </div><!-- 单条评论者信息及内容 --> <div class="comment-children"> <!-- 嵌套评论相关 --> </div> </li></code></pre> <p>自定义好HTML代码后,将如何去实现呢?首先我们要打开模板文件夹里的 comments.php 文件,做好修改准备。</p> <h3><a name="cl-47"></a>二、使用自定义评论函数</h3> <p>打开 comments.php 文件后,我们需要在它的顶部,插入以下函数代码:</p> <pre><code><?php function threadedComments($comments, $options) { $commentClass = ''; if ($comments->authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; //如果是文章作者的评论添加 .comment-by-author 样式 } else { $commentClass .= ' comment-by-user'; //如果是评论作者的添加 .comment-by-user 样式 } } $commentLevelClass = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级 ?> /* 自定义评论的代码结构 */ <?php } ?></code></pre> <p>其次,将我们刚才自定义好的单条评论的 HTML 代码,放在上面代码里注释的地方,如下:</p> <pre><code><?php function threadedComments($comments, $options) { $commentClass = ''; if ($comments->authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; //如果是文章作者的评论添加 .comment-by-author 样式 } else { $commentClass .= ' comment-by-user'; //如果是评论作者的添加 .comment-by-user 样式 } } $commentLevelClass = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级 ?> /* 自定义评论的代码结构 */ <li id="li-comment-520" class="comment-body comment-parent comment-odd"> <div id="comment-520"> <div class="comment-author"> <img class="avatar" src="avatar.png" alt="" width="40" height="40"> <cite class="fn"><a href="评论者主页">评论者名字</a></cite> </div> <div class="comment-meta"> <a href="评论地址">评论时间</a> <span class="comment-reply">回复按钮</span> </div> <p>我是评论内容</p> </div><!-- 单条评论者信息及内容 --> <div class="comment-children"> <!-- 嵌套评论相关 --> </div> </li> <?php } ?></code></pre> <h3><a name="cl-48"></a>三、用系统的评论变量替换HTML中相关属性</h3> <p>把 HTML 里相关的属性,替换成 typecho 系统中的评论变量,变量的列表可以参考下面。下面的例子,是替换评论的 id:</p> <pre><code><!-- 替换前 --> <li id="li-comment-520" class="comment-body comment-parent comment-odd"> /* 替换后 */ <li id="li-<?php $comments->theId(); ?>" class="comment-body<?php if ($comments->_levels > 0) { echo ' comment-child'; $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); } else { echo ' comment-parent'; } $comments->alt(' comment-odd', ' comment-even'); echo $commentClass; ?>"></code></pre> <p>其中,替换ID这里,还需要判断判断当前评论是父级评论还是子级评论,且判断评论 ID 的奇偶数等。</p> <h3><a name="cl-49"></a>四、添加嵌套评论(子评论)</h3> <p>替换前:</p> <pre><code><div class="comment-children"> <!-- 嵌套评论相关 --> </div></code></pre> <p>替换后后如下:</p> <pre><code><?php if ($comments->children) { ?> //是否嵌套评论判断开始 <div class="comment-children"> <?php $comments->threadedComments($options); ?> //嵌套评论所有内容 </div> <?php } ?> //是否嵌套评论判断结束</code></pre> <h3><a name="cl-50"></a>五、相关变量及说明</h3> <pre><code><?php $comments->gravatar('40', ''); ?> //头像,有两个参数,大小、默认头像? <?php $comments->author(); ?> //评论作者 <?php $comments->permalink(); ?> //当前评论的连接地址 <?php $comments->date('Y-m-d H:i'); ?>//评论时间,可在括号里设置格式 <?php $comments->reply(); ?> //回复按钮,可在括号里自定义评论按钮的文字 <?php $comments->content(); ?> //评论内容</code></pre> <h3><a name="cl-51"></a>六、最终得到的代码</h3> <p>当我们把上面所有变量都替换完成之后,最终得到的代码如下:</p> <pre><code><?php function threadedComments($comments, $options) { $commentClass = ''; if ($comments->authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; } else { $commentClass .= ' comment-by-user'; } } $commentLevelClass = $comments->levels > 0 ? ' comment-child' : ' comment-parent'; ?> <li id="li-<?php $comments->theId(); ?>" class="comment-body<?php if ($comments->levels > 0) { echo ' comment-child'; $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); } else { echo ' comment-parent'; } $comments->alt(' comment-odd', ' comment-even'); echo $commentClass; ?>"> <div id="<?php $comments->theId(); ?>"> <div class="comment-author"> <?php $comments->gravatar('40', ''); ?> <cite class="fn"><?php $comments->author(); ?></cite> </div> <div class="comment-meta"> <a href="<?php $comments->permalink(); ?>"><?php $comments->date('Y-m-d H:i'); ?></a> <span class="comment-reply"><?php $comments->reply(); ?></span> </div> <?php $comments->content(); ?> </div> <?php if ($comments->children) { ?> <div class="comment-children"> <?php $comments->threadedComments($options); ?> </div> <?php } ?> </li> <?php } ?></code></pre> <p>注意:上面的自定义评论代码输出的,就是本来评论页里的下面这段代码,所以你就不用对这段代码做任何更改了。</p> <pre><code><?php $comments->listComments(); ?></code></pre> <p>最新版本更新:首次评论审核提示,在自定义评论代码的适当地方添加以下语句,否则将看不到审核提示语句。</p> <pre><code><?php $singleCommentOptions->commentStatus(); ?></code></pre> <h2><a name="cl-52"></a>输出标签云</h2> <h3><a name="cl-53"></a>例子</h3> <pre><code><?php $this->widget('Widget_Metas_Tag_Cloud', 'sort=mid&ignoreZeroCount=1&desc=0&limit=30')->to($tags); ?> <?php if($tags->have()): ?> <ul class="tags-list"> <?php while ($tags->next()): ?> <li><a href="<?php $tags->permalink(); ?>" rel="tag" class="size-<?php $tags->split(5, 10, 20, 30); ?>" title="<?php $tags->count(); ?> 个话题"><?php $tags->name(); ?></a></li> <?php endwhile; ?> <?php else: ?> <li><?php _e('没有任何标签'); ?></li> <?php endif; ?> </ul></code></pre> <h3><a name="cl-54"></a>参数说明</h3> <p>sort:排序方式为 mid;<br /> ignoreZeroCount:忽略文章数为 0 的;<br /> desc:是否降序输出;<br /> limit:输出数目。</p> <h3><a name="cl-55"></a>随机颜色标签云</h3> <pre><code><?php $this->widget('Widget_Metas_Tag_Cloud', 'ignoreZeroCount=1&limit=30')->to($tags); ?> <ul class="tags-list"> <?php while($tags->next()): ?> <li><a style="color: rgb(<?php echo(rand(0, 255)); ?>, <?php echo(rand(0,255)); ?>, <?php echo(rand(0, 255)); ?>)" href="<?php $tags->permalink(); ?>" title='<?php $tags->name(); ?>'><?php $tags->name(); ?></a></li> <?php endwhile; ?> </ul></code></pre> <h2><a name="cl-56"></a>输出$this的所有内容</h2> <pre><code><?php print_r($this);?></code></pre> <p>转自:https://www.lvtao.net/dev/typecho_template.html</p> </article> <div class="stepass"> <button onclick="show_reward()" class="btn_reward">打赏</button> <link rel="stylesheet" href="/usr/plugins/TePass/static/css/style.css?v=0.8.2" type="text/css" /> <script src="/usr/plugins/TePass/static/js/tepass.js?v=0.8.2" async="async"></script> <div class="tepasspost" id="div_reward"> <form id="tepassReward" onsubmit="return false" action="##" method="post"> <div class="feetype"> <label for="feetype2"><img id="labe2" src="/usr/plugins/TePass/static/alipay2.png" nogallery="nogallery" no-zoom="true"><span>支付宝支付</span></label> <input type="radio" id="feetype2" name="feetype" value="alipay" checked="checked"></div> <div class="cl"></div>您的大名:<input type="text" id="reward_from" name="reward_from" value="匿名" placeholder="控制10个字内" required="required"/> <select name="reward_money" id="reward_money"> <option value="1">1 元</option> <option value="5" selected="selected">5 元</option> <option value="10">10 元</option> <option value="20">20 元</option> <option value="50">50 元</option> <option value="100">100 元</option> </select> <div class="cl"></div><input type="hidden" id="userAgent" name="userAgent" value="isDesktop" /> <input id="verifybtn" onclick="tepassReward();" οnkeydοwn="enter_down(this.form, event);" type="button" value="打赏"/> <input type="hidden" name="action" value="payrewardsubmit" /> <input type="hidden" id="callback_url" name="callback_url" value="http://chujian.xyz/tepass/notice?tip=pay_post_success/2018/2981.html" /> <input type="hidden" id="feecid" name="feecid" value="2981" /> <input type="hidden" id="feeuid" name="feeuid" value="" /> <input type="hidden" id="tepass_time" name="tepass_time" value="15kFtbHhEpDhQ" /> <input type="hidden" id="tepass_sign" name="tepass_sign" value="6790BF7DA4F8B7012B28B7F077553CF7" /> </form> <div class="cl"></div> <span class="tips">万水千山总是情,给个打赏行不行。</span> <span class="tepass_top_left">打赏</span> <span class="tepass_top_right"><img src="/usr/plugins/TePass/static/icon.png" nogallery="nogallery" no-zoom="true"></span> <div id="qrcode_box"></div><div id="bgdiv"></div> </div> <style type="text/css"> #div_reward { display: none; } .btn_reward { border-style: none; border-radius: 5px; width: 80px; height: 30px; background-color: #f17425 !important; line-height: 30px; text-align: center; color: #FFF; margin: 0 auto; display: block; font-weight: normal; } </style> <script type="text/javascript"> function show_reward (event) { //取消冒泡 let oevent = event || window.event if (document.all) { oevent.cancelBubble = true } else { oevent.stopPropagation() } if (document.getElementById("div_reward").style.display === "none" || document.getElementById("div_reward").style.display === "") { document.getElementById("div_reward").style.display = "block" } else { document.getElementById("div_reward").style.display = "none" } } document.onclick = function () { document.getElementById("div_reward").style.display = "none" } document.getElementById("div_reward").onclick = function (event) { let oevent = event || window.event oevent.stopPropagation() } </script></div> <p class="ad" id="hitokoto">:D 少女祈祷中...</p> <div class="tags"> <a href="http://chujian.xyz/tag/Typecho/">Typecho</a> <a href="http://chujian.xyz/category/Resources/">分享</a> <span class="diyyuedu"># 242 阅读</span> </div> <div id="comments" class="doc_comments"> <link rel="stylesheet" href="https://chujian.xyz/usr/themes/chopstack/css/OwO.min.css" type="text/css" /> <script src="https://chujian.xyz/usr/themes/chopstack/js/OwO.min.js" type="text/javascript" charset="utf-8"></script> <div id="respond-post-2981" class="respond"> <div class="cancel-comment-reply"> <a id="cancel-comment-reply-link" href="http://chujian.xyz/2018/2981.html#respond-post-2981" rel="nofollow" style="display:none" onclick="return TypechoComment.cancelReply();">取消回复</a> </div> <div id="response"><h4>我是誰?我在哪?我要幹什麽?</h4></div> <form id="new_comment_form" method="post" action="http://chujian.xyz/2018/2981.html/comment" _lpchecked="1"> <div class="new_comment"><textarea name="text" rows="2" class="textarea_box OwO-textarea" style="height: auto;" placeholder="「雲想衣裳 花想容」....在下李白,在....什麽大唐亡了?這裏是stars.xyz?劍來!我要砍死這個發廣告的!"></textarea><div title="OwO" class="OwO"></div></div> <span class="comment-mail-me"> <input name="receiveMail" type="checkbox" value="yes" checked /> <label for="receiveMail">有回复时通知我</label> </span> <div class="comment_triggered" style="display: block;"> <div class="input_body"> <ul class="ident"> <li> <input type="text" name="author" placeholder="你的名字*" value=""> </li> <li> <input type="mail" name="mail" placeholder="邮箱*" value=""> </li> <li> <input type="text" name="url" placeholder="网址" value=""> </li> </ul> <input type="submit" value="到此一遊" class="comment_submit_button c_button"> </div> </div> </form> </div> <!-- OWO 表情 --> <script> var OwO_demo = new OwO({ logo: 'OωO表情', container: document.getElementsByClassName('OwO')[0], target: document.getElementsByClassName('OwO-textarea')[0], api: '/usr/themes/chopstack/js/OwO.min.json', position: 'down', width: '100%', maxHeight: '250px' }); </script> </div> </div> </div> </div> <!-- 一言 --> <script src="https://cdn.jsdelivr.net/npm/bluebird@3/js/browser/bluebird.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js"></script> <!--End--> <script> fetch('https://v1.hitokoto.cn') .then(function (res){ return res.json(); }) .then(function (data) { var hitokoto = document.getElementById('hitokoto'); hitokoto.innerText = data.hitokoto; }) .catch(function (err) { console.error(err); }) </script> </div> </div> </section> <section id="footer"> <div class="body_container"> <div class="foot-log"> <div class="footer-copyright"> © <a href="https://chujian.xyz/" real="nofollow">True's ME</a> — 始于<a rel="nofollow" target="_blank" href="/about.html">2004</a> 追寻着释然的态度....5726天 </div> <div class="footer-links hidden-if-min"> <b style="color: #ff4425;">♥</b>纪念<a rel="nofollow" target="_blank" href="/2018/2576.html">Moonice</a>已逝的兄弟 . Powered by <a rel="nofollow" target="_blank" href="http://typecho.org">Typecho</a>. Theme by <a rel="nofollow" target="_blank" href="http://chopstack.com">Cho</a> & <a rel="nofollow" target="_blank" href="https://mrju.cn/">MrJu</a> . <span class="hidden-if-min"><a rel="nofollow" target="_blank" href="http://www.miitbeian.gov.cn">土星ICP备3.14159265号</a> . </span> </div> </div> </div> </section> </div> <script type="text/javascript" src="https://chujian.xyz/usr/plugins/Meting/assets/Meting.min.js?v=2.1.2"></script> <script type="text/javascript" src="https://chujian.xyz/usr/plugins/Highlight/res/highlight.js?version=9.12.0"></script><script type="text/javascript">$("pre code").each(function(i, block) {hljs.highlightBlock(block);});</script><script> SearchConfig = { url : "https://chujian.xyz/usr/plugins/Handsome/cache/search.json" } </script> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script><script> (function(){ var base = 50; $.each($('.photos'), function(i, photoSet){ $.each($(photoSet).children(), function(j, item){ var img = new Image(); img.src = $(item).find('img').attr('src'); img.onload = function(){ var w = parseFloat(img.width); var h = parseFloat(img.height); $(item).css('width', w*base/h +'px'); $(item).css('flex-grow', w*base/h); $(item).find('div').css('padding-top', h/w*100+'%'); }; }); }); })(); </script> <script src="https://chujian.xyz/usr/plugins/plyr/plyr.polyfilled.min.js"></script> <script> var eles = document.querySelectorAll("audio, video"); var players = []; for(var i = 0, len = eles.length; i < len; i++) { players.push(new Plyr(eles[i], { autoplay: false, i18n: { restart: "重新开始", rewind: "后退 {seektime} 秒", play: "播放", pause: "暂停", fastForward: "快进 {seektime} 秒", seek: "进度", played: "Played", buffered: "缓冲", currentTime: "当前时间", duration: "持续", volume: "音量", mute: "静音", unmute: "取消静音", enableCaptions: "启用字幕", disableCaptions: "禁用字幕", enterFullscreen: "进入全屏", exitFullscreen: "退出全屏", frameTitle: "Player for {title}", captions: "字幕", settings: "设置", speed: "速度", normal: "正常", quality: "品质", loop: "循环", start: "开始", end: "结束", all: "全部", reset: "重置", disabled: "Disabled", advertisement: "广告", } })); } </script><div class="directory"><div id="toc-container"> <div id="toc"> <strong>文章目录</strong> <ul> <li><a href="#cl-1">typecho模板文件结构说明</a></li> <li><a href="#cl-2">模板制作快速入门</a></li> <li><a href="#cl-3">index.PHP</a><ul> <li><a href="#cl-4">模板信息</a></li> <li><a href="#cl-5">显示文章</a></li> <li><a href="#cl-6">文章分页</a></li> </ul> </li><li><a href="#cl-7">header.php</a><ul> <li><a href="#cl-8">编码</a></li> <li><a href="#cl-9">页面标题</a></li> <li><a href="#cl-10">导入样式</a></li> <li><a href="#cl-11">其它HTML头部信息</a></li> <li><a href="#cl-12">自定义头部信息输出</a></li> <li><a href="#cl-13">页面导航</a></li> <li><a href="#cl-14">网站名称</a></li> <li><a href="#cl-15">站内搜索</a></li> </ul> </li><li><a href="#cl-16">sidebar.php</a><ul> <li><a href="#cl-17">最新文章列表</a></li> <li><a href="#cl-18">最新回复列表</a></li> <li><a href="#cl-19">文章分类列表</a></li> <li><a href="#cl-20">按月归档</a></li> <li><a href="#cl-21">其它连接</a></li> </ul> </li><li><a href="#cl-22">footer.php</a><ul> <li><a href="#cl-23">RSS地址</a></li> </ul> </li><li><a href="#cl-24">post.php</a><ul> <li><a href="#cl-25">Tag 标签</a></li> <li><a href="#cl-26">调用评论页</a></li> </ul> </li><li><a href="#cl-27">comments.php</a><ul> <li><a href="#cl-28">评论列表</a></li> <li><a href="#cl-29">还是循环输出评论:</a></li> <li><a href="#cl-30">评论输入表单</a></li> </ul> </li><li><a href="#cl-31">其它文件</a></li> <li><a href="#cl-32">神奇的is语法</a></li> <li><a href="#cl-33">自定义页面title显示方式</a></li> <li><a href="#cl-34">页面面包屑</a></li> <li><a href="#cl-35">分离文章的评论和引用通告</a></li> <li><a href="#cl-36">调用相关文章</a><ul> <li><a href="#cl-37">相关文章函数说明</a></li> </ul> </li><li><a href="#cl-38">分类描述</a></li> <li><a href="#cl-39">自定义模板</a><ul> <li><a href="#cl-40">方法一</a></li> <li><a href="#cl-41">方法二</a></li> <li><a href="#cl-42">自定义页面列表显示条数</a></li> </ul> </li><li><a href="#cl-43">自定义404页面</a><ul> <li><a href="#cl-44">自定义错误页面</a></li> </ul> </li><li><a href="#cl-45">自定义评论列表区域</a><ul> <li><a href="#cl-46">一、自定义单条评论的HTML代码</a></li> <li><a href="#cl-47">二、使用自定义评论函数</a></li> <li><a href="#cl-48">三、用系统的评论变量替换HTML中相关属性</a></li> <li><a href="#cl-49">四、添加嵌套评论(子评论)</a></li> <li><a href="#cl-50">五、相关变量及说明</a></li> <li><a href="#cl-51">六、最终得到的代码</a></li> </ul> </li><li><a href="#cl-52">输出标签云</a><ul> <li><a href="#cl-53">例子</a></li> <li><a href="#cl-54">参数说明</a></li> <li><a href="#cl-55">随机颜色标签云</a></li> </ul> </li><li><a href="#cl-56">输出$this的所有内容</a></li> </ul> </div> </div> </div> <div class="back-to-top cd-top faa-float animated cd-is-visible" style="top: -900px;"></div> <script src="https://chujian.xyz/usr/themes/chopstack/js/szgotop.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> jQuery(document).ready(function(){jQuery("a[rel='external'],a[rel='external nofollow']").click(function(){window.open(this.href);return false})}); </script> </body> </html>