卖坚果的怪叔叔 卖坚果的怪叔叔
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
首页 › 技术 › 在博客中加上memos记录展示。

在博客中加上memos记录展示。

坚果大叔
2024-12-25 23:41:27技术阅读 8,093

什么是 memos?

memos 是「一个具有知识管理和社交网络的开源、自我托管的备忘录中心」。这是一个类似私人微博的产品,支持标签、过滤、搜索、多账户,可以自用也可以和朋友一起使用,用来碎片化的记录信息,就像 flomo 一样。除了以上它还可以是一个免费的自托管知识库。

TA 能做什么?

你可以部署在自己的服务器,当作私人的微博、朋友圈、记录载体、知识库、笔记等。他可以支持 markdown 输入,也可以添加标签、附件📎等多种形式。

如何部署?

可以直接使用 docker 进行安装。

docker run -d --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos neosmemo/memos:latest

或者像我一样在宝塔面板中选择 docker- 应用-memos 直接进行安装。安装完成后再网站中新增一个 memos 网址 并设置反向代理到 docker 部署的 memos 服务的应用端口地址上。

在博客中加上memos记录展示。-卖坚果的怪叔叔

更多安装教程可以直接搜索 memos 安装教程。

在个人博客和小程序中添加 memos 信息展示页面

有的时候想随时记录下当前的一个心情、状态、或者要做的事情,那么对于博客来说可能有点不合适,因为对于rss 来说可能有太多不是正式的内容。所以在搭建 memos 后,发现TA有对外的 api。所以就想着把 memos 的状态更新到自己的博客上面。效果如下

web端博客

在博客中加上memos记录展示。-卖坚果的怪叔叔

博客小程序中

在博客中加上memos记录展示。-卖坚果的怪叔叔

实现方式

在小程序中,实现很简单只需要调取 memos 的 memos 接口,默认会返回当前所有的记录,在小程序中渲染即可。请求的时候需要带上 token 并且做好懒加载和分页即可。

  fetchMemos: function (pageToken = '', limit = 20) {
    const self = this;
    wx.request({
      url: 'https://demo.memos.cn/api/v1/memos?pageToken=${pageToken}&pageSize=${limit}&creatorId=1',
      method: 'GET',
      header: {
        'Authorization': 'Bearer ' + 'token',
        'Content-Type': 'application/json',
      },
      success: (res) => {
        if (res.statusCode === 200) {
          const newMemos = res.data.memos;
          const pageToken = res.data.nextPageToken;
          const mdata = this.data.memosData.concat(newMemos);
          mdata.forEach((item) => {
            item.newcreateTime = self.formatTimeAgo(item.createTime)
          })
          self.setData({
            memosData: mdata,
            pageToken: pageToken,
          });
        }
      },
    });
  },

在个人博客上如何实现呢?因为博客使用的 WordPress ,所以你需要在你的主题目录中新建一个单页模板文件,用来显示 memos 信息。

首先在你的博客安装目录中的主题文件目录下的 pages 目录中新建一个单页模板。同时设置信息如下:

在博客中加上memos记录展示。-卖坚果的怪叔叔

然后在博客后台新建页面,选择页面模板为刚刚设置的memos pages,然后将该页面添加到你的菜单中。

接下来在模板页面添加相关逻辑代码。

html 部分

碎碎念

加载中...
没有更多数据了

JavaScript 部分

    let isLoading = false;
    let hasMoreData = true;
    function loadMemos(pageToken = '') {
        if (isLoading || !hasMoreData) return;
        isLoading = true; document.getElementById('loading').style.display = 'block';
        fetch('', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: 'action=load_memos&pageToken=${pageToken}',
        })
        .then(response => response.json())
        .then(data => {
            isLoading = false; document.getElementById('loading').style.display = 'none';
            if (data && data.memos && Array.isArray(data.memos) && data.memos.length > 0) {
                const memosContainer = document.getElementById('memos-container');
                data.memos.forEach(memo => {
                    const existingMemo = Array.from(memosContainer.children).find(child => child.dataset.id === memo.id);
                    if (!existingMemo) {
                        const memoElement = document.createElement('div');
                        memoElement.className ='memo-item'; 
                        memoElement.dataset.id = memo.id;
                        let tagsHtml = '';
                        if (memo.property && memo.property.tags && memo.property.tags.length > 0) {
                            tagsHtml = '
${memo.property.tags.map(tag =>
#${tag}
).join('')}
'; } memoElement.innerHTML = `
                                 
坚果大叔
${memo.formattedTime}
${memo.content}
${tagsHtml} `;                       memosContainer.appendChild(memoElement); } }); // pageToken = data.nextPageToken; localStorage.setItem('nextPageToken', data.nextPageToken); if (!data.nextPageToken) { hasMoreData = false; document.getElementById('no-more-data').style.display = 'block'; } } else { hasMoreData = false; document.getElementById('no-more-data').style.display = 'block'; } }) .catch(error => { console.error('加载数据失败:', error); isLoading = false; document.getElementById('loading').style.display = 'none'; }); } window.addEventListener('scroll', function () { if (isLoading || !hasMoreData) return; const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; if (scrollTop + clientHeight >= scrollHeight - 140) { let pageToken = localStorage.getItem('nextPageToken') || '' loadMemos(pageToken); } }); document.addEventListener('DOMContentLoaded', function () { loadMemos(); });

因为需要分页加载,所以你还需要在你的博客目录下的 functions.php 中添加接口请求的功能。

add_action('wp_ajax_load_memos', 'handle_load_memos');
add_action('wp_ajax_nopriv_load_memos', 'handle_load_memos');

function handle_load_memos() {
    $pageToken = sanitize_text_field($_POST['pageToken'] ?? '');
    $limit = 20;
    $response = wp_remote_get("https://demo.memos.cn/api/v1/memos?pageToken={$pageToken}&pageSize={$limit}&creatorId=1", array(
        'headers' => array(
            'Authorization' => 'Bearer token',
            'Content-Type' => 'application/json',
        ),
    ));
    if (is_array($response) && !is_wp_error($response)) {
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);

        if (!empty($data['memos'])) {
            foreach ($data['memos'] as &$memo) {
                $memo['formattedTime'] = formatTimeAgo($memo['createTime']);
            }
            wp_send_json(array(
                'memos' => $data['memos'],
                'nextPageToken' => $data['nextPageToken'] ?? '',
            ));
        }
    }
    wp_send_json(array(
        'memos' => [],
        'nextPageToken' => '',
    ));

    wp_die(); // 必须调用 wp_die() 结束请求
}

将上面文件都保存完成后,就可以在你的博客成功显示 memos的内容了。

但是因为安装版本的 memos 的问题,api 返回的数据中只有文本信息,上传的多媒体内容并没有返回,这个问题还没有解决,还在查看 api 文档。后续一并更新解决。

赞赏 赞(3)
最近半个月
上一篇
我的2024!开了好头,但结尾好像有点不太好~
下一篇
在小程序中查看

这是个😊,挣点服务器费用😜

评论已关闭

热门文章
四月底
还未见面的小狗,去天堂了。
CSS实现网格背景!
感受了一波余震~
使用encodeURI出现URI malformed报错?
Css Filter
专题标签
agent (1) CSS (15) dom (1) Es6入门系列 (14) Git (3) html (1) iview (1) JavaScript (9) js (4) Lif (1) Node (4) pyecharts (1) Python (10) ref (1) scriptable (1) Skill (1) vsCode (1) vue (4) wordpress (2) 三月 (1) 上海 (1) 假期 (1) 其他分享 (3) 前端两三问 (15) 古镇 (1) 外滩 (1) 对象 (1) 小程序 (5) 年度总结 (6) 年终总结 (1) 微信机器人 (4) 打字机 (1) 技术 (1) 日常问题 (8) 日常问题记录 (1) 春天 (2) 服务器 (2) 海族馆 (1) 生活 (8) 网上国网 (1) 记录 (3) 通勤 (1) 重学JavaScript (11) 面试题 (10) 🌸 (1)
什么是Agent?
2026-08-15 23:49:12
217 0 1
什么是 Skill?
2026-08-12 21:32:42
244 1 0
失业在家,我给小朋友做了一个练字小程序!
2026-08-07 16:21:52
457 8 1
上线8年,15万用户的小程序,一共赚了多少钱?
2026-05-30 18:01:24
4,583 4 0
3
  • 3
博主

一位佛系的前端开发者,略通摄影,乐于尝试新事物,热衷于美食。

友链
故事胶片
公众号
坚果大叔 执行上下文 卖坚果的怪叔叔 Dacking
Copyright © 2017-2026 卖坚果的怪叔叔

开往-友链接力

萌ICP备20230818号

苏ICP备18048410号-3
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
# CSS # # JavaScript # # vue # # 微信 # # 生活 #
坚果大叔
345
文章
170
评论
431
喜欢