如何在Timber中通过短代码渲染的树枝中获取$ context?

时间:2016-09-06 20:26:28

标签: wordpress twig timber

我在帖子[短代码]中有一个短代码。我希望能够在短代码中访问当前帖子的标题,但是$context是空白有没有办法从通过短代码渲染的树枝中访问post

以下是示例代码:

add_shortcode('include', 'timber_partial_shortcode');

function timber_partial_shortcode($atts){
    $post = new TimberPost()
    $context['post'] = $post
    $name = sanitize_text_field($atts['name']);
    return Timber::compile('partials/' . $name . '.twig', $context);
}

现在这个有用,但我想知道是否有办法在已经设置的twig文件中访问TimberPost而不是重置它..如果我想要来自$ context的变量,{{1从短代码中抛出一个未定义的函数错误。

2 个答案:

答案 0 :(得分:3)

@damon试试Timber::get_context();:)

答案 1 :(得分:2)

我查看了get_context()函数。

  • 如果您致电get_context(),则会缓存在上下文中设置的所有值。
  • 每当您再次致电get_context()时,它只会返回缓存的上下文。
  • 这意味着,您在第一次调用get_context()后无法向上下文添加新值,例如通过timber/context过滤器。

我认为Jared’s答案实际上非常重要。由于他是木材的创造者,我猜他必须知道;)。

但是既然你问过如何在短代码和Timber的上下文中将值传递给函数,我会尝试向你展示一些选项:

使用匿名函数

在模板文件中,您可以使用匿名函数添加短代码作为回调(第二个参数)。这样,您就可以利用use关键字,您可以使用该关键字传递之前定义的$context

<?php

use Timber\Timber;

$context = Timber::get_context();

$post = Timber::get_post();
$context['post'] = $post;

// Add shortcode with an anonymous function
add_shortcode( 'include', function( $atts ) use ( $context ) {
    $name = sanitize_text_field( $atts['name'] );
    return Timber::compile( 'partials/' . $name . '.twig', $context );
} );

Timber::render( 'shortcodes.twig', $context );

但是,如果在多个模板文件中使用该短代码,则可能不希望每次都添加该函数。让我们看看我们能做些什么:

创建一个过滤器以传递上下文

模板文件(例如 post.php

<?php

use Timber\Timber;

$context = Timber::get_context();

$post = Timber::get_post();
$context['post'] = $post;

set_context_for_shortcodes( $context );

Timber::render( 'shortcodes.twig', $context );

<强>的functions.php

/**
 * Add a filter that simply returns the context passed to this function.
 *
 * @param $context
 */
function set_context_for_shortcodes( $context ) {
    add_filter( 'get_context', function( $empty = array() ) use ( $context ) {
        return $context;
    } );
}

add_shortcode( 'include', function( $atts ) {
    // Get the context trough the filter set before
    $context = apply_filters( 'get_context', [] );

    $name = sanitize_text_field( $atts['name'] );
    return Timber::compile( 'partials/' . $name . '.twig', $context );
} );

但是,请注意,当您使用带有操作和过滤器的匿名函数时,you cannot remove them later with remove_action() or remove_filter()。因此,当您开发要发布的插件或主题时,您可能会重新考虑这一点。否则,你可能会很高兴。

处理类

的短代码

您还有另一种选择,它不依赖于过滤器,而是依赖于处理短代码的类。

模板文件(例如 post.php

<?php

use Timber\Timber;

$context = Timber::get_context();

$post = Timber::get_post();
$context['post'] = $post;

new Shortcode_Handler( $context );

Timber::render( 'shortcodes.twig', $context );

<强>的functions.php

<?php

class Shortcode_Handler {
    public $context;

    public function __construct( $context ) {
        $this->context = $context;

        add_shortcode( 'include', array( $this, 'timber_partial_shortcode' ) );
    }

    public function timber_partial_shortcode( $atts ) {
        $context = $this->context;

        $name = sanitize_text_field( $atts['name'] );
        return Timber::compile( 'partials/' . $name . '.twig', $context );
    }
}