首页 > 解决方案 > 使用 Timber 将变量放入 WordPress 短代码中

问题描述

我将 Timber 用于 WordPress,并安装了一个评级插件(Yet Another Stars Rating 插件)。用户可以为电影投票。

这个插件使用简码来显示投票结果和投票系统。

我有一个电影列表,我想显示每部电影的投票系统。

我在电影模板中创建了查询:tpl_movies.php

$context['movies'] = Timber::get_posts(array(
    'post_type' => 'movies',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'orderby' => 'rand',
    'order' => 'ASC'
));

我的树枝文件中有一个循环:tpl_movies.twig

{% for item in movies %}
  <ul class="movies__list">
    <li>{{ item.title }} - Vote : {% filter shortcodes %} [yasr_overall_rating postid="{{ item.ID }}"] {% endfilter %}</li>
  </ul>
{% endfor %}

我试图{{ item.ID }}输入我的简码:

[yasr_overall_rating postid="{{ item.ID }}"]

但这行不通。

我可以为当前页面(显示电影列表的页面)投票,但不能为每部电影投票。

你有什么主意吗 ?先感谢您。

标签: wordpresstwigshortcoderatingtimber

解决方案


Joshua T 在上面的评论中提供的答案应该有效,它使用 twig 的字符串连接运算符~将正确的字符串输入到do_shortcode函数中。

如果您有兴趣更深入地了解 Timber,那么您可以使用几种方法。

Timber 对此有一些指导,您可以查看官方文档。

首先,所有简码都是输出函数的包装器 - 当您注册简码时,您会告诉 WordPress 相关的输出函数是什么。

对于这种情况,它是shortcode_overall_rating_callback(),并且它需要一个数组,$atts就像所有短代码一样。

所以你可以做这样的事情......

{# call the function directly from the twig template #}

{% for item in movies %}
    <ul class="movies__list">
        <li>{{ item.title }} - Vote : {{ function('shortcode_overall_rating_callback', { postid: item.id }) }}</li>
    </ul>
{% endfor %}

如果每部电影都有评分,那么您可以考虑扩展它的“模型”以包含此功能。

从概念上讲,这很好,因为这意味着每部电影都可以在您获取它们的任何地方输出它自己的评级,而不是将其仅绑定到您正在编写的这个模板。

为此,您将扩展Timber\Post并获取电影作为此自定义 Post 模型,而不是 stock Timber\Post

/* Somewhere in your theme, ensure it gets loaded, inc/models/Movie.php as an example */
<?php


namespace YourName\YourProject;
use \Timber\Post;
 
class Movie extends Post {

    public function get_rating_html(){
        if ( ! function_exists( 'shortcode_overall_rating_callback' ) ) return '';
        /* Can add other attributes to the array provided here */
        return shortcode_overall_rating_callback( [ 'postid' => $this->id, ] );
    }

}

然后在用于上下文构建的 PHP 模板中,通过将类名作为第二个参数传递给get_posts().

$queryArgs = [
  'post_type' => 'movies',
  'post_status' => 'publish',
  'posts_per_page' => -1,
  'orderby' => 'rand',
  'order' => 'ASC'
];

$context['movies'] = Timber::get_posts( $queryArgs, \YourName\YourProject\Movie::class );

最后在我们的树枝模板中,我们可以访问自定义方法..

{% for item in movies %}
  <ul class="movies__list">
    <li>{{ item.title }} - Vote : {{ item.get_rating_html }}</li>
  </ul>
{% endfor %}

这些示例确实使用了命名空间和现代 PHP 语法之类的东西,但如果您使用的是 Timber,那么您已经使用了支持此功能的 PHP 版本。

最后,如果您经常使用自定义 Post 对象,Timber 有一个很棒的过滤器Timber\PostClassMap,您可以在其中为每个帖子类型添加自己的映射,这样您就不需要每次都提供自定义帖子类名称,并且可以只是new PostQuery( $args );orTimber::get_posts($args)和您将取回与您的帖子类型匹配的自定义帖子类。一旦您开始使用它,这就是魔法!


推荐阅读