WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 5 months ago

#43597 new enhancement

Modify template-loader engine

Reported by: chespir Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Themes Keywords:
Focuses: template Cc:
PR Number:

Description

Hi, I think it would be useful if the functionality of the template-loader.php file that determines the template to load were added directly to the template_include filter with priority 1, so that it will be accessible using a function.
I have found the need in some projects in which I load the WordPress core from an external application, since once the core is loaded, it is necessary to include the template_loader.php file and it is not possible just to obtain which would be the template to load (and not ley ir load).

Change History (8)

#1 @SergeyBiryukov
2 years ago

  • Component changed from General to Themes
  • Focuses template added
  • Summary changed from Modifiy template-loader engine to Modify template-loader engine

#2 @soulseekah
2 years ago

  • Keywords reporter-feedback added

Hi, @chespir! Welcome to Trac! Thank you for your report. I'm sorry it took so long for someone to respond.

The template_include filter and the template_redirect action will not be pulled if WP_USE_THEMES is not defined. WP_USE_THEMES is only defined by default if you load index.php, i.e. it is a frontend request. The absence of WP_USE_THEMES allows wp-load.php to be included without any output produced. If you define WP_USE_THEMES inside the init action, for example, the core will produce theme output. This is in most cases undesirable.

What is your specific use case and proposed solution here?

Thanks!

#3 @chespir
2 years ago

  • Keywords reporter-feedback removed

Hi @soulseekah , thanks for your answer and do not worry about the delay.
I understand what you are saying about using WP_USE_THEMES to not get an answer as it is obtained in a frontend request.
In my case, I'm using a script (a .php file) that gets some parameters through an AJAX call. I use these parameters to set the global wp_query so that I can tell Wordpress that I am, for example, in a single or archive.
If I don't set WP_USE_THEMES, Wordpress will not load my single.php, but if I set WP_USE_THEMES it will load single.php.

Now, what I need in my script is to generate some variables that I want to get to the template that Wordpress is going to load, which is possible if I could get the template that Wordpress is going to load and I could load it myself with an include, just like the Wordpress core does right now. It should be noted that I try to avoid the use of global.

I think this could be fixed if I could access the Wordpress template decision, which is made before the template_include filter through a function. I also think this option would add versatility to the loading of the Wordpress core.

My proposed solution would be something like following lines.

<?php
//Function to decide which template will Wordpress load
function wordpress_decission_template(){
        $template = false;
        if     ( is_embed()          && $template = get_embed_template()          ) :
        elseif ( is_404()            && $template = get_404_template()            ) :
        elseif ( is_search()         && $template = get_search_template()         ) :
        elseif ( is_front_page()     && $template = get_front_page_template()     ) :
        elseif ( is_home()           && $template = get_home_template()           ) :
        elseif ( is_post_type_archive() && $template = get_post_type_archive_template() ) :
        elseif ( is_tax()            && $template = get_taxonomy_template()       ) :
        elseif ( is_attachment()     && $template = get_attachment_template()     ) :
                remove_filter('the_content', 'prepend_attachment');
        elseif ( is_single()         && $template = get_single_template()         ) :
        elseif ( is_page()           && $template = get_page_template()           ) :
        elseif ( is_singular()       && $template = get_singular_template()       ) :
        elseif ( is_category()       && $template = get_category_template()       ) :
        elseif ( is_tag()            && $template = get_tag_template()            ) :
        elseif ( is_author()         && $template = get_author_template()         ) :
        elseif ( is_date()           && $template = get_date_template()           ) :
        elseif ( is_archive()        && $template = get_archive_template()        ) :
        else :
                $template = get_index_template();
        endif;
        return $template;
}

//Load the template
$template = wordpress_decission_template();
if ( $template = apply_filters( 'template_include', $template ) ) {
        include( $template );
} elseif ( current_user_can( 'switch_themes' ) ) {
        $theme = wp_get_theme();
        if ( $theme->errors() ) {
                wp_die( $theme->errors() );
        }
}
?>

Then in my script I would call the wordpress_decission_template function, then I would set my desired variables, and I would include the template.

Thank you very much.

#4 @soulseekah
2 years ago

@chespir Thanks for the explanation!

It seems to me that you should be using WP_USE_THEMES in your a.php script and create two hooks on in the template_redirect action, so you can set you WP_Query parameters, and the other in template_include filter so you can see what core is about to load and override if needed.

Would this not solve your issue?

#5 @SergeyBiryukov
5 months ago

Related: #48175, #16128.

Last edited 5 months ago by SergeyBiryukov (previous) (diff)

#6 follow-up: @dhurlburtusa
5 months ago

Note: The proposed solution here is very similar to the one in #48175. The difference being that there is a filter named template_resolution_algorithm which runs the default template hierarchy algorithm as the template resolution algorithm (TRA). The benefit being that one can easily override the TRA. It also encapsulates the current template hierarchy algorithm in a function which could be used else where. It could even be used in the custom TRA depending on the request.

#7 in reply to: ↑ 6 @chespir
5 months ago

Replying to dhurlburtusa:

Note: The proposed solution here is very similar to the one in #48175. The difference being that there is a filter named template_resolution_algorithm which runs the default template hierarchy algorithm as the template resolution algorithm (TRA). The benefit being that one can easily override the TRA. It also encapsulates the current template hierarchy algorithm in a function which could be used else where. It could even be used in the custom TRA depending on the request.

Just to join criteria

I suggested in first post of this topic to add TRA to the template_include filter with priority 1 so that you can remove_filter and add your own algorithm. Similar to your nice example.
Wrapping TRA in a function may also be helpfull when you need to invoke WordPress TRA (or your own algorithm) when you need.

I think the issues we are talking about are:

  1. To wrap WordPress TRA in a function
  2. To be able to let Wordpress to use its own TRA (the function in point one) or other algorithm. Like this, point 1 and 2 would let you build a theme with an MVC-like architecture as you also mentioned
  3. As a consequence of the previous point, there would be a filter in which would be hooked the default Wordpress TRA. In this way, point two would be possible
Last edited 5 months ago by chespir (previous) (diff)

#8 @apedog
5 months ago

+1 to this (or the solution in #48175)
I think this ticket can get some attention alongside #41362 and https://github.com/WordPress/gutenberg/issues/17512

Note: See TracTickets for help on using tickets.