什么是 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 信息展示页面
有的时候想随时记录下当前的一个心情、状态、或者要做的事情,那么对于博客来说可能有点不合适,因为对于rss 来说可能有太多不是正式的内容。所以在搭建 memos 后,发现TA有对外的 api。所以就想着把 memos 的状态更新到自己的博客上面。效果如下
web端博客
博客小程序中
实现方式
在小程序中,实现很简单只需要调取 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 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 = <div class="memos-tags">${memo.property.tags.map(tag =>
).join('')}</div>
;
}
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 文档。后续一并更新解决。