Thêm bình luận Artalk vào ứng dụng Memos 2 - tải game bài đổi thưởng tặng vốn
Tiếp nối bài viết trước "Sử dụng Memos để xây dựng mạng xã hội độc lập, bộ ba self-host đã hoàn chỉnh." Bài viết này sẽ giới thiệu:
- Thêm bình luận Artalk vào ứng dụng Memos
- Tích hợp trang đơn Memos vào Typecho và thêm bình luận Artalk
Thêm bình luận Artalk vào ứng dụng Memos
Trước tiên, tải game bài đổi thưởng tặng vốn bạn cần tự thiết lập dịch vụ bình luận Artalk, có thể tham khảo từ trang chủ, ở đây sẽ không đi sâu giải thích chi ca cuoc the thao tiết.
Sau đó, trong phần "Cài đặt - Hệ thống" của Memos, thêm kiểu dáng tùy chỉnh và kịch bản tùy chỉnh.
- Thêm đoạn mã sau vào kịch bản tùy chỉnh Thay thế các thông số liên quan đến Artalk trong mã bằng thông số của riêng bạn.
1// artalk comments
2// css
3document.head.innerHTML += '<link rel="stylesheet" href=" type="text/css"/>';
4// js
5function addArtalkJS() {
6 var memosArtalk = document.createElement("script");
7 memosArtalk.src = `
8 var artakPos = document.getElementsByTagName("script")[0];
9 artakPos.parentNode.insertBefore(memosArtalk, artakPos);
10};
11// div
12function startArtalk() {
13 start = setInterval(function(){
14 var artalkDom = document.getElementById('Comments') || '';
15 var memoAt = document.querySelector('.memo-wrapper') || ''; // phiên bản 0.12.x hãy thay .memo-wrapper bằng .memo-container
16 var memoLoading = document.querySelector('.action-button-container') || '';
17 var memoLoadingA = document.querySelector('.action-button-container a') || '';
18 if(window.location.href.replace(/^.*\/(m)\/.*$/,'$1') == "m" && memoLoadingA){
19 memoLoading.innerHTML = "Đang tải bình luận..."
20 }
21 if(window.location.href.replace(/^.*\/(m)\/.*$/,'$1') == "m" && !artalkDom){
22 addArtalkJS()
23 if(memoAt){
24 clearInterval(start)
25 memoAt.insertAdjacentHTML('afterend', '<div id="Comments"></div>');
26 setTimeout(function() {
27 Artalk.init({
28 el: '#Comments',
29 pageKey: location.pathname,
30 pageTitle: document.title,
31 server: '
32 site: 'Weibo Thập Nguyệt',
33 darkMode: 'auto'
34 });
35 Artalk.on('list-loaded', function() {
36 // console.log('Bình luận đã được tải xong');
37 memoLoading.innerHTML = ''
38 startArtalk();
39 });
40 }, 1000);
41 }
42 }
43 //console.log(window.location.href);
44 }, 1000)
45}
46startArtalk();
- Thêm đoạn mã sau vào kiểu dáng tùy chỉnh
1a.time-text:after { content: ' Bình luận 💬 '; }
2.atk-main-editor { margin-top: 20px; }
Kết quả cuối cùng như sau:
Tích hợp trang đơn Memos vào Typecho và thêm bình luận
Dưới đây là kết quả sau khi tích hợp. Điểm nổi bật là: Khung bình luận mặc định được gập lại, khi nhấp vào bình luận thì khung bình luận sẽ mở ra trên cùng trang hiện tại mà không cần chuyển hướng, tương tự như Weibo
Trên mạng có rất nhiều ví dụ về ứng dụng trang đơn Memos, ví dụ như phiên bản do thầy Mộc phát triển mà tôi đã sử dụng trong một thời gian.
Blog của tôi được xây dựng bằng Typecho, có máy chủ phía sau, lần này tôi trực tiếp tạo một tệp mẫu memos.php
trong thư mục chủ đề (tôi đang sử dụng chủ đề mặc định), và lấy dữ liệu Memos từ máy chủ phía sau để hiển thị, mã nguồn như sau:
1<?php $this->need('header.php'); ?>
2<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
3/*
4
5 */
6?>
7<div class="col-mb-12 col-8" id="main" role="main">
8<article class="post"><h2 class="post-title"></h2><article>
9<?php
10$url = ' // Không giới hạn loại nội dung
11$ch = curl_init();
12curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Bỏ qua kiểm tra chứng chỉ
13curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // Kiểm tra thuật toán mã hóa SSL từ chứng chỉ
14curl_setopt($ch, CURLOPT_URL, $url);
15curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
16curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
17curl_setopt($ch, CURLOPT_TIMEOUT, 6);
18$response = curl_exec($ch);
19if($error=curl_error($ch)){
20 echo 'Lỗi tải weibo';
21}
22curl_close($ch);
23$array_data = json_decode($response,true)['data'];
24for($i=1; $i<count($array_data); $i++)
25{
26 $obj = $array_data[$i];
27 // Điều kiện nếu này chỉ hiển thị Memos trong 30 ngày gần nhất
28 if(time() - $obj['createdTs'] < 2592000){
29 $memo_id = $obj['id'];
30 $content = $obj['content'];
31 $create_time = date('Y-m-d H:i:s',$obj['createdTs']);
32 $resources = $obj['resourceList'];
33 $content_tag = preg_replace_callback('/#([^\s\n]+)(?=\s|\n|$)/', function ($matches) {
34 return '<span class="memo_tag">#' . $matches[1] . '</span>';
35 }, $content);
36 $content_html = Typecho_Widget::widget('Widget_Abstract_Contents')->markdown($content_tag); // Sử dụng trình phân tích Markdown có sẵn của Typecho để xử lý Memos
37 $body_html = sprintf('
38 <div class="memo-top-wrapper">Thập Nguyệt · %s</div>
39 <div class="memo-content-wrapper">%s</div>', $create_time, $content_html);
40 if($resources){
41 $image_html = '<div class="resource-wrapper"><div class="images-wrapper"><div class="w-full memo-resource">';
42 for($j=0; $j<count($resources); $j++){
43 $image_html = $image_html.sprintf('<img src="%s" decoding="async" loading="lazy">', $resources[$j]['externalLink']);
44 }
45 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.'">Bình luận</span>(<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>)</a><div style="display: none;" id="memo_'.$memo_id.'"></div></article>';
46 }else{
47 echo '<article class="memo-wrapper">'.$body_html.'<a style="cursor:pointer" onclick="loadArtalk(\''.$memo_id.'\')"><span id="btn_memo_'.$memo_id.'">Bình luận</span>(<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>)</a><div style="display: none;" id="memo_'.$memo_id.'"></div></article>';
48 } // Mã html trong echo, thuộc tính onclick gọi hàm tải khung bình luận Artalk bên dưới, cần truyền tham số memo_id
49 }
50}
51?> <!-- Xử lý dữ liệu Memos kết thúc -->
52<div class="memo-bottom">Nội dung thêm xem tại trang chủ weibo</div>
53</div>
54<!-- Tập tin artalk -->
55<link href=" rel="stylesheet">
56<script src="
57<!-- Đoạn JS này sẽ kích hoạt khi nhấn nút bình luận trên trang, hỗ trợ mở rộng và thu gọn khung bình luận -->
58<script>
59function loadArtalk(memo_id){
60 const commentDiv = document.getElementById('memo_'+memo_id);
61 const commentBtn = document.getElementById('btn_memo_'+memo_id);
62 if(commentDiv.style.display==='none'){
63 commentDiv.style.display='block';
64 commentBtn.innerHTML = 'Thu gọn bình luận';
65 new Artalk({
66 el: '#memo_' + memo_id, // Selector phần tử gắn kết
67 pageKey: '/m/'+memo_id, // Cố định
68 pageTitle: 'Weibo Thập Nguyệt', // Tiêu đề trang (rời trống để lấy tự động)
69 server: ' // Địa chỉ backend
70 site: 'Weibo Thập Nguyệt', // Tên trang web được tạo trong backend
71 });
72 }
73 else{
74 commentDiv.style.display='none';
75 commentBtn.innerHTML = 'Bình luận';
76 }
77}
78</script>
79<!-- Đoạn js này hiển thị số lượng bình luận khi chưa mở rộng -->
80<script>
81Artalk.loadCountWidget({
82 server: '
83 site: 'Weibo Thập Nguyệt',
84 pvEl: '#ArtalkPV',
85 countEl: '#ArtalkCount',
86});
87</script>
88<?php $this->need('footer.php'); ?>
Mã nguồn trên thực hiện hai chức năng:
- Lấy dữ liệu Memos thông qua API và hiển thị trực tiếp trên máy chủ.
- Cung cấp hai đoạn mã javascript, một để hiển thị số lượng bình luận, một để mở rộng và thu gọn khung bình luận.
Nếu bạn sử dụng chương trình blog Typecho, có khả năng cao mã nguồn trên sẽ hoạt động, chỉ cần sửa địa chỉ API Memos cũng như hai tham số server
và site
trong hàm loadArtalk theo tình huống cụ thể của bạn.
Về chức năng nhấn nút "Bình luận", điều quan trọng là ba điểm sau:
- Mỗi memo trong mẫu đều có một container
div
vớiid
làmemo_{memo_id}
, sau khi render sẽ giống<div id="memo_1"></div>
. Vai trò của nó là tải khung bình luận ngay dưới memo tương ứng. - Thêm thuộc tính
onclick
cho nút "Bình luận", gọi hàmloadArtalk
, kèm theo tham sốmemo_id
. Khi đoạn mã js này chạy, nó sẽ tìm kiếm container đã nói ở trên, tải khung bình luận và lấy bình luận của Memo tương ứng để hiển thị. Nhấn lại khi đang mở rộng sẽ thu gọn. - Số lượng bình luận trong dấu ngoặc vuông của nút "Bình luận" được thực hiện bởi
<span id="ArtalkCount" data-page-key="/m/'.$memo_id.'"></span>
.
Dưới đây là kiểu dáng bổ sung trong file style.css của chủ đề:
1article.memo-wrapper {
2 padding: 15px;
3 border: 1px solid darkgray;
4 margin: 20px 0px;
5}
6.memo-content-wrapper {
7 line-height: 1.6;
8 font-size: 17px;
9 word-wrap: break-word;
10}
11.memo-resource img {
12 width: auto;
13 max-width: 100%;
14}
15span.memo_tag {
16 color: cornflowerblue;
17}
18.memo-bottom {
19 margin: 50px 0px;
20 text-align: center;
21}
22.memo-top-wrapper {
23 color: gray;
24}
Chỉ những thứ này thôi, làm suốt đêm đến 4 giờ sáng thứ Bảy, may nhờ có ChatGPT.
Ngoài ra, còn một số chỗ chưa hoàn hảo, ví dụ:
- Hiện tại hình ảnh được sắp xếp thẳng hàng dọc, chưa làm lưới hình 9 ô thu nhỏ.
- Chưa có trang chi tiết, mở thông báo bình luận vẫn dẫn đến trang memos.skyue.com.
Để lại chỗ trống, khi rảnh sẽ giải quyết hai vấn đề này, đặc biệt là vấn đề thứ hai, rất muốn thực hiện trang chi tiết Memos trên www.skyue.com, về mặt kỹ thuật chắc chắn có thể, chỉ là hiện tại chưa biết cách.