3

I have a plugin with multiple php files. I want to load some of them only when specific template files are loaded. I don't want to load everything.

Currently, I'm doing it with add_action( 'wp', 'load_files' ) , but it means actions defined in the additional php files are not being done. Any ideas?

EDIT: Seems like there is some of work around, by getting the id from the url, like this What's the earliest point I can get the queried object ID?

I still don't know if there is any option to work from the WP functions, as this way is not my preferred way

  • how about using include_once in the template itself? – majick Aug 2 '16 at 12:30
  • @majick But then the actions will not be loaded – eddr Aug 2 '16 at 13:16
  • right you are but see my answer for a way around that. – majick Aug 2 '16 at 13:51
0

I think you have a bit of mixing up in different purposes to file includes, which are normally separated in modern PHP development: definitions and runtime code.

Definitions

Files that include definitions (such as classes and functions) should not contain runtime (immediately executing) code. That makes safe them to include early (quite optimized operation in proper PHP stack, more so with opcode caching) or lazily (class autoload).

Runtime code bootstrap

In WordPress context it is normal practice to stagger runtime code in following way:

  1. As soon as your extension loads you hook logic to init hook and that's all (with some variations for more specific needs).
  2. When init hook fires, your logic further hooks necessary actions to appropriate hooks.

Overall

Includes are just a poor mechanism to implement timing and logic with.

Their role should be limited to load process and further actions should be handled with appropriate event system (hooks in WP case).

  • Thanks. I'm missing something. I generally understand what you are saying, but not really and also not the definitions you are talking about: 1. hooking logic to 'init', what do you mean? what's my logic? 2. When 'init' fires, I still don't have the necessary data (like the post_type) in order to add the appropriate actions. 3. I understand the separation of definitions files and runtime code. However, for some runtime code, I need to load the definitions code. I don't want to load definitions files if it's not necessary for the specific page, but I don't have this info in time – eddr Aug 2 '16 at 23:00
  • (1) you hook to init a callback which does rest of the setup (as opposed to running setup immediately on load) (2) then when you reach init you hook again to the point that is late enough to have required context (3) as per answer this isn't really something to worry about much in modern PHP – Rarst Aug 2 '16 at 23:08
  • (3) So, I should just load all the files and that's it? (1)+(2): In this earliest point (to the best of my knowledge), I want to load the additional php file, but, at this point the hooks that I'm interested in have already fired (the ajax privileges hooks) Sorry for the headache.. Is there anywhere a full hook flow? – eddr Aug 2 '16 at 23:24
  • Yes, for definition files you should just load them or let autoload do it. It's hard to advise on specific hooks, there are a lot of them. There are questions on stack about boot process and timing, search around. – Rarst Aug 3 '16 at 8:28
-1

If you did want to use include_once in the template files, you could preload them by buffering the output of template-loader.php early. This way the files would be included the first time and the template would output as standard.

The advantage is you can keep track of what is included directly in the templates themselves rather than having to keep a separate index to match actions and templates.

add_action('init','preload_template_includes');
function preload_template_includes() {
    ob_start();
    require_once( ABSPATH . WPINC . '/template-loader.php' );
    ob_end_clean();
}

Note: not sure that init hook is the earliest but is usually sufficient... setup_theme or after_setup_theme are other possibilities.

EDIT If you are concerned about performance issues loading the template twice, you can add some extra logic at the top of the template where the includes are run to handle the conditional loading of the template itself OR it's includes. eg.

// list of relevant includes files
$includes = array(
    dirname(__FILE__).'/template-functions1.php', 
    dirname(__FILE__).'/template-functions2.php'
); 
$included = get_included_files(); $doneincludes = false;
foreach ($includes as $include) {
    if (!in_array($include,$included)) {include($include); $doneincludes = true;}
}
if ($doneincludes) {return;}
...the Template itself...

EDIT2 Sorry I missed you were wanting to do this in a plugin, the above is more an approach for theme development... Try something like this:

add_filter('template_include','myplugin_template_preload_check');
function myplugin_template_preload_check($template) {
    global $pluginpreload; 
    // so is run only the first time
    if ( (isset($pluginpreload)) && ($pluginpreload) ) {return;}

    $templatefile = basename($template);
    $templatefunctions = MYPLUGINDIR.'/template-functions/'.$templatefile;
    if (file_exists($templatefunctions)) {include($templatefunctions);}

    $pluginpreload = true;
    // do not actually process the template
    return false;                
}

add_action('init','myplugin_preload_templates');
function myplugin_preload_templates() {
    ob_start();
    require_once( ABSPATH . WPINC . '/template-loader.php' );
    ob_end_clean();
}

This way you could match your included functions in the plugin to the template used by matching the template name.

  • Thanks! But then all the PHP files are loaded, right? – eddr Aug 2 '16 at 14:39
  • the template file will be processed twice but that should have minimal impact on the pageload. i am not sure what you mean by "all", the idea is to just include the relevant files for the specific template isn't it? – majick Aug 2 '16 at 16:21
  • Processing template twice might have enormous impact on pageload. In any properly optimized WP site the core/extensions load time would be kept to a minimum and template (actual point of the page) would be relatively significant. – Rarst Aug 2 '16 at 18:10
  • @Rarst yes but might is the operative word there, for the majority of themes the template file is actually very minimal (compared to say, loading the theme itself) and reprocessing it would have almost zero impact... besides - if needed - it would be simple enough to add something extra at the top to detect whether it is the first or second load and process the actual template or just the includes. again I believe the advantage of being able to keep track of includes directly in the template in this solution would far outweigh the possible disadvantages. – majick Aug 4 '16 at 2:33
  • I've added an example of how to do that to the answer if one wants to avoid that possible drawback. – majick Aug 4 '16 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.