书接上文《使用memos搭建独立微博,self-host三件套齐全了

本文介绍:

1、Memos应用中添加Artalk评论
2、Typecho集成单页Memos并添加Artalk评论

Memos应用中添加Artalk评论

首先,你需要自建Artalk评论服务,可参考官网,此处不详细介绍了。

然后,在Memos的设置-系统中添加自定义样式和自定义脚本。

1、在自定义脚本中追加如下代码

将代码中Artalk相关的参数配置,替换为自己的。

// artalk comments
// css
document.head.innerHTML += '<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/artalk/2.5.4/Artalk.css" type="text/css"/>';
// js
function addArtalkJS() { 
    var memosArtalk = document.createElement("script");
    memosArtalk.src = `https://cdn.bootcdn.net/ajax/libs/artalk/2.5.4/Artalk.js`;
    var artakPos = document.getElementsByTagName("script")[0];
    artakPos.parentNode.insertBefore(memosArtalk, artakPos);
};
// div
function startArtalk() {
    start = setInterval(function(){
        var artalkDom = document.getElementById('Comments') || '';
        var memoAt = document.querySelector('.memo-wrapper') || ''; // 0.12.x的版本请将.memo-wrapper替换为.memo-container
        var memoLoading = document.querySelector('.action-button-container') || '';
        var memoLoadingA = document.querySelector('.action-button-container a') || '';
        if(window.location.href.replace(/^.*\/(m)\/.*$/,'$1') == "m" && memoLoadingA){
        memoLoading.innerHTML = "评论加载中……"
        }
        if(window.location.href.replace(/^.*\/(m)\/.*$/,'$1') == "m" && !artalkDom){
            addArtalkJS()
            if(memoAt){
                clearInterval(start)
                memoAt.insertAdjacentHTML('afterend', '<div id="Comments"></div>');
                setTimeout(function() {
                    Artalk.init({
                        el: '#Comments',
                        pageKey: location.pathname,
                        pageTitle: document.title,
                        server: 'https://artalk.skyue.com',
                        site: '拾月微博',
                        darkMode: 'auto'
                    });
                    Artalk.on('list-loaded', function() {
                        // console.log('评论加载完成');
                        memoLoading.innerHTML = ''
                        startArtalk();
                    });
                }, 1000);
            }
        }
        //console.log(window.location.href);
    }, 1000)
}
startArtalk();

2、在自定义样式中追加如下代码

a.time-text:after { content: ' 评论 💬 '; }
.atk-main-editor { margin-top: 20px; }

最终效果如下:

Typecho集成单页Memos并添加评论

先来欣赏下集成后效果,如下图所示。主要特点在于:评论框默认折叠,点击评论后评论框在当前页展开,无需跳转,类似微博。(点击这里线上体验)

网上有很多Memos单页应用示例代码,比如我用过一段时间木老师开发的版本

我的博客是Typecho搭建的,有服务端,这次我直接在主题(我用的默认主题)文件夹新建了一个memos.php的模板文件,并在服务端直接获取Memos数据并渲染,代码如下:

<?php $this->need('header.php'); ?>
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
 * Memos模板
 *
 * @package custom
 */
?>

<div class="col-mb-12 col-8" id="main" role="main">
<article class="post"><h2 class="post-title"></h2><article>
<?php
$url = 'https://memos.skyue.com/api/memo?creatorId=1&limit=300'; // 不限定内容类型
$ch = curl_init();  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查 SSL 加密算法是否存在
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 6);
$response = curl_exec($ch);  
if($error=curl_error($ch)){  
    echo '微博加载错误';
}  
curl_close($ch);
$array_data = json_decode($response,true)['data'];
for($i=1; $i<count($array_data); $i++)
{
    $obj = $array_data[$i];
    // 下面这个if判断,是只展示最近30天的Memos
    if(time() - $obj['createdTs'] < 2592000){
        $memo_id = $obj['id'];
        $content = $obj['content'];
        $create_time = date('Y-m-d H:i:s',$obj['createdTs']);
        $resources = $obj['resourceList'];

        $content_tag = preg_replace_callback('/#([^\s\n]+)(?=\s|\n|$)/', function ($matches) {
            return '<span class="memo_tag">#' . $matches[1] . '</span>';
        }, $content);
        $content_html = Typecho_Widget::widget('Widget_Abstract_Contents')->markdown($content_tag); // 使用Typecho自带的Markdown解析器解析Memos

        $body_html = sprintf('
            <div class="memo-top-wrapper">拾月 · %s</div>
            <div class="memo-content-wrapper">%s</div>', $create_time, $content_html); 

        if($resources){
            $image_html = '<div class="resource-wrapper"><div class="images-wrapper"><div class="w-full memo-resource">';
            for($j=0; $j<count($resources); $j++){
                $image_html = $image_html.sprintf('<img src="%s" decoding="async" loading="lazy">', $resources[$j]['externalLink']);
            }
            echo '<article class="memo-wrapper">'.$body_html.$image_html.'</div></div></div><a style="cursor:pointer" onclick="loadArtalk(\''.$memo_id.'\')"><span id="btn_memo_'.$memo_id.'">评论</span>(<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>)</a><div style="display: none;" id="memo_'.$memo_id.'"></div></article>';
        }else{
            echo '<article class="memo-wrapper">'.$body_html.'<a style="cursor:pointer" onclick="loadArtalk(\''.$memo_id.'\')"><span id="btn_memo_'.$memo_id.'">评论</span>(<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>)</a><div style="display: none;" id="memo_'.$memo_id.'"></div></article>';
        }  // echo的html代码中,onclick属性调用下面的加载Artalk评论框代码,需要传memo_id参数
    }
}
?> <!-- Memos数据处理结束 -->

<div class="memo-bottom">更多内容前往<a href="https://memos.skyue.com" target="_blank">微博主站</a></div>

</div>

<!-- artalk文件 -->
<link href="https://npm.elemecdn.com/artalk@2.5.4/dist/Artalk.css" rel="stylesheet">
<script src="https://npm.elemecdn.com/artalk@2.5.4/dist/Artalk.js"></script>

<!-- 下面这段JS,在页面上点击评论按钮时触发,支持展开评论和收起评论 -->
<script>
function loadArtalk(memo_id){
    const commentDiv = document.getElementById('memo_'+memo_id);
    const commentBtn = document.getElementById('btn_memo_'+memo_id);
    if(commentDiv.style.display==='none'){
        commentDiv.style.display='block';
        commentBtn.innerHTML = '收起评论';
        new Artalk({
            el: '#memo_' + memo_id,  // 绑定元素的 Selector
            pageKey: '/m/'+memo_id,  // 固定链接 (留空自动获取)
            pageTitle: '拾月微博',    // 页面标题 (留空自动获取)
            server: 'https://artalk.skyue.com',  // 后端地址
            site: '拾月微博',         // 在后端中创建的站点名
        });
    }
    else{
        commentDiv.style.display='none';
        commentBtn.innerHTML = '评论';
    }
}
</script>

<!-- 这段js,在未展开评论时,就展示评论数量 -->
<script>
Artalk.loadCountWidget({
  server:  'https://artalk.skyue.com',
  site:    '拾月微博',
  pvEl:    '#ArtalkPV',
  countEl: '#ArtalkCount',
});
</script>

<?php $this->need('footer.php'); ?>

上面这段代码实现两个功能:

  1. 通过api抓取Memos数据并直接在服务端渲染。
  2. 提供了两段javascript代码,一个实现展示评论数,一个实现评论框的展开和收起。

如果是Typecho博客程序,大概率能使用上述代码,只根据自己的情况修改Memos api地址以及loadArtalk中serversite两个参数。

关于点击「评论」按钮的功能,关键是下面三处:

  1. 模板中每条memo下面预留一个div容器,容器idmemo_{memo_id},渲染后类似<div id="memo_1"></div>。其作用是在对应的memo下方加载评论框。
  2. 为「评论」按钮添加onclick属性,调用loadArtalk函数,调用时带上memo_id参数。这段js执行时,会寻找上面提到的容器,加载评论框,并获取对应Memo的评论进行展示。展开状态再点击,又会收起。
  3. 「评论」按钮括号内的评论数,是<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>起的作用。

下面是在主题文件夹style.css中追加的样式:

/* memo专用css */

article.memo-wrapper {
    padding: 15px;
    border: 1px solid darkgray;
    margin: 20px 0px;
}

.memo-content-wrapper {
    line-height: 1.6;
    font-size: 17px;
    word-wrap: break-word;
}

.memo-resource img {
    width: auto;
    max-width: 100%;
}

span.memo_tag {
    color: cornflowerblue;
}

.memo-bottom {
    margin: 50px 0px;
    text-align: center;
}

.memo-top-wrapper {
    color: gray;
}

以上,就这么点东西,周六晚上肝到凌晨4点,还好有ChatGPT。

另外,有些不完美的地方,比如:

  1. 现在图片是纵向平铺的,没有做九宫格缩略图。
  2. 没有详情页,从评论通知邮件打开Memos,还是memos.skyue.com站点。

留坑,有空再解决这两个问题,尤其是第2个,非常想在www.skyue.com主站实现memos详情页,技术上肯定可行,只是现在还不会。

分类: 折腾 标签: Typecho, Memos, Artalk, 独立微博

🔔 Email RSS订阅本博客

已有 73 条评论

  1. 汲墨 汲墨

    老师您好,我跟您一样是使用了Typecho做的博客,将Memos添加到独立页面后,点击分类时无法跳转到对应的memos内容分类,实际页面跳转到了 https://www.lniaen.com/index.php/undefined/api/v1/memo?creatorId=1&tag=% E6%97% A5% E5% B8% B8&rowStatus=NORMAL&limit=50,而不是memos.lniaen.com,请问您有相同问题吗?

    1. 是说点击memo右上角的跳转吗?
      我感觉是你拼接的链接错了,我之前做的,没有这个问题。

  2. 详情页没什么难的吧! 我是直接获取memos数据,作为wordpress的评论存储到wordpress的评论数据库,然后通过wordpress的评论系统输出,并使用wordpress的评论系统进行互动。这个页面获取、提交并展示memos数据:http://manman.qian.lu:2080/laodao 这个页面调用本地评论数据列表展示:http://manman.qian.lu:2080/pinglun?action=memos

    1. 你这个方法好trick啊,把memos当发布客户端,数据过个桥,最终进到wordpress。不过,是个不错的思路。

  3. Dcrclub Dcrclub

    你现在这个站点是memos吗?🤝

    1. 现在这个是typecho建的博客。
      memos是 https://memos.skyue.com

  4. sharp sharp

    老哥,我装了最新的0.16版本的memos,上面的代码粘贴到后台后好像不行了,不显示评论框没法评论,是不是代码哪里要更新一下呀~

    1. 额,可能是,但我也不太会,我当时都是基于别的的代码改的。
      另:我已经取消memos的评论了,所以没再跟进。

      可以关注下老张的博客,他一直有跟进memos的评论功能: https://www.laozhang.org/

      1. sharp sharp

        好的蟹蟹~

  5. Jackkim Jackkim

    大佬请问,
    通过memos的自定义样式和脚本
    可否能够实现点赞功能?

    1. 肯定可以复用artalk的点赞功能,不过我没有深入研究了,我也不是专业的,瞎折腾,哈哈。

  6. 请教下默认不点击展开评论怎么可以获取评论数,目前是加了这参数,但没点击评论就无法显示评论数,点击就正常显示了~~
    也加了

    Artalk.loadCountWidget({ server: 'xxx', site: 'xxx', pvEl: '#ArtalkPV', countEl: '#ArtalkCount', });

    但是无效~~使用的是hugo

    1. 页面上对应展示评论数的HTML元素,有没有加上id和data-page-key属性。比如我的代码中是这样的:
      <span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>

      data-page-key属性指定该条memo的key值,用以获取对应memo的评论数。

      官方说明见:https://artalk.js.org/guide/frontend/config.html#%E5%8A%9F%E8%83%BD

      1. 加了,也是看了官方的这个文档。渲染出来的的页面也能正确的获取到memos 内容的链接/m/数字id,但不点击评论的时候就获取不到评论数。开始以为是/m/前面没加memos域名的原因,发现不是加了也没用。

        1. https://koobai.com/memos/
          在这个页面的评论icon边上,好像没看到显示评论数的元素。

        2. 你的页面URL是多少,我瞧瞧看,可以在Chrome的开发者工具上看下有没有相关的报错信息。

          1. 原先是在本地测试,现在同步上去了,空的时候麻烦帮忙看看,辛苦
            https://koobai.com/memos/

            在控制台也没见报错~

            发现现在有时候打开页面可以显示评论,有时候不行,必须得点击评论按钮才会显示。包括点击页面下方的查看更多,加载出来的memos信息也不显示数字,必须得按评论按钮才行~

  7. 感谢大佬 请问 图片怎么做成九宫格呀 平铺 发长图 屏占比太大了😂

    1. 我不会改九宫格,可以等等看老莫讲的autophoto。
      我自己最后是用了折叠的方式: https://www.skyue.com/memos.html

      九宫格的方式,可以参考下老张这篇 https://laozhang.org/archives/3421.html 他复用了空白的代码,支持九宫格。

    2. 老莫 老莫

      用插件可以解决这个问题,我今天刚好找到一个

      1. 您好 方便告知 是什么插件吗 谢谢

        1. 老莫 老莫

          AutoPhotos图片自动排版.😂

          1. 好的 谢谢 我有空看看 方便给个链接 看看效果图吗 😂

    3. 我也不会,所以就退而求其次,平铺了,哈哈。

  8. 以前看这个项目,就觉得和flomo特别像,本来打算自己也搭建一个,以后在上面发短文,但奈何不懂前端,不知道怎么集成到模板,于是用了最朴素的办法,在一个文档里,用时间标题做分割,每段一个动态,可惜没有传统的评论和点赞,收不到反馈,只能看到整体页面。

    记得以前用飞书文档干这个事情的时候,最可怕的是可以实时看到反馈,给自己的刺激太强了,文档上面直接显示有那些人,现在正在看文档,然后他们可以针对,每一句话留评论。

    说起来,有没有一种可能,通过给typecho的模板里加一段JS代码,让它也在页面上显示,目前有那些人现在正在看博客,感觉这个对网站作者的刺激性,还是很大的。😎

    1. 技术上是可行的。
      但独立博客的流量一般都不大,同一时间浏览的人很少。并且这个需要用户登录,成本比较高。

      1. 确实,http请求是单向一次性的,检测访客有没有关掉网页,哪怕不做用户账号系统,对网页也有性能压力。

        另外,站长这个回复评论的速度很快啊,我比较好奇站长是怎么接收邮件提醒的?我之前自己的博客别人评论后,手机邮箱没提醒,当我看到后台评论,都几个月之后了。😂

        还有一点,我设置了gravatar头像了,为啥没显示?是因为缓存问题?😂

        1. 哈哈,刚好在电脑边上😂,不过手机有收到邮件提醒,我的评论邮件提醒都还挺及时的。你是不是配置不对。
          头像不知道怎么回事,有可能是缓存吧。但这个页面其它留言头像都是正常的。

          1. 插件提醒那个我已经配好了,可以很快的收到邮件,只是我以前没有看邮件的习惯,所以,我比较好奇站长用的邮件客户端是什么?网页版的收件箱?还是电脑手机自带的邮件客户端?😂

            我以前每次看邮箱,都得打开网页,登陆邮箱的网址,进去才能看到邮件,所以,想问问有什么好的邮件客户端,或者接受邮件提醒的便利方法。🙏

            头像估计是CDN缓存问题了,过几天可能会好。

            1. 我用的是Gmail,手机上用的官方App,电脑上是Chrome的gmail提醒插件,都是实时提醒。
              没有提醒,我通常每天也会查看一次邮件,个人使用邮件频率挺高的。

              1. 好的,了解了,谢谢🙏

  9. 感谢大佬分享,先收藏起来。

  10. 我直接用typecho原生做了个memos。mrju.cn/talk
    memos docker玩球不来,憋了800多行js给memos做出来了。支持tag标签,还有浏览器插件发布,以及后台登陆后直接在talk页面直接修改和删除某条哔哔。😂

    1. 你这个太强了,有没有开源?想研究一下。

      1. 右键查看源码。😂全是js。你去看看。

添加新评论