Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何调用异步标签,目前是不是不支持异步标签? #877

Open
sunkaifei opened this issue Dec 3, 2023 · 9 comments
Open

Comments

@sunkaifei
Copy link

一个网站里有很多模块,首页要推荐很多栏目列表,这些列表要从数据库读取,例如文章的推荐类型就有最新的,推荐的,热门的等等,如果这个标签可以通过设置的参数调用各个所需的内容就行了

@Keats
Copy link
Owner

Keats commented Dec 3, 2023

Can you translate in English?

@sunkaifei
Copy link
Author

Hello, I understand that you are facing some issues with the tera template engine in the actix_web framework. Here is a translation of your previous message into English:

For example, in a Java program, there is a freemarker template plugin that defines a module's tag at the Java backend. For instance, it can be an article list tag that allows setting various parameters. Then, in the template, you can directly call this tag with parameters to retrieve the desired content. This tag can be global.

Currently, I am using actix_web and the tera engine. I encountered the following issues:

The tera.register_function method cannot invoke asynchronous functions, such as retrieving data from a database.
It seems that in actix_web, the global usage of tags requires calling them again in each controller for them to take effect.
The template reload feature does not seem to work when set in actix_web. It requires calling the template setup function every time. Is there a way to set it globally in the main function?

@sunkaifei
Copy link
Author

sunkaifei commented Dec 3, 2023

If you are using an asynchronous function to retrieve an article list and the returned content can be of various types, but Tera only accepts Result as the output type, you will need to handle the conversion from different types to Value within your code.

`pub async fn article_tags(args: &HashMap<String, Value>) -> Result {

let mut param =ArticlesPageRequest{
    category_id: None,
    user_id: None,
    status: None,
    page_no: 1,
    page_size: 10,
};

if let Some(category_id) = args.get("categoryId") {
    param.category_id = Some(category_id.as_i64().unwrap() as u64);
}
if let Some(user_id) = args.get("userId") {
    param.user_id = Some(user_id.as_i64().unwrap() as u64);
}
if let Some(status) = args.get("status") {
    param.status = Some(status.as_i64().unwrap() as i8);
}

let mut result: Vec<ArticlesListData> = Vec::new();
match article_service::get_by_page(param).await {
    Ok(data_op) => {
        result = data_op.records.iter().map(|article| {
            ArticlesListData {
                id: article.id.clone(),
                short_url: article.short_url.clone(),
                category_id: article.category_id.clone(),
                category_ids: article.category_ids.clone(),
                user_id: article.user_id.clone(),
                title: article.title.clone(),
                short_title: article.short_title.clone(),
                title_image: article.title_image.clone(),
                author: article.author.clone(),
                original_link: article.original_link.clone(),
                description: article.description.clone(),
                content: article.content.clone(),
                count_comment: article.count_comment.clone(),
                count_view: article.count_view.clone(),
                count_love: article.count_love.clone(),
                count_digg: article.count_digg.clone(),
                count_burys: article.count_burys.clone(),
                count_follow: article.count_follow.clone(),
                isclose: article.isclose.clone(),
                iscomment: article.iscomment.clone(),
                iscommentshow: article.iscommentshow.clone(),
                isposts: article.isposts.clone(),
                isrecommend: article.isrecommend.clone(),
                update_time: article.update_time.clone(),
            }
        }).collect();

        let json_value: Value = to_value(result)?;
        return Ok(json_value);
    }
    Err(_) => {}
}`

13 | tera.register_function("article_tags", article_tags); | ----------------- ^^^^^^^^^^^^ expectedResult<Value, Error>, found future | | | required by a bound introduced by this call | note: calling an async function returns a future --> src\core\service\templates_service.rs:13:44 | 13 | tera.register_function("article_tags", article_tags); | ^^^^^^^^^^^^ = note: required for fn(&HashMap<String, Value>) -> impl Future<Output = Result<Value, Error>> {article_tags}to implementFunction= note: the full type name has been written to 'E:\rustwork\actix-admin\target\debug\deps\actix_admin.long-type-17683279296791569248.txt' note: required by a bound inTera::register_function--> C:\Users\kaife\.cargo\registry\src\github.com-1ecc6299db9ec823\tera-1.19.1\src\tera.rs:668:33 | 668 | pub fn register_function<F: Function + 'static>(&mut self, name: &str, function: F) { | ^^^^^^^^ required by this bound inTera::register_functionhelp: considerawaiting on the Future| 13 | tera.register_function("article_tags", article_tags.await); | ++++++

@Keats
Copy link
Owner

Keats commented Dec 4, 2023

Tera doesn't support async tests/functions/filters no

@sunkaifei
Copy link
Author

Is there a plan to support asynchronous calling of tags?

@Keats
Copy link
Owner

Keats commented Dec 4, 2023

No

@dw0616
Copy link

dw0616 commented Mar 6, 2024

@sunkaifei async functions你有没有实现出来?
我另起一个线程,然后使用futures::executor::block_on加载异步调用数据,但是有时会卡死。

@sunkaifei
Copy link
Author

@dw0616 没有,我技术能力有限,没搞定就没搞了

@sunkaifei
Copy link
Author

@dw0616 作者好像没有实现这个功能想法,哈哈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants