GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-gamajo-template-loader.php
Go to the documentation of this file.
1 <?php
2 /**
3  * Template Loader for Plugins.
4  *
5  * @package Gamajo_Template_Loader
6  * @author Gary Jones
7  * @link http://github.com/GaryJones/Gamajo-Template-Loader
8  * @copyright 2013 Gary Jones
9  * @license GPL-2.0-or-later
10  * @version 1.3.2-gv-internal
11  */
12 
13 namespace GV;
14 
15 if ( ! class_exists( '\GV\Gamajo_Template_Loader' ) ) {
16 
17  /**
18  * Template loader.
19  *
20  * Originally based on functions in Easy Digital Downloads (thanks Pippin!).
21  *
22  * When using in a plugin, create a new class that extends this one and just overrides the properties.
23  *
24  * @package Gamajo_Template_Loader
25  * @author Gary Jones
26  */
28  /**
29  * Prefix for filter names.
30  *
31  * @since 1.0.0
32  *
33  * @var string
34  */
35  protected $filter_prefix = 'your_plugin';
36 
37  /**
38  * Directory name where custom templates for this plugin should be found in the theme.
39  *
40  * For example: 'your-plugin-templates'.
41  *
42  * @since 1.0.0
43  *
44  * @var string
45  */
46  protected $theme_template_directory = 'plugin-templates';
47 
48  /**
49  * Reference to the root directory path of this plugin.
50  *
51  * Can either be a defined constant, or a relative reference from where the subclass lives.
52  *
53  * e.g. YOUR_PLUGIN_TEMPLATE or plugin_dir_path( dirname( __FILE__ ) ); etc.
54  *
55  * @since 1.0.0
56  *
57  * @var string
58  */
59  protected $plugin_directory = 'YOUR_PLUGIN_DIR';
60 
61  /**
62  * Directory name where templates are found in this plugin.
63  *
64  * Can either be a defined constant, or a relative reference from where the subclass lives.
65  *
66  * e.g. 'templates' or 'includes/templates', etc.
67  *
68  * @since 1.1.0
69  *
70  * @var string
71  */
72  protected $plugin_template_directory = 'templates';
73 
74  /**
75  * Internal use only: Store variable names used for template data.
76  *
77  * Means unset_template_data() can remove all custom references from $wp_query.
78  *
79  * Initialized to contain the default 'data'.
80  *
81  * @var array
82  */
83  private $template_data_var_names = array( 'data' );
84 
85  /**
86  * @var array $file_paths A list of file paths to check when generating template paths.
87  *
88  * @since 1.3.2-gv-internal
89  */
90  private $file_paths = array();
91 
92  /**
93  * Clean up template data.
94  *
95  * @since 1.2.0
96  */
97  public function __destruct() {
98  $this->unset_template_data();
99  }
100 
101  /**
102  * Retrieve a template part.
103  *
104  * @since 1.0.0
105  *
106  * @param string $slug Template slug.
107  * @param string $name Optional. Template variation name. Default null.
108  * @param bool $load Optional. Whether to load template. Default true.
109  * @return string
110  */
111  public function get_template_part( $slug, $name = null, $load = true ) {
112  // Execute code for this part.
113  do_action( 'get_template_part_' . $slug, $slug, $name );
114  do_action( $this->filter_prefix . '_get_template_part_' . $slug, $slug, $name );
115 
116  // Get files names of templates, for given slug and name.
117  $templates = $this->get_template_file_names( $slug, $name );
118 
119  // Return the part that is found.
120  return $this->locate_template( $templates, $load, false );
121  }
122 
123  /**
124  * Make custom data available to template.
125  *
126  * Data is available to the template as properties under the `$data` variable.
127  * i.e. A value provided here under `$data['foo']` is available as `$data->foo`.
128  *
129  * When an input key has a hyphen, you can use `$data->{foo-bar}` in the template.
130  *
131  * @since 1.2.0
132  *
133  * @param mixed $data Custom data for the template.
134  * @param string $var_name Optional. Variable under which the custom data is available in the template.
135  * Default is 'data'.
136  * @return Gamajo_Template_Loader
137  */
138  public function set_template_data( $data, $var_name = 'data' ) {
139  global $wp_query;
140 
141  $wp_query->query_vars[ $var_name ] = (object) $data;
142 
143  // Add $var_name to custom variable store if not default value.
144  if ( 'data' !== $var_name ) {
145  $this->template_data_var_names[] = $var_name;
146  }
147 
148  return $this;
149  }
150 
151  /**
152  * Remove access to custom data in template.
153  *
154  * Good to use once the final template part has been requested.
155  *
156  * @since 1.2.0
157  *
158  * @return Gamajo_Template_Loader
159  */
160  public function unset_template_data() {
161  global $wp_query;
162 
163  // Remove any duplicates from the custom variable store.
164  $custom_var_names = array_unique( $this->template_data_var_names );
165 
166  // Remove each custom data reference from $wp_query.
167  foreach ( $custom_var_names as $var ) {
168  if ( isset( $wp_query->query_vars[ $var ] ) ) {
169  unset( $wp_query->query_vars[ $var ] );
170  }
171  }
172 
173  return $this;
174  }
175 
176  /**
177  * Given a slug and optional name, create the file names of templates.
178  *
179  * @since 1.0.0
180  *
181  * @param string $slug Template slug.
182  * @param string $name Template variation name.
183  * @return array
184  */
185  protected function get_template_file_names( $slug, $name ) {
186  $templates = array();
187  if ( isset( $name ) ) {
188  $templates[] = $slug . '-' . $name . '.php';
189  }
190  $templates[] = $slug . '.php';
191 
192  /**
193  * Allow template choices to be filtered.
194  *
195  * The resulting array should be in the order of most specific first, to least specific last.
196  * e.g. 0 => recipe-instructions.php, 1 => recipe.php
197  *
198  * @since 1.0.0
199  *
200  * @param array $templates Names of template files that should be looked for, for given slug and name.
201  * @param string $slug Template slug.
202  * @param string $name Template variation name.
203  */
204  return apply_filters( $this->filter_prefix . '_get_template_part', $templates, $slug, $name );
205  }
206 
207  /**
208  * Retrieve the name of the highest priority template file that exists.
209  *
210  * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
211  * inherit from a parent theme can just overload one file. If the template is
212  * not found in either of those, it looks in the theme-compat folder last.
213  *
214  * @since 1.0.0
215  *
216  * @param string|array $template_names Template file(s) to search for, in order.
217  * @param bool $load If true the template file will be loaded if it is found.
218  * @param bool $require_once Whether to require_once or require. Default true.
219  * Has no effect if $load is false.
220  * @return string The template filename if one is located.
221  */
222  public function locate_template( $template_names, $load = false, $require_once = true ) {
223  static $template_path_cache = array();
224 
225  // Generate a fast hash of the template names for unique lookup
226  $cache_key = md5( json_encode( $template_names ) );
227 
228  // If the key is in the cache array, we've already located this file.
229  if ( isset( $template_path_cache[ $this->filter_prefix ][ $cache_key ] ) ) {
230  $located = $template_path_cache[ $this->filter_prefix ][ $cache_key ];
231  } else {
232  // No file found yet.
233  $located = false;
234 
235  // Remove empty entries.
236  $template_names = array_filter( (array) $template_names );
237  $template_paths = $this->get_template_paths();
238 
239  // Try to find a template file.
240  foreach ( $template_names as $template_name ) {
241  // Trim off any slashes from the template name.
242  $template_name = ltrim( $template_name, '/' );
243 
244  // Try locating this template file by looping through the template paths.
245  foreach ( $template_paths as $template_path ) {
246  if ( file_exists( $template_path . $template_name ) ) {
247  $located = $template_path . $template_name;
248  // Store the template path in the cache.
249  $template_path_cache[ $this->filter_prefix ][ $cache_key ] = $located;
250  break 2;
251  }
252  }
253  }
254 
255  // The templates weren't found; don't look this up again.
256  if( ! $located ) {
257  $template_path_cache[ $this->filter_prefix ][ $cache_key ] = false;
258  }
259  }
260 
261  if ( $load && $located ) {
262  load_template( $located, $require_once );
263  }
264 
265  return $located;
266  }
267 
268  /**
269  * Return a list of paths to check for template locations.
270  *
271  * Default is to check in a child theme (if relevant) before a parent theme, so that themes which inherit from a
272  * parent theme can just overload one file. If the template is not found in either of those, it looks in the
273  * theme-compat folder last.
274  *
275  * @since 1.0.0
276  *
277  * @return mixed|void
278  */
279  protected function get_template_paths() {
280 
281  if ( ! empty( $this->file_paths ) ) {
282  return $this->file_paths;
283  }
284 
285  $theme_directory = trailingslashit( $this->theme_template_directory );
286 
287  $file_paths = array(
288  10 => trailingslashit( get_template_directory() ) . $theme_directory,
289  100 => $this->get_templates_dir(),
290  );
291 
292  // Only add this conditionally, so non-child themes don't redundantly check active theme twice.
293  if ( get_stylesheet_directory() !== get_template_directory() ) {
294  $file_paths[1] = trailingslashit( get_stylesheet_directory() ) . $theme_directory;
295  }
296 
297  /**
298  * Allow ordered list of template paths to be amended.
299  *
300  * @since 1.0.0
301  *
302  * @param array $var Default is directory in child theme at index 1, parent theme at 10, and plugin at 100.
303  */
304  $file_paths = apply_filters( $this->filter_prefix . '_template_paths', $file_paths );
305 
306  // Sort the file paths based on priority.
307  ksort( $file_paths, SORT_NUMERIC );
308 
309  $file_paths = array_map( 'trailingslashit', $file_paths );
310 
311  $this->file_paths = $file_paths;
312 
313  return $this->file_paths;
314  }
315 
316  /**
317  * Return the path to the templates directory in this plugin.
318  *
319  * May be overridden in subclass.
320  *
321  * @since 1.0.0
322  *
323  * @return string
324  */
325  protected function get_templates_dir() {
326  return trailingslashit( $this->plugin_directory ) . $this->plugin_template_directory;
327  }
328  }
329 }
Template Loader for Plugins.
$templates