缩略图

Emlog主题开发入门:从零到上线,我的第一个主题开发记录

2026年04月01日 文章分类 会被自动插入 会被自动插入
本文最后更新于2026-04-01已经过去了1天请注意内容时效性
热度7 点赞 收藏0 评论0

想自己开发Emlog主题,但不知道从哪开始?我第一个主题做了2个月,踩了无数坑。

现在我把经验总结出来,按这个教程做,新手2周也能做出可用的主题。我的"简洁蓝"主题就是这么来的,现在有500多个站在用。


一、开发前准备:别急着写代码

先搞清楚Emlog主题的结构,不然写半天发现不对。

1.1 Emlog主题目录结构

your-theme/
├── images/          # 图片资源
├── style.css        # 样式文件(必须)
├── header.php       # 头部模板(必须)
├── footer.php       # 底部模板(必须)
├── index.php        # 首页模板(必须)
├── log_list.php     # 文章列表模板
├── log.php          # 文章页模板
├── page.php         # 页面模板
├── comments.php     # 评论模板
└── module.php       # 模块函数(可选)

必须文件: style.css、header.php、footer.php、index.php。少一个主题就不能用。

1.2 开发环境建议

我的配置:

  • 本地环境:PHPStudy(Windows)或 MAMP(Mac)
  • 代码编辑器:VS Code 或 PHPStorm
  • 浏览器:Chrome + 开发者工具
  • 测试站点:本地Emlog安装

别在线上站开发:改错了网站就挂了。一定要在本地或测试服务器开发。


二、style.css:主题的身份证

这个文件不只是样式,还包含主题信息。

2.1 基本信息(必须)

/*
Theme Name: 简洁蓝
Theme Url: https://www.xuewutheme.com/
Description: 简洁蓝色系Emlog主题,适合技术博客
Version: 1.0
Author: 大佬虾
Author Url: https://www.xuewutheme.com/
*/

注意:

  • Theme Name:主题名,后台显示用
  • Version:版本号,更新主题时需要
  • 这些信息Emlog后台会读取,必须写对

2.2 基础样式

先写重置样式,避免浏览器默认样式干扰:

/* 重置样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: "Microsoft YaHei", sans-serif;
    line-height: 1.6;
    color: #333;
    background: #f5f5f5;
}

a {
    color: #0066cc;
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

我的经验: 先写基础样式,确保各浏览器表现一致。


三、header.php:网站头部

头部包含LOGO、导航、搜索等。

3.1 基本结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?php echo $site_title; ?> - <?php echo $site_description; ?></title>
    <link rel="stylesheet" href="<?php echo TEMPLATE_URL; ?>style.css">
    <?php doAction('index_head'); ?>
</head>
<body>
    <header class="site-header">
        <div class="container">
            <!-- LOGO -->
            <div class="logo">
                <a href="<?php echo BLOG_URL; ?>">
                    <h1><?php echo $blogname; ?></h1>
                </a>
                <p class="description"><?php echo $bloginfo; ?></p>
            </div>

            <!-- 导航 -->
            <nav class="main-nav">
                <ul>
                    <li><a href="<?php echo BLOG_URL; ?>">首页</a></li>
                    <?php 
                    // 显示分类导航
                    $navs = getNavs();
                    foreach ($navs as $nav):
                    ?>
                    <li><a href="<?php echo $nav['url']; ?>"><?php echo $nav['naviname']; ?></a></li>
                    <?php endforeach; ?>
                </ul>
            </nav>

            <!-- 搜索框 -->
            <div class="search-box">
                <form action="<?php echo BLOG_URL; ?>index.php" method="get">
                    <input type="text" name="keyword" placeholder="搜索文章...">
                    <button type="submit">搜索</button>
                </form>
            </div>
        </div>
    </header>

    <main class="site-main">

关键变量:

  • $site_title:页面标题
  • $blogname:网站名称
  • $bloginfo:网站描述
  • BLOG_URL:网站根地址
  • TEMPLATE_URL:主题目录地址

四、footer.php:网站底部

底部包含版权信息、统计代码等。

4.1 基本结构

    </main> <!-- 接header.php的main标签 -->

    <footer class="site-footer">
        <div class="container">
            <div class="footer-content">
                <!-- 版权信息 -->
                <div class="copyright">
                    <p>&copy; <?php echo date('Y'); ?> <?php echo $blogname; ?>. All rights reserved.</p>
                    <p>Powered by <a href="https://www.emlog.net" target="_blank">Emlog</a></p>
                    <p>Theme by <a href="https://www.xuewutheme.com" target="_blank">大佬虾</a></p>
                </div>

                <!-- 友情链接 -->
                <div class="friend-links">
                    <h3>友情链接</h3>
                    <ul>
                        <?php
                        $links = getLinks();
                        foreach ($links as $link):
                        ?>
                        <li><a href="<?php echo $link['url']; ?>" target="_blank"><?php echo $link['sitename']; ?></a></li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            </div>
        </div>
    </footer>

    <?php doAction('index_footer'); ?>
</body>
</html>

注意: doAction('index_footer') 是钩子,插件可能在这里插入代码(比如统计代码)。


五、index.php:首页模板

首页显示文章列表。

5.1 基本结构

<?php if (!defined('EMLOG_ROOT')) {exit('error!');} ?>
<?php include View::getView('header'); ?>

<div class="content">
    <?php if (!empty($logs)): ?>
        <?php foreach ($logs as $value): ?>
        <article class="post">
            <h2 class="post-title">
                <a href="<?php echo $value['log_url']; ?>"><?php echo $value['log_title']; ?></a>
            </h2>

            <div class="post-meta">
                <span class="date"><?php echo gmdate('Y-m-d', $value['date']); ?></span>
                <span class="category">
                    <a href="<?php echo $value['sort_url']; ?>"><?php echo $value['sortname']; ?></a>
                </span>
                <span class="comments">
                    <a href="<?php echo $value['log_url']; ?>#comments">评论(<?php echo $value['comnum']; ?>)</a>
                </span>
                <span class="views">浏览(<?php echo $value['views']; ?>)</span>
            </div>

            <div class="post-excerpt">
                <?php echo $value['log_description']; ?>
            </div>

            <div class="post-more">
                <a href="<?php echo $value['log_url']; ?>">阅读全文</a>
            </div>
        </article>
        <?php endforeach; ?>
    <?php else: ?>
        <div class="no-content">
            <p>暂无文章</p>
        </div>
    <?php endif; ?>

    <!-- 分页 -->
    <div class="pagination">
        <?php echo $page_url; ?>
    </div>
</div>

<?php include View::getView('footer'); ?>

关键变量:

  • $logs:文章列表数组
  • $value['log_url']:文章链接
  • $value['log_title']:文章标题
  • $page_url:分页链接

六、log.php:文章页模板

显示单篇文章内容。

6.1 基本结构

<?php if (!defined('EMLOG_ROOT')) {exit('error!');} ?>
<?php include View::getView('header'); ?>

<div class="content">
    <article class="single-post">
        <h1 class="post-title"><?php echo $log_title; ?></h1>

        <div class="post-meta">
            <span class="date">发布时间:<?php echo gmdate('Y-m-d H:i', $date); ?></span>
            <span class="category">分类:<a href="<?php echo $sort_url; ?>"><?php echo $sortname; ?></a></span>
            <span class="views">浏览:<?php echo $views; ?></span>
            <?php if ($author): ?>
            <span class="author">作者:<?php echo $author; ?></span>
            <?php endif; ?>
        </div>

        <div class="post-content">
            <?php echo $log_content; ?>
        </div>

        <div class="post-tags">
            <strong>标签:</strong>
            <?php if (!empty($tag)): ?>
                <?php foreach ($tag as $t): ?>
                <a href="<?php echo Url::tag($t['tag']); ?>"><?php echo $t['tag']; ?></a>
                <?php endforeach; ?>
            <?php else: ?>
                暂无标签
            <?php endif; ?>
        </div>

        <!-- 上一篇下一篇 -->
        <div class="post-nav">
            <?php if ($neighborLog['prev']): ?>
            <div class="prev">
                <span>上一篇:</span>
                <a href="<?php echo $neighborLog['prev']['log_url']; ?>"><?php echo $neighborLog['prev']['log_title']; ?></a>
            </div>
            <?php endif; ?>

            <?php if ($neighborLog['next']): ?>
            <div class="next">
                <span>下一篇:</span>
                <a href="<?php echo $neighborLog['next']['log_url']; ?>"><?php echo $neighborLog['next']['log_title']; ?></a>
            </div>
            <?php endif; ?>
        </div>
    </article>

    <!-- 评论 -->
    <?php include View::getView('comments'); ?>
</div>

<?php include View::getView('footer'); ?>

注意: $log_content 是文章内容,Emlog已经处理了格式。


七、module.php:自定义函数

有些功能需要自定义函数,比如最新文章、热门标签。

7.1 示例:最新文章函数

<?php
// 最新文章
function getLatestPosts($num = 10) {
    $db = Database::getInstance();
    $sql = "SELECT * FROM " . DB_PREFIX . "blog 
            WHERE hide='n' AND type='blog' 
            ORDER BY date DESC 
            LIMIT $num";
    $result = $db->query($sql);

    $posts = [];
    while ($row = $db->fetch_array($result)) {
        $row['log_url'] = Url::log($row['gid']);
        $posts[] = $row;
    }

    return $posts;
}

// 在模板中使用
$latestPosts = getLatestPosts(5);
foreach ($latestPosts as $post) {
    echo '<li><a href="' . $post['log_url'] . '">' . $post['title'] . '</a></li>';
}
?>

7.2 示例:热门标签

// 热门标签
function getHotTags($num = 20) {
    $db = Database::getInstance();
    $sql = "SELECT tagname, COUNT(*) as count 
            FROM " . DB_PREFIX . "tag 
            GROUP BY tagname 
            ORDER BY count DESC 
            LIMIT $num";
    $result = $db->query($sql);

    $tags = [];
    while ($row = $db->fetch_array($result)) {
        $tags[] = [
            'name' => $row['tagname'],
            'count' => $row['count'],
            'url' => Url::tag(rawurlencode($row['tagname']))
        ];
    }

    return $tags;
}

八、响应式设计:适配手机

现在一半流量来自手机,必须做响应式。

8.1 媒体查询

/* 桌面端(默认) */
.container {
    width: 1200px;
    margin: 0 auto;
}

/* 平板 */
@media (max-width: 1024px) {
    .container {
        width: 90%;
    }
    .main-nav ul {
        flex-wrap: wrap;
    }
}

/* 手机 */
@media (max-width: 768px) {
    .container {
        width: 95%;
    }
    .main-nav {
        display: none; /* 改成汉堡菜单 */
    }
    .post-content img {
        max-width: 100%;
        height: auto;
    }
}

8.2 我的响应式策略

  1. 移动优先:先写手机样式,再写桌面
  2. 断点设置:768px(手机)、1024px(平板)、1200px(桌面)
  3. 图片优化:手机用小图,桌面用大图
  4. 触摸友好:按钮至少44×44像素

九、主题打包和安装

开发完要打包,让别人能用。

9.1 打包结构

简洁蓝主题.zip
└── simple-blue/      # 主题文件夹名
    ├── images/
    ├── style.css
    ├── header.php
    ├── footer.php
    ├── index.php
    ├── log.php
    ├── page.php
    ├── comments.php
    ├── module.php
    └── screenshot.png  # 主题截图(必须)

注意: 主题文件夹名要和style.css里的Theme Name对应。

9.2 安装测试

  1. 本地Emlog后台 → 主题 → 上传安装
  2. 启用主题
  3. 检查所有页面是否正常
  4. 测试响应式
  5. 检查PHP错误日志

我的测试清单:

  • [ ] 首页显示正常
  • [ ] 文章页显示正常
  • [ ] 分类页显示正常
  • [ ] 搜索功能正常
  • [ ] 评论功能正常
  • [ ] 手机端显示正常
  • [ ] 没有PHP错误

十、常见问题

Q:主题安装后显示空白?

A:可能原因:

  1. PHP语法错误(看错误日志)
  2. 缺少必须文件(style.css、header.php等)
  3. 文件编码不对(用UTF-8无BOM)

Q:自定义函数不生效?

A:检查:

  1. 函数名是否冲突
  2. 是否在module.php里
  3. 模板里是否调用了

Q:样式在手机端乱了?

A:可能:

  1. 没做响应式
  2. 图片太大
  3. 用了固定宽度

Q:怎么更新主题?

A:步骤:

  1. 修改style.css里的Version
  2. 用户后台会提示更新
  3. 上传新版本覆盖
  4. 清除浏览器缓存

十一、我的第一个主题开发记录

第1周: 学习Emlog模板结构,看官方文档 第2周: 写基础模板,各种报错 第3周: 调试,解决兼容性问题
第4周: 做响应式,适配手机 第5周: 测试,修复bug 第6周: 发布,收集反馈 第7-8周: 根据反馈优化

踩过的坑:

  1. 文件编码问题(BOM头导致空白)
  2. PHP版本兼容(有的函数老版本没有)
  3. 浏览器兼容(IE真是个坑)
  4. 性能问题(数据库查询太多)

建议: 第一个主题别追求完美,先做出来能用,再慢慢优化。


十二、学习资源

  1. 官方文档https://www.emlog.net/docs
  2. 主题开发教程:Emlog论坛有很多
  3. 参考主题:下载官方主题研究代码
  4. CSS学习:MDN Web Docs
  5. PHP学习:PHP官方手册

我的学习路径:

  1. 先看官方主题代码
  2. 改现有主题练手
  3. 自己从头写一个
  4. 发布收集反馈
  5. 持续优化

十三、最后建议

主题开发不难,难在坚持。我的建议:

  1. 从简单开始:先做单栏,再做复杂布局
  2. 多测试:不同浏览器、不同设备都测
  3. 代码规范:写好注释,方便
正文结束 阅读本文相关话题
相关阅读
评论框
正在回复
评论列表
暂无评论,快来抢沙发吧~
sitemap