织梦CMS如何让已阅读文章显示已阅读?

99ANYc3cd6
预计阅读时长 29 分钟
位置: 首页 织梦建站 正文

这个功能的核心在于记录判断,下面我将为您提供两种主流的实现方案:

织梦cms阅读过的文章显示已阅读
(图片来源网络,侵删)
  1. 基于Cookie的方案:简单易行,无需修改数据库,但用户清除Cookie后失效,且多设备间不互通。
  2. 基于数据库的方案:更可靠,用户登录后状态持久化,但需要修改数据库结构和编写更复杂的逻辑。

基于Cookie的实现(推荐新手)

这个方案的核心思想是:当用户阅读一篇文章时,就在他的浏览器里设置一个Cookie,记录下这篇文章的ID,下次再加载页面时,就去检查这个Cookie,如果文章ID在Cookie里,就显示“已读”标记。

步骤详解:

修改文章列表模板文件

你需要找到你网站的文章列表模板,通常是 /templets/default/list_*.htm 或者你自定义的列表模板。

{dede:list} 标签循环中,找到文章标题的链接 <a> 标签,在其附近添加判断逻辑。

织梦cms阅读过的文章显示已阅读
(图片来源网络,侵删)
{dede:list}
    <li>
        <!-- 原有的文章标题链接 -->
        <a href="[field:arcurl/]">[field:title/]</a>
        <!-- ====== 在这里添加以下代码 ====== -->
        <span class="read-status">
            {dede:php}
                // 获取当前文章ID
                $aid = $GLOBALS['arcid'];
                // 从Cookie中获取已读文章ID列表(假设Cookie名为 'dede_read_articles')
                $read_articles = isset($_COOKIE['dede_read_articles']) ? $_COOKIE['dede_read_articles'] : '';
                // 将Cookie字符串转换成数组
                $read_ids = $read_articles ? explode(',', $read_articles) : array();
                // 判断当前文章ID是否在已读数组中
                if (in_array($aid, $read_ids)) {
                    // 如果已读,显示“已读”标记
                    echo '<span class="read-tag">已读</span>';
                }
            {/dede:php}
        </span>
        <!-- ================================= -->
        <!-- 其他信息,如时间、点击等 -->
        <span class="info">[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:list}

修改文章内容页模板文件

当用户在文章内容页时,也需要记录他刚刚阅读了这篇文章,所以要在文章内容页模板(通常是 /templets/default/article_article.htm)的底部,添加设置Cookie的代码。

... 文章内容 ...
<!-- 在页面底部,</body> 标签之前添加以下代码 -->
<script>
    // 获取当前文章ID
    var articleId = "{dede:field.id/}";
    // 获取或创建已读文章ID的Cookie
    var readArticles = getCookie('dede_read_articles');
    // 如果Cookie不存在,则初始化为一个空字符串
    if (!readArticles) {
        readArticles = '';
    }
    // 检查当前文章ID是否已在Cookie中
    if (readArticles.indexOf(articleId) === -1) {
        // 如果不在,则将当前文章ID添加到Cookie字符串中
        readArticles += (readArticles ? ',' : '') + articleId;
        // 设置Cookie,有效期设为30天
        setCookie('dede_read_articles', readArticles, 30);
    }
    // 设置Cookie的函数
    function setCookie(cname, cvalue, exdays) {
        var d = new Date();
        d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        var expires = "expires=" + d.toUTCString();
        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
    }
    // 获取Cookie的函数(如果需要的话,但上面代码可以直接用document.cookie)
    function getCookie(cname) {
        var name = cname + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var ca = decodedCookie.split(';');
        for(var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return "";
    }
</script>
</body>
</html>

添加CSS样式(可选)

为了让“已读”标记更美观,你可以在模板的CSS文件或<style>标签中添加一些样式。

<!-- 在你的CSS文件或模板的 <head> 标签内添加 -->
<style>
    .read-status {
        margin-left: 10px;
        font-size: 12px;
        color: #999;
    }
    .read-tag {
        color: #ccc;
        text-decoration: line-through; /* 可以加个删除线效果 */
    }
    /* 或者用一个图标代替文字 */
    .read-tag::before {
        content: "👁"; /* 眼睛图标 */
        margin-right: 3px;
    }
</style>

基于数据库的实现(更专业)

这个方案要求用户登录,已读状态会保存在数据库的用户表中,更稳定。

步骤详解:

修改数据库

dede_member 表(或其他会员表)中增加一个字段来存储已读文章ID。

ALTER TABLE `dede_member` ADD COLUMN `readarticleids` TEXT NOT NULL DEFAULT '';
  • readarticleids 字段类型为 TEXT,因为ID可能会很长。
  • 默认值为空字符串 。

修改文章列表模板

逻辑和方案一类似,但数据来源变成了数据库。

{dede:list}
    <li>
        <a href="[field:arcurl/]">[field:title/]</a>
        <!-- ====== 在这里添加以下代码 ====== -->
        <span class="read-status">
            {dede:php}
                global $dsql;
                $aid = $GLOBALS['arcid'];
                // 获取当前登录用户的信息
                $uid = isset($cfg_ml->M_ID) ? $cfg_ml->M_ID : 0;
                if ($uid > 0) {
                    // 查询用户的已读文章ID列表
                    $row = $dsql->GetOne("SELECT `readarticleids` FROM `dede_member` WHERE `mid` = '$uid'");
                    if ($row) {
                        $read_ids = $row['readarticleids'] ? explode(',', $row['readarticleids']) : array();
                        if (in_array($aid, $read_ids)) {
                            echo '<span class="read-tag">已读</span>';
                        }
                    }
                }
            {/dede:php}
        </span>
        <!-- ================================= -->
        <span class="info">[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:list}

修改文章内容页模板

当用户阅读文章时,更新其 readarticleids 字段。

... 文章内容 ...
<!-- 在页面底部,</body> 标签之前添加以下代码 -->
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // 获取当前文章ID
        var articleId = "{dede:field.id/}";
        // 获取当前登录用户ID
        var userId = <?php echo isset($cfg_ml->M_ID) ? $cfg_ml->M_ID : 0; ?>;
        if (userId > 0) {
            // 发送AJAX请求到后端更新数据库
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/plus/read_record.php', true); // 我们需要创建这个文件
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send('aid=' + articleId + '&uid=' + userId);
        }
    });
</script>
</body>
</html>

创建处理记录的PHP文件

在网站根目录的 /plus/ 文件夹下,创建一个名为 read_record.php 的文件,内容如下:

<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
require_once(DEDEINC."/memberlogin.class.php");
// 只接受POST请求
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
    exit('Error: Request method not allowed.');
}
// 获取参数
$aid = isset($_POST['aid']) ? intval($_POST['aid']) : 0;
$uid = isset($_POST['uid']) ? intval($_POST['uid']) : 0;
if ($aid <= 0 || $uid <= 0) {
    exit('Error: Invalid parameters.');
}
// 判断用户是否登录
if ($cfg_ml->M_ID != $uid) {
    exit('Error: User not logged in or ID mismatch.');
}
// 获取用户的已读文章ID列表
$read_ids = isset($cfg_ml->M_Infos['readarticleids']) ? $cfg_ml->M_Infos['readarticleids'] : '';
$read_ids_array = $read_ids ? explode(',', $read_ids) : array();
// 如果当前文章ID不在列表中,则添加
if (!in_array($aid, $read_ids_array)) {
    $read_ids_array[] = $aid;
    // 将数组重新组合成字符串
    $new_read_ids = implode(',', $read_ids_array);
    // 更新数据库
    $sql = "UPDATE `dede_member` SET `readarticleids` = '$new_read_ids' WHERE `mid` = '$uid'";
    $dsql->ExecuteNoneQuery($sql);
}
echo 'Record updated successfully.';
?>

总结与建议

特性 方案一 (Cookie) 方案二 (数据库)
实现难度 简单 较复杂
用户体验 非登录用户也可用,但多设备状态不互通 需登录,状态永久保存,体验一致
数据可靠性 低,用户清除Cookie即失效 ,数据存储在服务器
适用场景 普通资讯类、博客类网站 需要用户登录的门户、社区、学习平台

对于大多数网站,方案一(Cookie)已经足够好用且易于实现,如果你的网站有严格的会员体系和用户数据追踪需求,那么方案二(数据库)是更可靠的选择。

希望这个详细的教程能帮助到你!

-- 展开阅读全文 --
头像
C语言如何实现KNN算法?
« 上一篇 2025-12-11
织梦CMS编辑器如何解析自定义字段?
下一篇 » 2025-12-11

相关文章

取消
微信二维码
支付宝二维码

目录[+]