【Emlog6.1.1】主题模板制作快速入门

模板的制作并非难事,只要你写好了HTML和CSS,嵌套模板就非常简单了,你无需了解标签的内部结构,你只要会使用,模板就能迅速完成。这篇文章只简单的介绍了常用标签的使用方法,希望能带你进入模板的世界。^_^
本篇文章以Emlog的默认模板为例,您可以打开默认模板default边看边学习。该模板所在的路径为 /content/templates/default,每个模板都是一个单独的文件夹,文件夹以模板名字命名。通过后台上传安装的模板都保存在这个目录下。进入该目录后,我们可以看到有许多文件,别犯愁,我们将在下文一一介绍。
http://emlog.tongleer.com

准备工作

一、在准备开始主题开发之前,你必须具备以下条件:

  1. 能够在本地运行的web开发服务器,并装好Emlog的最新版本。(如果你没有安装,我们推荐XAMPP)

  2. 基本的HTML知识

  3. 少得可怜的php知识

二、主题下载

https://joke.tongleer.com/category/program/

模板文件结构说明

文件名 作用 必须
images文件夹 存放模板所需图片
preview.jpg 在后台模板选择界面显示的模板预览图,300×225 jpg格式。
404.php 自定义404页面未找到时的报错页面
header.php 头部页面文件
footer.php 底部页面文件
log_list.php 显示日志列表内容
echo_log.php 显示日志内容
module.php 模板公共代码,包含侧边widgets、评论、引用、编辑等,该文件是模板最核心的模块。
page.php 自定义的页面内容的模板。
side.php 模板侧边栏文件,如制作单栏模板则该文件不是必须的。
t.php 显示emlog系统自带的微博(碎语)内容。

公共代码分析

通过预览整个模板中的各个文件,你会发现以下代码同时存在于多个文件中,这些代码分别有以下用途: 

  •  
  •  
  •  
  •  
  •  
  •  
/* * 此行代码存在于模板目录下的每个php文件起始部分(事实上为了安全起见, * 该行代码也在admin目录下的几乎所有php文件起始部分存在), * 其作用是防止代码所在的php脚本被直接访问执行。 */if(!defined('EMLOG_ROOT')) {exit('error!');}

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
/* * 这两行代码存在于log_list.php、echo_log.php、page.php、t.php里面, * 其作用是调用模板文件夹下的side.php和footer.php的代码到当前文件的 * 当前位置。View是emlog的模板视图控制器, * View::getView('文件名','文件后缀')将返回当前模板安装路径下对应的文件。 * getView函数的第二个参数为缺省参数,在不传入值的情况下, * 将默认作为.php文件后缀返回文件路径。 */require_once View::getView('side');require_once View::getView('footer');

header.php

一、开头注释内容是模板信息,该信息显示在模板选择界面

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
/*Template Name:模板名称Description:模板介绍描述Version:模板版本ForEmlog:适用版本Author:模板作者Author Url:作者或模板发布的URLSidebar Amount:标记该模板有几个侧边栏,一般为1,有些模板有两个侧边栏则标记2。这样可以在后台widgets里识别管理*/

二、编码

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

  •  
meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

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

三、页面标题

  •  
title> echo $site_title; ?>title>

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

四、导入样式

  •  
"style.css" rel="stylesheet" type="text/css" />

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

五、其它HTML头部信息

  •  
 doAction('index_head'); ?>

别忘了这句,前台头部扩展,它关系到增加前台css样式、加载js以及插件的正常使用。

六、页面导航

  •  
 blog_navi();?>

它定义在了module.php中,使用缓存循环输出导航数据。

  •  
  •  
global $CACHE; $navi_cache = $CACHE->readCache('navi');

七、网站名称

  •  
  •  
  •  
 echo BLOG_URL; ?>//网站的首页地址 echo $blogname; ?>//网站名称 echo $bloginfo; ?>//网站的一些简短描述、介绍

八、站内搜索

  •  
  •  
  •  
form name="keyform" method="get" action="index.php">  input name="keyword" type="text" />form>

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

九、一些模板公共代码

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
if(!defined('EMLOG_ROOT')) {exit('error!');}//该行代码同样存在于其它模板文件中,为防止该文件被直接执行。require_once View::getView('module');$site_title//站点标题$site_key//关键字$site_description//输出博客设置的摘要BLOG_URL//博客首页的URLTEMPLATE_URL//模板文件夹的URL,用于加载模板内的css、js及其他内容Option::get('blogname')//使用Option配置类获取数据表options中的配置,此处获取的是博客名
echo $curpage == CURPAGE_HOME ? 'current' : 'common';?> //判断当前是否首页,是则给导航加current类,用于表现当前位置。 if($istwitter == 'y'):?> endif;?>//如后台设置在前台显示碎语,则输出…….中的内容。
echo $curpage == CURPAGE_TW ? 'current' : 'common';?>//判断当前URL是否为微语并选择加类名。
foreach ($navibar as $key ⇒ $val):?> endforeach;?>//输出自定义页面的链接

index.php

一、显示文章

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
if (!empty($logs)){  foreach($logs as $value){?>    div>$value['logid']div>     }}?>

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

类型 代码
文章所在的连接 Url::log($value[‘logid’])
文章标题 $value[‘log_title’]
文章作者ID $value[‘author’]
文章作者地址 Url::author($value[‘author’])
文章的发布日期,格式可参考PHP日期格式 date(‘Y-n-j’, $value[‘date’])
文章所在分类 blog_sort($value[‘logid’])//blog_sort在model.php中自己定义
文章评论数 $value[‘comnum’]
文章内容 $value[‘log_description’]

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

二、文章分页

  •  
 echo $page_url;?>

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

三、一些模板公共代码

 doAction('index_loglist_top');?>//文章列表顶部挂载点加入。$value['logid']//该变量为当前日志的id topflg($value['top']); ?>//显示置顶标记,该函数位于模板module.php内。 echo $value['log_url']; ?>//输出日志URL blog_author($value['author']);?>//输出日志的作者,该函数位于模板module.php内。 editflg($value['logid'],$value['author']); ?>//当管理员或作者登陆时显示“编辑”链接,该函数位于模板module.php内。 blog_att($value['logid']); ?>//如日志有附件则输出附件,该函数位于模板module.php内。 blog_tag($value['logid']); ?>//输出日志的标签,该函数位于模板module.php内。 echo $value['tbcount'];?>//输出当前日志的引用量 echo $value['views']; ?>//输出当前日志的浏览量 echo $page_url;?>//显示当前列表页的翻页功能。 include View::getView('side'); include View::getView('footer');?>//加入侧边栏及加入页脚。

footer.php

  •  
  •  
  •  
  •  
  •  
"https://www.tongleer.com">同乐儿//以示对同乐儿的支持 echo BLOG_URL; ?>rss.php//RSS地址Option::EMLOG_VERSION//获得版本号。$icp//获得后台设置的ICP备案号。 doAction('index_footer'); ?>//页脚底部挂载点加入。

echo_log.php

该文件功能函数与列表页一致,但参数有区别,注意区分。$logid 该变量为当前日志的id

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
 topflg($top); ?>//显示置顶标记,该函数位于模板module.php内。 echo $log_title; ?>//输出日志标题。 blog_author($author);  ?>//输出日志的作者,该函数位于模板module.php内。 echo date('Y-n-j G:i l', $date); ?>//输出日志发布时间,参数'Y-n-j G:i l'用于定义日期格式。 blog_sort($logid); ?>//输出日志所属的分类,该函数位于模板module.php内。 editflg($logid,$author); ?>//当管理员或作者登陆时显示“编辑”链接,该函数位于模板module.php内。 echo $log_content; ?>//输出日志全文内容。 blog_att($logid); ?>//如日志有附件则输出附件,该函数位于模板module.php内。 blog_tag($logid); ?>//输出日志的标签,该函数位于模板module.php内。 echo $comnum;?>//日志页显示评论数 echo $tbcount; ?>//日志页显示引用数 echo $views; ?>//日志页显示浏览量 doAction('log_related', $logData); ?>//相关日志的挂载点,与3.x版本不同,4.0带第二参数。 neighbor_log($neighborLog);?>//输出邻近,就是上一篇及下一篇,该函数位于模板module.php内。 blog_trackback($tb, $tb_url, $allow_tb); ?>//输出该日志被引用的信息列表,与3.x不同注意区分。 blog_comments($comments); ?>//输出该日志评论列表,与3.x不同注意区分。 blog_comments_post($logid,$ckname,$ckmail,$ckurl,$verifyCode,$allow_remark); ?>//输出发表评论框,与3.x不同注意区分。

page.php

该文件写法与echo_log.php类似,不再重复。

t.php

与之前相同的内容不再重复。

404.php

用于自定义404页面的模板。

 

side.php

侧边栏,主要负责根据后台widgets设置信息输出侧边栏内容。建议该文件内代码保持不变,主要代码如下:

   $widgets = !empty($options_cache['widgets1']) ? unserialize($options_cache['widgets1']) : array();  doAction('diff_side');  foreach ($widgets as $val)  {    $widget_title = @unserialize($options_cache['widget_title']);    $custom_widget = @unserialize($options_cache['custom_widget']);    if(strpos($val, 'custom_wg_') === 0)    {      $callback = 'widget_custom_text';      if(function_exists($callback))      {        call_user_func($callback, htmlspecialchars($custom_widget[$val]['title']), $custom_widget[$val]['content']);      }    }else{      $callback = 'widget_'.$val;      if(function_exists($callback))      {        preg_match("/^.*s((.*))/", $widget_title[$val], $matchs);        $wgTitle = isset($matchs[1]) ? $matchs[1] : $widget_title[$val];        call_user_func($callback, htmlspecialchars($wgTitle));      }    }  }  ?>

module.php

模板公共代码,包含侧边widgets、评论、引用、编辑等。 该文件由若干函数组成,被博客前台文件调用,可在内自定义函数实现更多功能。 如在自定义函数内调用emlog缓存时,假设读取user缓存信息,则形如:

global $CACHE;

$user_cache = $CACHE->readCache(‘user’);

如需要操作数据库,则形如:

$DB = Database::getInstance();

$res = $DB->query($sql);。

一、个人资料模块

  •  
  •  
  •  
  •  
  •  
function widget_blogger($title){  global $CACHE;  $user_cache = $CACHE->readCache('user');  ……}

二、日历模块

  •  
  •  
  •  
  •  
 function widget_calendar($title){?>div class="layui-row layui-col-space15" id="calendar">div>script>sendinfo(' echo Calendar::url(); ?>','calendar');script> }?>

三、标签模块

  •  
  •  
  •  
  •  
  •  
function widget_tag($title){  global $CACHE;  $tag_cache = $CACHE->readCache('tags');  ……}

四、分类模块

  •  
  •  
  •  
  •  
  •  
function widget_sort($title){  global $CACHE;  $sort_cache = $CACHE->readCache('sort');  ……}

五、最新微语模块

  •  
  •  
  •  
  •  
  •  
function widget_sort($title){  global $CACHE;  $sort_cache = $CACHE->readCache('sort');  ……}

六、最新微语模块

  •  
  •  
  •  
  •  
  •  
  •  
function widget_twitter($title){  global $CACHE;  $newtw_cache = $CACHE->readCache('newtw');  $istwitter = Option::get('istwitter');  ……}

七、最新评论模块

  •  
  •  
  •  
  •  
  •  
function widget_newcomm($title){  global $CACHE;  $comment_cache = $CACHE->readCache('comment');  ……}

八、最新文章模块

  •  
  •  
  •  
  •  
  •  
function widget_newlog($title){  global $CACHE;  $newlog_cache = $CACHE->readCache('newlog');  ……}

九、热门文章模块

  •  
  •  
  •  
  •  
  •  
  •  
  •  
function widget_hotlog($title){  $DB = Database::getInstance();  $index_hotlognum = Option::get('index_hotlognum');  $Log_Model = new Log_Model();  $randLogs = $Log_Model->getHotLog($index_hotlognum);  ……}

十、随机文章模块

  •  
  •  
  •  
  •  
  •  
  •  
  •  
function widget_random_log($title){  $DB = Database::getInstance();  $index_randlognum = Option::get('index_randlognum');  $Log_Model = new Log_Model();  $randLogs = $Log_Model->getRandLog($index_randlognum);  ……}

十一、搜索模块

  •  
  •  
  •  
  •  
  •  
 function widget_search($title){ ?>form name="keyform" method="get" action="index.php">  input name="keyword" type="text" />form> }?>

十二、归档模块

  •  
  •  
  •  
  •  
  •  
function widget_archive($title){  global $CACHE;   $record_cache = $CACHE->readCache('record');  ……}

十三、自定义组件模块

  •  
  •  
  •  
function widget_custom_text($title, $content){  ……}

十四、链接模块

function widget_link($title){  global $CACHE;   $link_cache = $CACHE->readCache('link');  ……}

十五、评论列表示例

function blog_comments($comments){    extract($comments);    if($commentStacks): ?>  a name="comments">a>  p class="comment-header">b>b>p>   endif; ?>    $isGravatar = Option::get('isgravatar');  foreach($commentStacks as $cid):    $comment = $comments[$cid];  $comment['poster'] = $comment['url'] ? ''url'].'" target="_blank">'.$comment['poster'].'' : $comment['poster'];  ?>  div class="media-item comment" id="comment-">    a name="">a>     if($isGravatar == 'y'): ?>div class="avatar media-item-left">img class="img-xs" src="" />div> endif; ?>    div class="media-text comment-info">    a href="javascript:;"> echo $comment['poster']; ?>a>    mdall class="comment-time"> echo $comment['date']; ?>mdall>    a class="comment-reply" href="#comment-" onclick="commentReply(,this)">回复a>    div class="comment-content"> echo $comment['content']; ?>div>    div>  div>   blog_comments_children($comments, $comment['children']); ?>   endforeach; ?>    div id="pagenavi">       echo $commentPageUrl;?>    div> }?>

十六、子评论列表示例

function blog_comments_children($comments, $children){  $isGravatar = Option::get('isgravatar');  foreach($children as $child):  $comment = $comments[$child];  $comment['poster'] = $comment['url'] ? ''url'].'" target="_blank">'.$comment['poster'].'' : $comment['poster'];  ?>  div class="media-item comment comment-children" id="comment-">    a name="">a>     if($isGravatar == 'y'): ?>div class="avatar media-item-left">img class="img-xs" src="" />div> endif; ?>    div class="media-text comment-info">    a href="javascript:;"> echo $comment['poster']; ?>a>    mdall class="comment-time"> echo $comment['date']; ?>mdall>     if($comment['level'] 4): ?>a class="comment-reply" href="#comment-" onclick="commentReply(,this)">回复a> endif; ?>    div class="comment-content"> echo $comment['content']; ?>div>    div>  div>   blog_comments_children($comments, $comment['children']);?>   endforeach; ?> }?>

十七、评论输入表单示例

function blog_comments_post($logid,$ckname,$ckmail,$ckurl,$verifyCode,$allow_remark){  if($allow_remark == 'y'): ?>  div id="comment-place">  div class="comment-post" id="comment-post">    div class="cancel-reply" id="cancel-reply" style="display:none">a href="javascript:void(0);" onclick="cancelReply()" class="layui-btn layui-btn-primary">取消回复a>div>    p class="comment-header">b>b>a name="respond">a>p>    form class="layui-form" method="post" name="commentform" action="index.php?action=addcom" id="commentform">      input type="hidden" name="gid" value="" />       if(ROLE == ROLE_VISITOR): ?>      p>        input class="layui-input" type="text" name="comname" maxlength="49" value="" size="22" tabindex="1" placeholder="昵称">      p>      p>        input class="layui-input" type="text" name="commail"  maxlength="128"  value="" size="22" tabindex="2" placeholder="邮件地址 (选填)">      p>      p>        input class="layui-input" type="text" name="comurl" maxlength="128"  value="" size="22" tabindex="3" placeholder="个人主页 (选填)">      p>       endif; ?>      p>textarea class="layui-textarea" name="comment" id="comment" rows="10" tabindex="4" required="required" placeholder="评论内容">textarea>p>      p> echo $verifyCode; ?> input class="layui-btn layui-btn-primary" type="submit" id="comment_submit" value="发表评论" tabindex="6" />p>      input type="hidden" name="pid" id="comment-pid" value="0" size="22" tabindex="1"/>    form>  div>  div>   endif; ?> }?>

前台模板部分挂载点一览

doAction('index_footer'); //页脚底部挂载点doAction('index_loglist_top'); //首页日志列表顶部挂载点doAction('log_related', $logData); //相关日志挂载点doAction('diff_side'); //侧边栏挂载点

结束语

OK,这篇简短的入门讲解结束了,希望你看着不累,同时能对Emlog的模板系统了解一二,这样文章的目的也就达到了,针对当前文章的不明白的地方,欢迎到论坛提出问题。谢谢

 

 

© 版权声明