如何将帖子存储为复杂的 JSON 对象并在 Dyson 协议上将它们呈现到您的网站(第 7 部分)
如何将帖子存储为复杂的 JSON 对象并在 Dyson 协议上将它们呈现到您的网站(第 7 部分)
欢迎回到戴森协议教程系列。
请注意,提供的某些屏幕截图可能无法反映我们网站 UI 的当前版本。
在我们上一个教程中,您学习了如何遍历存储的帖子并将它们作为博客呈现到您的网站。
在今天的教程中,您将学习:
如果您是戴森协议生态系统的新手,请从以下教程开始获取您的戴森币并创建您的第一个函数:
戴森协议:如何使用 Keplr 钱包(并获得免费的 DYS)
如果您遇到困难或有任何疑问,请不要犹豫跳到我们的 Discord 服务器。请记住,通过将脚本地址粘贴到我们的 Discord 服务器的 testnet-airdrop 通道中,您始终可以获得更多 DYS 硬币。
第 1 步:从上次中断的地方继续。
与往常一样,您将返回到您在上一个教程中处理的脚本。
为此,首先在浏览器中打开一个新选项卡,然后转到 dysonvalidator.com
您的脚本地址尚不可见,但不要惊慌——您只需要解锁您的钱包。点击 连接钱包
, 然后 连接 Keplr
,然后输入您的 Keplr 登录详细信息。
现在您应该在窗口顶部看到您的脚本地址。
如果您在桌面上访问 Dyson 协议,请单击脚本地址。您的浏览器将导航到您的脚本,其中应该可以看到上一教程中的代码行。
如果您在移动设备上访问 Dyson 协议并且看不到您的脚本地址 — 不要恐慌! 按下屏幕右上角的三个水平条按钮,菜单将下拉显示您的脚本地址。
单击您的脚本地址,浏览器将导航到您的脚本。
在继续之前,请确保您的脚本代码如下。如果它看起来有什么不同,那没关系。只需从脚本中删除所有代码行,然后将以下行复制并粘贴到脚本中,然后单击保存。
如果您在上一教程结束后对脚本的 CSS 或 HTML 进行了任何其他更改,最好将您的代码恢复为我们在此处使用的代码,以便更轻松地进行调试。
导入re2
导入html
从字符串导入模板
从dy导入_chain,get_script_address,get_caller
def new_post(标题:str,正文:str):
断言 get_script_address() == get_caller(), "权限被拒绝"
数据 = f"{title} -- {body}"
title_slug = re2.sub("\W+", "-", 标题)
print(data) # 帮助调试
返回_链(
"戴森/sendMsgCreateStorage",
创建者=get_script_address(),
index=get_script_address() + "/post/v1/" + title_slug,
数据=数据,
力=真,
)
def get_all_posts():
响应 = _链(
"戴森/QueryPrefixStorage",
前缀=get_script_address() + "/post/v1/"
)
返回响应[“结果”]
def 渲染页面(正文:str):
返回模板(
"""<!doctype html>
<html>
<head>
<title>你好世界</title>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[[email protected]](/cdn-cgi/l/email-protection)/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<style>
.标题{
文字阴影:#FC0 1px 0 10px;
}
</style>
</head>
<body>
<div class="container">
<h1 class="heading">帖子!</h1>
<p>$身体</p>
</div>
</body>
</html>
"""
).safe_substitute(body=body)
def render_posts(posts: list[dict[str, str]]):
返回 (
"<ul> "
+ "".join(["<li> " + html.escape(s["data"]) + "</li> " 用于帖子中的 s])
+ "</ul> "
)
def 应用程序(环境,start_response):
start_response("200 ok", [("Content-type", "text/html")])
post_data = get_all_posts()
返回 [
render_page(render_posts(post_data["storage"])).encode(),
]
最后,通过将脚本渲染到 webapp 并查看它来确保您的脚本是正确的。
就像之前的教程一样,首先你需要保存你的脚本。输入您的姓名 问好
,然后单击 运行say_hello
.
接下来,在新选项卡中导航到以下 URL,将占位符替换为您的脚本地址。
https://[YOUR_SCRIPT_ADDRESS_HERE].dysonvalidator.com/
如果一切正常,您应该会在浏览器中看到您的博客文章。它应该类似于:
您现在可以开始本教程了!
第 2 步:重构 new_post 函数以将数据存储为 JSON 字典。
以下代码显示了您将在此步骤中进行的更改,删除的行以红色突出显示,添加的行以绿色突出显示:
到目前为止,您的博客文章已被格式化为一个简单的 f 字符串,将标题和正文连接在一起。在这种格式下,不可能单独访问帖子的标题或正文。存储数据的更好方法是采用 JSON字典 .
这里有个问题——戴森只能将数据作为字符串存储在链上,所以你不能直接存储 JSON 字典。
但是,您可以做的是使用 JSON 模块中的一个方便的函数,称为[ json.dumps()](https://docs.python.org/3/library/json.html?#basic-usage)
,它本质上将 JSON 字典转换为 JSON 格式的字符串。这为您提供了 JSON 字典的功能,同时允许 Dyson 使用它,因为它仍然是一个字符串。
通过添加以下内容在脚本顶部导入 JSON 模块:
导入json
现在实施 json.dumps
通过替换你的第二行来发挥作用 最新帖子
功能:
数据 = json.dumps({"title": title, "body": body})
您刚刚更改了数据架构,因此您应该更新保存帖子的位置。在上一教程中,您介绍了一个简单的版本控制系统。这是它将开始有用的地方。
通过替换您的倒数第四行,将数据模式的版本更改为版本 2 最新帖子
功能:
index=get_script_address() + "/post/v2/" + title_slug,
就本教程而言,您将需要访问您在数据模式版本 1 下保存的以前的博客文章。为此,请替换您的第 2 行和第 3 行 获取所有帖子
具有以下功能:
“dyson/QueryPrefixStorage”,前缀=get_script_address() + “/post/”
请注意,您在这里所做的只是从 戴森/QueryPrefixStorage
函数用于搜索帖子。这意味着它现在将返回所有存储的帖子,而不管它们的数据模式如何。
通过发布一些新的博客文章来试验这种变化。请记住,您可以通过在您的 最新帖子
功能和点击 运行 new_post
.
现在您已经发布了一些新帖子,请导航到您的博客并刷新页面。它现在应该看起来像这样:
奖励步骤:从存储中删除。
如果您想知道如何删除已保存到存储中的任何内容,例如博客文章,请听好!
首先,导航到 https://dys.dysonvalidator.com/commands?command=dyson/sendMsgDeleteStorage .
如果您在桌面上访问 Dyson,您应该会在页面顶部看到 Msg Delete Storage 命令。如果您使用的是移动设备,请向下滚动到页面底部。
输入你的脚本地址 创造者
字段,以及您希望在 指数
场地。
在删除博客文章的情况下,索引由以下内容组成:
[您的脚本地址]/post/[数据架构 (v1/v2)]/[您的帖子标题 slug]
请记住,您帖子的标题段是您帖子的标题,任何非单词字符都替换为“-”。
注意任何大小写,因为此功能是特定于大小写的,并且您要删除的项目是否属于 v1
或者 v2
数据架构。
点击 签署交易
,然后导航回您的网站并刷新页面以查看更改。
第 3 步:创建一个新的 render_post 函数以提供更大的灵活性。
以下代码显示了您将在此步骤中进行的更改,删除的行以红色突出显示,添加的行以绿色突出显示:
现在您有两种不同的数据模式:
- 版本 1 或 v1,其中博客文章存储为格式为字符串
“标题——正文”
- 版本 2 或 v2,其中博客文章存储为 JSON 字典。
有很多方法可以处理这种情况。最适合您的应用程序的方法取决于您的数据和逻辑。但是,在本教程中,您将根据数据模式有条件地呈现这两种类型的帖子。
在我们这样做之前,让我们将渲染单个帖子的逻辑分离到一个新函数中。这一步只是一个小改动,但您将在下一步中看到为什么它很重要。
在您的下方添加两个换行符 渲染页面
函数,然后将以下函数复制并粘贴到您的脚本中:
def render_post(post: dict[str, str]):
返回 html.escape(post["data"])
现在重构你的 渲染帖子
功能,使 渲染帖子
函数在其内部被调用 为了
通过将第三行替换为:
+ "".join(["<li> " + render_post(post) + "</li> " 用于帖子中的帖子])
您的代码不会做任何不同的事情,但它功能更强大,并为下一步做好了准备。
第 4 步:改进 render_post 函数以根据帖子的数据模式有条件地渲染帖子。
以下代码显示了您将在此步骤中进行的更改,删除的行以红色突出显示,添加的行以绿色突出显示:
既然您有一个单独呈现帖子而不是作为一个组呈现帖子的功能,您可以根据某些条件以不同的方式呈现它们。
在这种情况下,您必须实现一些简单的 if 语句 .
正如您从前面的步骤中看到的那样,保存在数据方案 v1 下的帖子已经正常显示,因此在渲染它们时无需进行任何更改。因此,将 render_post 函数的第一行替换为:
如果 "/v1/" 在 post["index"] 中:
返回 html.escape(post["data"])
格式化为 JSON 字典的帖子需要在幕后进行更多工作才能以一种不错的方式呈现,但正如您稍后会看到的,额外的工作是值得的。
将以下行添加到您的末尾 渲染帖子
功能:
如果 "/v2/" 在 post["index"] 中:
模板 = 模板(“<div><h2> $标题</h2><p>$身体</p></div>")
post_data = json.loads(post["data"])
返回模板.safe_substitute(
标题=html.escape(post_data["title"]),
body=html.escape(post_data["body"]),
)
现在看看这两种数据模式如何以不同的方式显示帖子。保存您的脚本,导航到您的博客,然后刷新页面。它现在应该看起来像这样:
现在您的博客文章的标题实际上看起来像标题!是不是看起来好多了?当然,它需要一些额外的工作才能使其正常工作,但很清楚哪个数据模式更实用。
恭喜,您已完成第七期戴森协议教程!
您的代码现在应该如下所示:
导入json
导入re2
导入html
从字符串导入模板
从dy导入_chain,get_script_address,get_caller
def new_post(标题:str,正文:str):
断言 get_script_address() == get_caller(), "权限被拒绝"
数据 = json.dumps({"title": title, "body": body})
title_slug = re2.sub("\W+", "-", 标题)
print(data) # 帮助调试
返回_链(
"戴森/sendMsgCreateStorage",
创建者=get_script_address(),
index=get_script_address() + "/post/v2/" + title_slug,
数据=数据,
力=真,
)
def get_all_posts():
响应 = _链(
“dyson/QueryPrefixStorage”,前缀=get_script_address() + “/post/”
)
返回响应[“结果”]
def 渲染页面(正文:str):
返回模板(
"""<!doctype html>
<html>
<head>
<title>你好世界</title>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[[email protected]](/cdn-cgi/l/email-protection)/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<style>
.标题{
文字阴影:#FC0 1px 0 10px;
}
</style>
</head>
<body>
<div class="container">
<h1 class="heading">帖子!</h1>
<p>$身体</p>
</div>
</body>
</html>
"""
).safe_substitute(body=body)
def render_post(post: dict[str, str]):
如果 "/v1/" 在 post["index"] 中:
返回 html.escape(post["data"])
如果 "/v2/" 在 post["index"] 中:
模板 = 模板(“<div><h2> $标题</h2><p>$身体</p></div>")
post_data = json.loads(post["data"])
返回模板.safe_substitute(
标题=html.escape(post_data["title"]),
body=html.escape(post_data["body"]),
)
def render_posts(posts: list[dict[str, str]]):
返回 (
"<ul> "
+ "".join(["<li> " + render_post(post) + "</li> " 用于帖子中的帖子])
+ "</ul> "
)
def 应用程序(环境,start_response):
start_response("200 ok", [("Content-type", "text/html")])
post_data = get_all_posts()
返回 [
render_page(render_posts(post_data["storage"])).encode(),
]
到目前为止,您现在应该能够:
现在看看你,你已经创建了一个更好看的博客!与前两个教程一样,现在花一些时间来看看如何使用一些额外的 CSS 添加更多样式。在这个阶段,您应该对更改博客的风格感到很自在,所以真的要全力以赴,让我们感到自豪!
一旦您对博客的外观感到满意,请在我们的 Discord 频道上分享!
请继续关注我们的下一个教程!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明