WordPress.org

Make WordPress Core

#23180 closed feature request (duplicate)

Introduce get_plugin_part

Reported by: wonderboymusic Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Plugins Keywords: dev-feedback
Focuses: Cc:

Description

To anyone who uses "plugins" to package components that contain UI elements, this might be a no-brainer. Themes have a dead simple way of loading template parts from anywhere without having to resolve paths: get_template_part(). Because the arguments passed are arbitrary strings, it's easy to reference templates in deep directories by doing get_template_part( 'artist/reviews', 'main' ) and the like.

This is all well and good, but it would awesome to be able to grab "template parts" from plugins as well, from anywhere, without having to resolve path dependencies on your own.

I attempt to solve this with get_plugin_part()

Example for a plugin called JJJ, which has a template called cat-meow.php in a folder called views:

get_plugin_part( 'jjj', 'views/cat', 'meow' );

Attachments (1)

get-plugin-part.diff (1.9 KB) - added by wonderboymusic 15 months ago.

Download all attachments as: .zip

Change History (15)

comment:1 wonderboymusic15 months ago

  • Type changed from defect (bug) to feature request

comment:2 johnbillion15 months ago

Some possible improvements:

  • Make the $plugin parameter the last parameter of the function, make it optional, and default it to the base plugin directory of the current file.
  • Add $plugin to the parameters passed to the get_plugin_part_{$slug} hook. Maybe even change it to get_plugin_part_{$plugin}_{$slug}.

comment:3 johnbillion15 months ago

You know what, I'm not sure if this function would be much use at all without being able to pass variables into the scope that the template file is included. get_template_part() suffers from the same issue. See #21676.

comment:4 wonderboymusic15 months ago

I just fired this off quickly to see if Sergey would close it because it had already been suggested elsewhere. The filter needs to change to your suggestion for sure.

I have tons of use cases where this helps my giant codebase. The arguments thing is present for ANY function in PHP that doesn't let you directly inject data. get_*_part functions IMO only serve two purposes:

  • resolve paths magically
  • make UI elements modular

Any scope issue can be resolved via globals, template tags, or getter functions. B*Press plugins use one global variable each to store retrievable data code like:

bp()->irrationally_long_variable_name_or_methodor_filter etc

comment:5 tarasm15 months ago

  • Cc tarasm@… added

+1 for this suggestion.

A few days ago, I wrote a plugin that provides a library that does the same thing.

https://github.com/wrktg/scaleup-templates

If this was possible in WordPress then my code would be unnecessary for this purpose.

comment:6 kovshenin15 months ago

  • Cc kovshenin added

I think we're missing the whole point of get_template_part here. It's not just an alias for require, it's the whole child-parent model which allows you to define fallback templates. Unless plugins can adopt a similar model, I don't see any value in creating a wrapper function over require, besides, if you want someone to be able to override the included template in your plugin, just pass it through a filter:

require( apply_filters( 'jjj_cat_meow_view', dirname( __FILE__ ) . '/views/cat-meow.php' ) );

comment:7 follow-up: tarasm15 months ago

@kovshenin, @wonderboymusic I originally misread this ticket.

I don't like the idea of introducing another function(get_plugin_part), instead it would be helpful if it was possible for plugin developer to register templates from plugin with get_template_part.

@kovshenin your suggestion requires theme developer to know what filter he/she must apply to overwrite plugin's path. This is an extra step that could be take care of by get_template_part.

What do you think?

comment:8 in reply to: ↑ 7 kovshenin15 months ago

Replying to tarasm:

@kovshenin your suggestion requires theme developer to know what filter he/she must apply to overwrite plugin's path. This is an extra step that could be take care of by get_template_part.

That's true, but the proposed patch is no different. In fact it doesn't allow you to filter it at all :) In any case, even if the plugin used get_plugin_part you'd still have to look at the plugin code to see what the values and file names are passed to the function if you want to filter them. I think it just makes it even more confusing :)

comment:9 tarasm15 months ago

@kovshenin its true that it might necessary to look into plugins directory to figure out the paths but it can be done in a way that's not confusing.

For example: if templates went into templates directory then you'd just have to follow directory structure thats in the plugin.

To load template thats located at /wp-content/plugins/someplugin/templates/template1.php, themer would use code

get_template_part( 'templates1')

If its located in subdirectory, /wp-content/plugins/someplugin/templates/directory/template1.php, the themer would use

get_template_part( 'directory/template1')

Would you like me to propose a patch to this effect?

comment:10 kovshenin15 months ago

I don't think that limiting the function to a directory structure is a good solution.

comment:11 tarasm15 months ago

@kovshnin I'm not suggesting to limit the functionality to the directory structure. I showed the path to show how a themer might learn about what templates are available. If by convention, the templates are in plugin's templates directory then it will be the first place that the themer would go to.

comment:12 DrewAPicture15 months ago

This almost sounds like what @johnjamesjacoby proposed in #22355

comment:13 tarasm15 months ago

@DrewAPicture good catch its very similar and would work. It looks like they're much further along then we are.

comment:14 DrewAPicture15 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #22355.

Note: See TracTickets for help on using tickets.