Có một biến cho một tên bộ phận mẫu?


8

Một bạn đã gọi một mẫu với get_template_part()(hoặc locate_template()) là có một cách để biết bạn đang ở trong mẫu nào.

Ví dụ: nếu bạn gọi get_template_part('loop','archive');từarchive.php

và sau đó đang làm việc trong tệp loop-archive.php của bạn. Có cách nào để xác định một biến có tên của phần mẫu hiện tại .... vì vậy $template = 'loop-archive'. tốt hơn nữa, có thể trong hai phần nên 'vòng lặp' và 'lưu trữ' nhưng tôi có thể làm điều đó với một số phân tách chuỗi.

Câu hỏi # 10537 có vẻ như có liên quan nhưng dường như không bao gồm các phần mẫu .

Câu trả lời:


2

Không có một biến toàn cầu cốt lõi nào trả về bối cảnh hiện tại. Tuy nhiên, bạn có thể tự xây dựng, sử dụng các thẻ điều kiện mẫu theo ngữ cảnh . Bạn có thể bước qua các thẻ có điều kiện theo cùng thứ tự với lõi WordPress, bằng cách làm theo wp-includes/template-loader.php.

Chỉ cần bọc đầu ra của bạn trong một chức năng Theme tùy chỉnh. Đây là cách tôi làm điều đó (lưu ý: Tôi không nghĩ rằng tôi tuân thủ nghiêm ngặt theo mẫu-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;
}

Sau đó, tôi chỉ truyền oenology_get_context()như một tham số, ví dụ:

get_template_part( 'loop', oenology_get_context() );

Tôi nghĩ rằng một cái gì đó dọc theo những dòng này sẽ là một ứng cử viên tốt cho cốt lõi, mặc dù tôi không chắc chắn cách tốt nhất để thực hiện. Tôi muốn gửi một bản vá, mặc dù.


wow chip. Điều đó rất, rất lắt léo. và trường hợp sử dụng của bạn là chính xác những gì tôi đã dự định. xa như một bản vá, tại sao bạn không đăng ký toàn cầu này cùng lúc bạn đang bước qua trình tải mẫu?
đạp xe vào

1
Bởi vì tôi không chắc chắn nếu thêm một toàn cầu khác sẽ là cách tiếp cận "may mắn" cho cốt lõi. Có lẽ một hàm trả về bối cảnh dưới dạng một chuỗi sẽ tốt hơn - nhưng sau đó, có lẽ sẽ cần một chút viết lại template-loader.php.
Chip Bennett

Đẹp +1. Chỉ cần một lưu ý: indexsẽ không bao giờ khớp, vì một trong hai is_front_page()hoặc is_home()sẽ kích hoạt.
kaiser

1
Một điều nữa: is_home()nên là đầu tiên, vì nó trả lại front-pagengay cả khi cài đặt "bài đăng mới nhất" được kích hoạt và không có trang nhất nào xuất hiện. Chỉ cần thử nghiệm.
kaiser

Đồng ý với @kaiser. Bạn thậm chí có thể sử dụng is_home() && 'page', tùy thuộc vào nhu cầu. Để biết thêm thông tin về Bài viết Blog và Trang tĩnh trong Trang trước, hãy xem câu trả lời của riêng tôi, tại đây: wordpress.stackexchange.com/questions/208503/ . BTW, @Chip và @helgatheviking, tốt hơn nên sử dụng sử dụng switchthay vì rất nhiều elseif(hiệu quả hơn ;-). Trân trọng!
Gerard

4

một chút của một facepalm, bởi vì câu trả lời là trong PHP thuần túy

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

2

Nếu bạn nhìn vào mã nguồn của get_template_parthàm, bạn sẽ thấy:

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);
}

Nó tạo ra một mảng gồm 2 tên mẫu: {$slug}-{$name}.php{$slug}.phpsử dụng load_templateđể tìm tệp mẫu và bao gồm nó (tham số thứ 2 là true, có nghĩa là bao gồm tệp đó).

Bạn có thể bắt chước hàm này để trả về đường dẫn tệp mẫu thay vì bao gồm nó, như:

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);
}

Sử dụng:

// 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 );

Bạn có thể chơi nhiều hơn $templateđể có được những gì bạn muốn.


Điều đó khá gọn gàng! Chắc chắn +1, nhưng tôi cần biết thông tin mẫu $ bên trong mẫu loop-arhive.php (để làm theo ví dụ của bạn)
helgatheviking

Bạn có thể sử dụng biến toàn cục được đặt archive.phpvà sử dụng lại trongloop-archive.php
Anh Tran

2

Liệt kê tất cả các điều kiện true

Vì tất cả các is_*()hàm có tương đương trong một biến truy vấn (các hàm chỉ là hàm bao), bạn cũng có thể truy cập chúng theo một cách khác: Nhận đơn giản tất cả những gì đang có true.

Tôi đã viết một vé trên core / trac có thêm chức năng liệt kê tất cả.

Trong khi đó, bạn có thể sử dụng cả hai chức năng được liệt kê dưới dạng bổ trợ trợ giúp cho bạn biết yêu cầu nào có điều kiện. Nó sẽ in một var_dump()chân trang bên dưới (cả quản trị viên & công khai) tại shutdownhook.

<?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' );

Bằng cách này bạn có thể chỉ cần lặp qua chúng.

@ fouu đã thêm chức năng của mình vào vé (một giải pháp thú vị nữa).

   

<?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' );

Hiệu suất

Tôi đã chạy thử nghiệm hiệu năng trên từng chức năng ở giữa một mẫu bằng cách sử dụng timer_start/*_stop();. Để công bằng, tôi đã đổi tên tất cả các chức năng thành một tên nhân vật a/b/c().

Như bạn có thể thấy, chức năng mã hóa cứng của Chips là nhanh nhất, sau đó là của tôi và cuối cùng là trong trường hợp này là scribus.

nhập mô tả hình ảnh ở đây

Cập nhật

Nếu bạn biết tôi, thì bạn sẽ biết tình yêu của tôi dành cho các trình vòng lặp vì sự thanh lịch, rõ ràng và khả năng của họ chỉ giữ một mục duy nhất trong bộ nhớ thay vì sao chép toàn bộ một mảng trong khi lặp. Vì vậy, đây là một lớp tùy chỉnh nhanh mở rộng một \FilterIterator, do đó chỉ cần một phương thức duy nhất được làm lại.

<?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
            );
    }
}

Nó có thể được sử dụng khá dễ dàng. Các $it->current()giữ giá trị, trong khi $it->key()lợi nhuận tên có điều kiện / tài sản.

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

1
Vâng, đó là rất thông minh. Cảm ơn! Tôi sẽ phải truy cập lại điều này khi tôi hoàn thành một số điều khác mà tôi đang làm việc. Ngoài ra, thật khó để nhớ để tận dụng! Thói quen xấu là khó phá vỡ.
xe đạp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.