模板零件名称是否有变量?


8

您使用get_template_part()(或locate_template())称为模板的人有一种方法可以知道您所使用的模板。

例如,如果您get_template_part('loop','archive');archive.php

然后在您的loop-archive.php文件中工作。有没有一种方法可以定义一个具有当前模板部件名称的变量$template = 'loop-archive'。更好的是,也许分为两部分,分别是“循环”和“归档”,但我可以通过一些字符串拆分来做到这一点。

问题#10537似乎有点相关,但似乎没有涵盖模板部分

Answers:


2

没有返回当前上下文的核心全局变量。但是,您可以使用上下文模板条件标签构造自己的标签。您可以按照,以与WordPress核心相同的顺序浏览条件标签wp-includes/template-loader.php

只需将输出包装在自定义主题函数中即可。这是我的操作方法(注意:我认为我不严格遵循template-loader.php):

function oenology_get_context() {

    $context = 'index';

    if ( is_home() ) {
        // Blog Posts Index
        $context = 'home';
        if ( is_front_page() ) {
            // Front Page
            $context = 'front-page';
        } 
    }else if ( is_date() ) {
        // Date Archive Index
        $context = 'date';
    } else if ( is_author() ) {
        // Author Archive Index
        $context = 'author';
    } else if ( is_category() ) {
        // Category Archive Index
        $context = 'category';
    } else if ( is_tag() ) {
        // Tag Archive Index
        $context = 'tag';
    } else if ( is_tax() ) {
        // Taxonomy Archive Index
        $context = 'taxonomy';
    } else if ( is_archive() ) {
        // Archive Index
        $context = 'archive';
    } else if ( is_search() ) {
        // Search Results Page
        $context = 'search';
    } else if ( is_404() ) {
        // Error 404 Page
        $context = '404';
    } else if ( is_attachment() ) {
        // Attachment Page
        $context = 'attachment';
    } else if ( is_single() ) {
        // Single Blog Post
        $context = 'single';
    } else if ( is_page() ) {
        // Static Page
        $context = 'page';
    }

    return $context;
}

然后,我只是将其oenology_get_context()作为参数传递,例如:

get_template_part( 'loop', oenology_get_context() );

我认为遵循这些思路的某些东西将是核心的不错选择,尽管我不确定实现的最佳方法。不过,我很想提交补丁。


哇芯片。那非常非常光滑。而您的用例正是我想要的。至于补丁,为什么不单步执行模板加载器就同时注册该全局权限?
helgatheviking 2012年

1
因为我不确定添加另一个全局变量是否是内核的“有福”方法。将上下文返回为字符串的函数可能会更好-但是,这可能需要对进行一些重写template-loader.php
Chip Bennett

不错+1。只要一注:index永远不会匹配,因为无论是is_front_page()is_home()会触发。
kaiser 2012年

1
另一件事:is_home()应该是第一位的,因为front-page即使激活了“最新帖子”设置并且没有首页,它也会返回。刚刚测试。
kaiser 2012年

同意@kaiser。您甚至可以is_home() && 'page'根据需要使用。有关首页中博客文章与静态页面的更多信息,请查看我自己的答案,这里是:wordpress.stackexchange.com/questions/208503/…。顺便说一句,@Chip和@helgatheviking,最好使用a switch代替这么多elseif(效率更高;-)。问候!
杰拉德(Gerard)2015年

4

一点点facepalm,因为答案是在纯PHP中

$path_parts = pathinfo(__FILE__);
//var_dump($path_parts); 
echo $path_parts['filename'];

2

如果您查看get_template_part函数的源代码,您将看到:

function get_template_part( $slug, $name = null ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    locate_template($templates, true, false);
}

它创建了一个由2个模板名称组成的数组:{$slug}-{$name}.php{$slug}.php并用于load_template查找模板文件并将其包含(第二个参数是true,这意味着包括该文件)。

您可以模仿此函数以返回模板文件路径,而不是包含它,例如:

function my_get_template_part( $slug, $name = null, $include = false ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    return locate_template($templates, $include, false);
}

用法:

// Don't load the template
$template = my_get_template_part( 'loop', 'archive', false );

// Or load the template
$template = my_get_template_part( 'loop', 'archive', true );

// Get the file name only
$template = basename( $template );

// Without .php extension
$template = substr( $template, 0, -4 );

您可以玩更多,$template以获得想要的东西。


太整齐了!当然可以+1,但我需要知道loop-arhive.php模板内的$ template信息(按照您的示例)
helgatheviking 2012年

您可以使用它在设置一个全局变量archive.php,并在重新使用它loop-archive.php
映陈德良

2

列出所有符合条件的 true

由于所有is_*()函数在查询变量中都有它们的等效项(这些函数只是包装器),因此您还可以另一种方式访问​​它们:只需获取所有true

我在core / trac上写了一张票,其中添加了一个功能以列出所有票。

同时,您可以将列出的两个功能用作帮助程序插件,以向您显示在哪个请求上可以使用哪个条件。它将var_dump()shutdown钩子的页脚下方(管理员和公共)打印a 。

<?php
/** Plugin Name: (#62232) »kaiser« List all conditionals that are true */
function get_conditionals()
{ 
    global $wp_query; 

    foreach ( get_object_vars( $wp_query ) as $is_key => $is_value ) 
    { 
            if ( $is_value && preg_match( "/is_/", $is_key ) ) 
                    $conditionals[] = $is_key; 
    } 

    return var_dump( $conditionals );
} 
add_action( 'shutdown', 'get_conditionals' );

这样,您可以简单地遍历它们。

@scribu在票证中添加了自己的功能(也是一个有趣的解决方案)。

   

<?php
/** Plugin Name: (#62232) »scribu« List all conditionals that are true */
function get_query_flags( $wp_query = null ) {
    if ( !$wp_query )
        $wp_query = $GLOBALS['wp_query'];

    $flags = array();

    foreach ( get_object_vars( $wp_query ) as $key => $val ) {
        if ( 'is_' == substr( $key, 0, 3 ) && $val )
            $flags[] = substr( $key, 3 );
    }

    return var_dump( $flags );
}
add_action( 'shutdown', 'get_query_flags' );

性能

我使用来对模板中间的每个函数进行了性能测试timer_start/*_stop();。公平地说,我将所有功能重命名为一个字符名称a/b/c()

如您所见,Chips硬编码功能最快,然后是我的,最后是scribus。

在此处输入图片说明

更新资料

如果您了解我,那么您就会知道我对迭代器的热爱,因为它们的优雅,透明和仅在内存中保留单个项目而不是在循环时复制整个数组的能力。因此,这是一个扩展了的快速自定义类\FilterIterator,因此只需要修改一个方法即可。

<?php

namespace WPSE;

class ConditionalsFilter extends \FilterIterator
{
    /**
     * Accepts properties that start with `is_` and have a positive boolean value
     * @return bool
     */
    public function accept()
    {
        return 0 === strncasecmp( $this->key(), 'is_', 3 )
            and filter_var(
                $this->current(),
                FILTER_VALIDATE_BOOLEAN,
                FILTER_NULL_ON_FAILURE
            );
    }
}

它可以很容易地使用。将$it->current()持有的价值,同时$it->key()回报条件/属性名称。

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}

1
好吧,这非常聪明。谢谢!当我完成其他工作时,我将不得不重新考虑这一点。另外,真的很难记住要大写!坏习惯很难打破。
helgatheviking 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.