带有动态值的Rust TinyTemplate(hashmap)?
我使用TinyTemplate板条箱为Actix Web Rust网站提供服务,其中它们的键和值是在使用config
crate序列化的TOML文件中定义的。 这与预定义的键(在编译时已知)非常有用,但是我想添加一个动态的“另请参见”部分,我不知道如何实现它。
config.toml
title= "Example Title" # this works great
[seealso] # dynamic values, is this possible?
"Project Homepage" = "https://my-project-page.eu"
"Repository" = "https://github.com/myorg/myrepo"
template.html
{title}
{{ for x in seealso }}
...
{{ endfor }}
main.rs
[...]
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub title: String,
pub seealso: HashMap<String, String>,
}
impl Config {
pub fn new() -> Result<Self, ConfigError> {
config::Config::builder()
.add_source(File::from_str(DEFAULT, FileFormat::Toml))
.build()?
.try_deserialize()
}
}
[...]
lazy_static! {
pub static ref CONFIG: Config = Config::new().expect("Error reading configuration.");
}
[...]
let mut template = TinyTemplate::new();
template.add_template("index", INDEX).expect("Could not parse default template");
let body = template().render("index", &*CONFIG).unwrap();
输出
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: RenderError { msg: "Expected an array for path 'seealso' but found a non-iterable value.", line: 32, column: 17 }', src/main.rs:80:53
我假设Serde可以将哈希截止归为JSON对象,并以Hashmap键为对象键,这就是为什么我假设Rust不会让我迭代它们。问题在于,TinyTemplate在设计上是基本的功能,并且不能让我在{{}}}
之间放置任意代码,因此我无法将对象(struct?)转换为TinyTemplate可以迭代。我对Rust的新手很新,所以我可能在这里缺少一些明显的东西,但是有没有一种方法可以使用TinyTemplates这样的动态值,或者没有办法处理hashmaps?结果不必使用哈希图。
目标是实现以下伪代码之类的东西:
{{ if ! seealso.empty() }}
See also:
<ul>
{{ for (key, value) in seealso }}
<li><a href="{value}">{key}</a></li>
{{ endfor }}
</ul>
{{ endif }}
I serve an Actix Web Rust website using the TinyTemplate crate, where they keys and values are defined in a TOML file that is serialized using the config
crate.
This works great with predefined keys (known at compile time) like "title" but I want to add a dynamic "see also" section and I can't figure out how to implement this.
config.toml
title= "Example Title" # this works great
[seealso] # dynamic values, is this possible?
"Project Homepage" = "https://my-project-page.eu"
"Repository" = "https://github.com/myorg/myrepo"
template.html
{title}
{{ for x in seealso }}
...
{{ endfor }}
main.rs
[...]
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub title: String,
pub seealso: HashMap<String, String>,
}
impl Config {
pub fn new() -> Result<Self, ConfigError> {
config::Config::builder()
.add_source(File::from_str(DEFAULT, FileFormat::Toml))
.build()?
.try_deserialize()
}
}
[...]
lazy_static! {
pub static ref CONFIG: Config = Config::new().expect("Error reading configuration.");
}
[...]
let mut template = TinyTemplate::new();
template.add_template("index", INDEX).expect("Could not parse default template");
let body = template().render("index", &*CONFIG).unwrap();
Output
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: RenderError { msg: "Expected an array for path 'seealso' but found a non-iterable value.", line: 32, column: 17 }', src/main.rs:80:53
I assume that serde deserializes the HashMap into a JSON object, with the HashMap keys as object keys, which is why I assume Rust won't let me iterate over them. The problem is that TinyTemplate is quite basic in functionality by design, and won't let me put arbitrary code between {{ }}
so I can't transform the object (struct?) into something that TinyTemplate can iterate over. I'm quite new to Rust so I may be missing something obvious here, but is there a way to use dynamic values like this with TinyTemplates or is there no way to handle HashMaps? The result doesn't have to use HashMaps though.
The goal is to achieve something like the following pseudocode:
{{ if ! seealso.empty() }}
See also:
<ul>
{{ for (key, value) in seealso }}
<li><a href="{value}">{key}</a></li>
{{ endfor }}
</ul>
{{ endif }}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经在
tinyTemplate
上查看了代码。它将给定对象转换为JSON
对象,用serde
将其与JSON表示形式一起工作以进行进一步处理。给定Hashmap
,它将创建一个普通的对象节点,该节点是根据板条箱的代码而无法的。云创建
板条板的拉请请求
;在对象字段上迭代应直接。另一个可能的解决方案可能是创建您的配置的第二个表示。
I have took a look on the code on
tinytemplate
. It converts the given object into ajson
object withserde
and works with the json representation for further processing. Given aHashmap
, it will create an plain object node which isn't iterable according to the code of the crate.You cloud create a pull request for the
crate
; iterating over object fields should be straight forward.Another possible solution could be to create a second representation of your config.