如何将帖子存储为复杂的 JSON 对象并在 Dyson 协议上将它们呈现到您的网站(第 7 部分)

如何将帖子存储为复杂的 JSON 对象并在 Dyson 协议上将它们呈现到您的网站(第 7 部分)

欢迎回到戴森协议教程系列。

请注意,提供的某些屏幕截图可能无法反映我们网站 UI 的当前版本。

在我们上一个教程中,您学习了如何遍历存储的帖子并将它们作为博客呈现到您的网站。

在今天的教程中,您将学习:

  • 如何存储复杂的帖子 JSON 要存储的对象。
  • 如何从存储中删除已保存的数据
  • 如何使用 条件 根据其数据模式呈现博客文章。

如果您是戴森协议生态系统的新手,请从以下教程开始获取您的戴森币并创建您的第一个函数:

戴森协议:如何使用 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(),  
 ]

到目前为止,您现在应该能够:

  • 将帖子存储为复杂 JSON 要存储的对象。
  • 从存储中删除已保存的数据
  • 利用 条件 根据其数据模式呈现博客文章。

现在看看你,你已经创建了一个更好看的博客!与前两个教程一样,现在花一些时间来看看如何使用一些额外的 CSS 添加更多样式。在这个阶段,您应该对更改博客的风格感到很自在,所以真的要全力以赴,让我们感到自豪!

一旦您对博客的外观感到满意,请在我们的 Discord 频道上分享!

请继续关注我们的下一个教程!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/40272/51410117

posted @ 2022-10-01 17:53  哈哈哈来了啊啊啊  阅读(66)  评论(0编辑  收藏  举报