title: [Technical Exploration of Xlog] Smoother User Experience 1 Feasibility Exploration
slug: play-xlog-01
tags:
- xlog
update_time: 2023/10/16 11:07:44
create_time: 2023/10/13 20:51:10
sha: 31389d4e74e912fe0c504a396ab7d4cc5a290510
I want to write a series of articles, exploring the best blog platform on Earth, xlog.app, from a technical perspective. I aim to achieve the following things (I'm starting to boast again, for new friends, this is my way of expressing myself, haha):
- Stick to my beloved text editor, obsidian, and still publish xlog blogs
- Access xlog and read other people's blogs and interact without opening a web page
- Synchronize xlog blogs and display my own content using my own domain and server
- github + xlog = multi-tenant cms
- Become a member of xlog
After the introduction, let's start exploring the feasibility from a technical perspective. In this article, we will discuss how to access xlog content through the official openapi.
Background
As the best blog platform on Earth, xlog has two small issues: accessing it from mainland China may be slightly slow, and after migrating all blogs to xlog, your own server will be idle.
Or simply put, can we publish articles on xlog and deploy our own version? Looking ahead, who says xlog.app is the only way to access xlog? Are we limiting the potential of xlog becoming the best headlessCMS on Earth?
So let's get started.
Technical Exploration
From the currently available information, xlog provides multiple ways to access xlog content, for example, to access your own data:
- You can access data through the
crossbell
SDK - You can access data through the http restful API
Next, we will access our data through these two methods, focusing on accessing publicly published articles.
Preparations
The prerequisite for the following content is that you need to be a user of xlog. If you don't have an account, go ahead and register.
Get the public address, visit https://xlog.app/dashboard, follow the instructions in the screenshot, click on it, and it will prompt "Copied". You can consider this as the unique ID of the current user on xlog. If you have multiple roles, the ID will be different.
Write it down in a notebook. Taking mine as an example, we will use it for subsequent access: 0xA0fb033D4849b13A16690EEbdd575Dd90bF29711
Next, we will use different methods to access the data.
Accessing Data through the SDK
You need to have a Node.js environment for this method. If you are not familiar with Node.js, please directly refer to the section "Accessing through the Official API" below.
The official SDK's Github address is https://github.com/Crossbell-Box/crossbell.js
Criticism: The official documentation is not very good. I will contribute to its modification later.
First, start the project.
mkdir xlog-api-demo
cd xlog-api-demo && pnpm init
pnpm i crossbell
# Prepare the ts environment
pnpm i typescript tsx -D
touch index.ts
Organize the following code in index.ts
.
import { createIndexer } from "crossbell";
const indexer = createIndexer();
const Address = process.env.USER_ADDRESS as `0x${string}`;
const getUserByAddress = async () => {
const res = await indexer.character.getMany(Address);
console.log(res);
};
getUserByAddress();
Execute the code. For specific execution, refer to the corresponding repository. The main purpose is to get character information based on the address. You can get metadata and characterId.
// const characterId = 53710;
const getNotesByCharacterId = async (characterId: number) => {
const res = await indexer.note.getMany({
characterId,
includeNestedNotes: false,
limit: 10,
});
console.log(res);
};
With these methods, you can read the user's data. Pagination can be implemented using total + cursor + limit, and the cursor is reflected in each request result.
To query specific details, you can use the following implementation.
const noteId = 16;
const characterId = 53710;
const getNoteById = async (noteId: number) => {
const res = await indexer.note.get(characterId, noteId);
// console.log(res);
console.log(res?.metadata?.content);
};
getNoteById(noteId);
Similar methods can be applied to display various types of data.
With these two methods, we can build a personal blog, including the basic information of the homepage, the update list of the list page, and the information display of the detail page.
Here are two details to note:
- Custom embeds, such as audio and video, need to be handled by yourself. This can be discussed later.
- Images and links are all handled using ipfs. Let's discuss this in detail.
ipfs Protocol
The ipfs protocol encompasses everything. Simply put, it is a hash or cid that corresponds to a network resource. I won't go into details here. For the web, ipfs is not the same as the http protocol. To display images, there needs to be a protocol conversion process, which involves the parsing of the api gateway.
At first, I searched the source code and found the gateway myself, but later I realized that it doesn't have to be so geeky. Visit https://crossbell-ipfs-utils.vercel.app/img/bafkreiarfgti3xpv2oznl7rzanfbzm7gvklvcwn5poqb53wlhi3n4cwp2a, this webpage loads images from different gateways, you can choose the one you like.
Note that for faster loading speed, if you consider sub-hosting, it is obviously best to handle resources yourself.
In addition, xlog has a dedicated utility library to handle this issue, which can be used as a programming solution. Just a reminder.
import { ipfsFetch } from "@crossbell/ipfs-fetch";
ipfsFetch(ipfsUrl)
.then((res) => {
console.log(1, res);
})
.catch((err) => {
console.log(3, err);
});
These are the details. You can refer to the api for more interactions.
Accessing through the Official API
The technical solution mentioned earlier relies on Node.js. If you are proficient in other languages or want something simpler, the official API provides a restful api for interaction, which has lower invasiveness.
Visit
https://indexer.crossbell.io/docs
and use the address mentioned in the SDK as the entry point:
- Access "Character" and use "Get characters of an address" to get the characterId
/v1/addresses/{address}/characters
- Access "Get a character by characterId" to get the user's basic information for the homepage
/v1/characters/{characterId}
- Access
/v1/characters/{characterId}/notes
to get the articles of the corresponding person - Access
/v1/notes/{characterId}/{noteId}
to get the details of the corresponding article
We will actually use these accesses in the future, but let's skip the details for now.
With the above accesses, you can achieve the same effect as the SDK.
Next, we will continue to explore how to implement article publishing and other management operations through authentication, so that xlog will have the ability of a headless cms.
Additional: Uploading Files to ipfs
Based on actual experience, images, audio, and video files uploaded to xlog will be automatically uploaded to ipfs and the image links will be replaced with ipfs links.
Currently, there are two methods: using xlog's ipfs upload protocol or using http.
Here is a simple guide to ipfs file upload, which will help you become familiar with the xlog source code.
The idea is as follows:
- Because image upload is triggered by dragging and pasting, you can search for drag/paste in the source code to locate
src/components/ui/ImageUploader.tsx#handleDrop
- Further locate
handleFile
-uploadFile
-useUploadFile
-UploadFile
- You can see that it is submitted to the specified interface through the POST protocol
Let's ignore the screenshots for now. I found that there is no authentication...
Conclusion
The above is the feasibility exploration. At least we can access data through the interface. In the next article, we will explore how to implement article publishing and other management operations through authentication. At that time, xlog will have the ability of a headless cms.