Custom Post Template - Version 0.9b

Version Description

Download this release

Release Info

Developer simonwheatley
Plugin Icon wp plugin Custom Post Template
Version 0.9b
Comparing to
See all releases

Version 0.9b

custom-post-templates.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Custom Post Templates
4
+ Plugin URI: http://wordpress.org/extend/plugins/custom-post-template/
5
+ Description: Provides a drop-down to select different templates for posts from the post edit screen. The templates are defined similarly to page templates, and will replace single.php for the specified post.
6
+ Author: Simon Wheatley
7
+ Version: 0.9b
8
+ Author URI: http://simonwheatley.co.uk/wordpress/
9
+ */
10
+
11
+ /* Copyright 2008 Simon Wheatley
12
+
13
+ This program is free software; you can redistribute it and/or modify
14
+ it under the terms of the GNU General Public License as published by
15
+ the Free Software Foundation; either version 2 of the License, or
16
+ (at your option) any later version.
17
+
18
+ This program is distributed in the hope that it will be useful,
19
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ GNU General Public License for more details.
22
+
23
+ You should have received a copy of the GNU General Public License
24
+ along with this program; if not, write to the Free Software
25
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
+
27
+ */
28
+
29
+ require_once( dirname (__FILE__) . '/plugin.php' );
30
+
31
+ /**
32
+ *
33
+ * @package default
34
+ * @author Simon Wheatley
35
+ **/
36
+ class CustomPostTemplates extends CustomPostTemplates_Plugin
37
+ {
38
+ private $tpl_meta_key = 'custom_post_template';
39
+ private $post_ID;
40
+
41
+ function __construct()
42
+ {
43
+ $this->register_plugin ( 'post-templates', __FILE__ );
44
+ $this->add_meta_box( 'select_post_template', __('Post Template'), 'select_post_template', 'post', 'normal', 'core' );
45
+ $this->add_action( 'save_post' );
46
+ $this->add_filter( 'single_template', 'filter_single_template' );
47
+ }
48
+
49
+ /*
50
+ * FILTERS & ACTIONS
51
+ * *******************
52
+ */
53
+
54
+ public function select_post_template( $post )
55
+ {
56
+ $this->post_ID = $post->ID;
57
+
58
+ $template_vars = array();
59
+ $template_vars[ 'templates' ] = $this->get_post_templates();
60
+ $template_vars[ 'custom_template' ] = $this->get_custom_post_template();
61
+
62
+ // Render the template
63
+ $this->render_admin ( 'select_post_template', $template_vars );
64
+ }
65
+
66
+ public function save_post( $post_ID )
67
+ {
68
+ $action_needed = (bool) @ $_POST[ 'custom_post_template_present' ];
69
+ if ( ! $action_needed ) return;
70
+
71
+ $this->post_ID = $post_ID;
72
+
73
+ $template = (string) @ $_POST[ 'custom_post_template' ];
74
+ $this->set_custom_post_template( $template );
75
+ }
76
+
77
+ public function filter_single_template( $template )
78
+ {
79
+ global $wp_query;
80
+
81
+ $this->post_ID = $wp_query->post->ID;
82
+
83
+ $custom_template = TEMPLATEPATH . "/" . $this->get_custom_post_template();
84
+ if ( file_exists( $custom_template ) ) return $custom_template;
85
+
86
+ return $template;
87
+ }
88
+
89
+ /*
90
+ * UTILITY METHODS
91
+ * *****************
92
+ */
93
+
94
+ protected function set_custom_post_template( $template )
95
+ {
96
+ delete_post_meta( $this->post_ID, $this->tpl_meta_key );
97
+ if ( ! $template || $template == 'default' ) return;
98
+
99
+ add_post_meta( $this->post_ID, $this->tpl_meta_key, $template );
100
+ }
101
+
102
+ protected function get_custom_post_template()
103
+ {
104
+ $custom_template = get_post_meta( $this->post_ID, $this->tpl_meta_key );
105
+ // Seems to come out as an array. Irritating.
106
+ if ( is_array( $custom_template ) ) $custom_template = $custom_template[ 0 ];
107
+ return $custom_template;
108
+ }
109
+
110
+ protected function get_post_templates()
111
+ {
112
+ $themes = get_themes();
113
+ $theme = get_current_theme();
114
+ $templates = $themes[ $theme ][ 'Template Files' ];
115
+
116
+ $page_templates = array();
117
+
118
+ if ( is_array( $templates ) ) {
119
+ foreach ( $templates as $template ) {
120
+ $template_data = implode( '', file( WP_CONTENT_DIR . $template ) );
121
+
122
+ preg_match( '|Template Name Posts:(.*)$|mi', $template_data, $name );
123
+ if ( empty( $name ) ) continue;
124
+
125
+ $name = $name[ 1 ];
126
+
127
+ $page_templates[ trim( $name ) ] = basename( $template );
128
+ }
129
+ }
130
+
131
+ return $page_templates;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Instantiate the plugin
137
+ *
138
+ * @global
139
+ **/
140
+
141
+ $CustomPostTemplates = new CustomPostTemplates();
142
+
143
+ ?>
plugin.php ADDED
@@ -0,0 +1,676 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // ======================================================================================
4
+ // This library is free software; you can redistribute it and/or
5
+ // modify it under the terms of the GNU Lesser General Public
6
+ // License as published by the Free Software Foundation; either
7
+ // version 2.1 of the License, or (at your option) any later version.
8
+ //
9
+ // This library is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ // Lesser General Public License for more details.
13
+ // ======================================================================================
14
+ // @author John Godley (http://urbangiraffe.com)
15
+ // @version 0.1.25
16
+ // @copyright Copyright &copy; 2007 John Godley, All Rights Reserved
17
+ // ======================================================================================
18
+ // 0.1.6 - Corrected WP locale functions
19
+ // 0.1.7 - Add phpdoc comments
20
+ // 0.1.8 - Support for Admin SSL
21
+ // 0.1.9 - URL encoding, defer localization until init
22
+ // 0.1.10 - Better URL encoding
23
+ // 0.1.11 - Make work in WP 2.0, fix HTTPS issue on IIS
24
+ // 0.1.12 - Activation/deactivation actions that take into account the directory
25
+ // 0.1.13 - Add realpath function
26
+ // 0.1.14 - Add select/checked functions, fix locale loader
27
+ // 0.1.15 - Remove dependency on prototype
28
+ // 0.1.16 - Add support for homedir in realpath
29
+ // 0.1.17 - Added widget class
30
+ // 0.1.18 - Expand checked function
31
+ // 0.1.19 - Make url() cope with sites with no trailing slash
32
+ // 0.1.20 - Change init function to prevent overloading
33
+ // 0.1.21 - Make widget work for WP 2.1
34
+ // 0.1.22 - Make select work with option groups, RSS compatability fix
35
+ // 0.1.23 - Make widget count work better, fix widgets in K2
36
+ // 0.1.24 - Make realpath better
37
+ // 0.1.25 - Support for new WP2.6 config location
38
+ // ======================================================================================
39
+
40
+
41
+ /**
42
+ * Wraps up several useful functions for WordPress plugins and provides a method to separate
43
+ * display HTML from PHP code.
44
+ *
45
+ * <h4>Display Rendering</h4>
46
+ * The class uses a similar technique to Ruby On Rails views, whereby the display HTML is kept
47
+ * in a separate directory and file from the main code. A display is 'rendered' (sent to the browser)
48
+ * or 'captured' (returned to the calling function).
49
+ *
50
+ * Template files are separated into two areas: admin and user. Admin templates are only for display in
51
+ * the WordPress admin interface, while user templates are typically for display on the site (although neither
52
+ * of these are enforced). All templates are PHP code, but are referred to without .php extension.
53
+ *
54
+ * The reason for this separation is that one golden rule of plugin creation is that someone will always want to change
55
+ * the formatting and style of your output. Rather than forcing them to modify the plugin (bad), or modify files within
56
+ * the plugin (equally bad), the class allows user templates to be overridden with files contained within the theme.
57
+ *
58
+ * An additional benefit is that it leads to code re-use, especially with regards to Ajax (i.e. your display code can be called from
59
+ * many locations)
60
+ *
61
+ * Template files are located within the 'view' subdirectory of the plugins base (specified when registering the plugin):
62
+ *
63
+ * <pre>myplugin/view/admin
64
+ * myplugin/view/myplugin</pre>
65
+ *
66
+ * Admin templates are contained within 'admin', and user templates are contained within a directory of the same name as the plugin.
67
+ *
68
+ * User files can be overridden within the theme by creating a similar directory structure:
69
+ *
70
+ * <pre>/themes/mytheme/view/myplugin</pre>
71
+ *
72
+ * The class will first look in the theme and then defaults to the plugin. A plugin should always provide default templates.
73
+ *
74
+ * <h4>Display Parameters</h4>
75
+ * Also similar to Ruby On Rails, when you display a template you must supply the parameters that the template has access to. This tries
76
+ * to ensure a very clean separation between code and display. Parameters are supplied as an associative array mapping variable name to variable value.
77
+ *
78
+ * For example,
79
+ *
80
+ * array ('message' => 'Your data was processed', 'items' => 103);
81
+ *
82
+ * <h4>How it works in practice</h4>
83
+ * You create a template file to display how many items have been processed. You store this in 'view/admin/processed.php':
84
+ *
85
+ * <pre>&lt;p&gt;You processed &lt;?php echo $items ?&gt; items&lt;/p&gt;</pre>
86
+ *
87
+ * When you want to display this in your plugin you use:
88
+ *
89
+ * <pre> $this->render_admin ('processed', array ('items' => 100));
90
+ *
91
+ * @package WordPress base library
92
+ * @author John Godley
93
+ * @copyright Copyright (C) John Godley
94
+ **/
95
+
96
+ class CustomPostTemplates_Plugin
97
+ {
98
+ /**
99
+ * Plugin name
100
+ * @var string
101
+ **/
102
+ var $plugin_name;
103
+
104
+ /**
105
+ * Plugin 'view' directory
106
+ * @var string Directory
107
+ **/
108
+ var $plugin_base;
109
+
110
+
111
+ /**
112
+ * Register your plugin with a name and base directory. This <strong>must</strong> be called once.
113
+ *
114
+ * @param string $name Name of your plugin. Is used to determine the plugin locale domain
115
+ * @param string $base Directory containing the plugin's 'view' files.
116
+ * @return void
117
+ **/
118
+
119
+ function register_plugin ($name, $base)
120
+ {
121
+ $this->plugin_base = rtrim (dirname ($base), '/');
122
+ $this->plugin_name = $name;
123
+
124
+ $this->add_action ('init', 'load_locale');
125
+ }
126
+
127
+ function load_locale ()
128
+ {
129
+ // Here we manually fudge the plugin locale as WP doesnt allow many options
130
+ $locale = get_locale ();
131
+ if ( empty($locale) )
132
+ $locale = 'en_US';
133
+
134
+ $mofile = dirname (__FILE__)."/locale/$locale.mo";
135
+ load_textdomain ($this->plugin_name, $mofile);
136
+ }
137
+
138
+
139
+ /**
140
+ * Register a WordPress action and map it back to the calling object
141
+ *
142
+ * @param string $action Name of the action
143
+ * @param string $function Function name (optional)
144
+ * @param int $priority WordPress priority (optional)
145
+ * @param int $accepted_args Number of arguments the function accepts (optional)
146
+ * @return void
147
+ **/
148
+
149
+ function add_action ($action, $function = '', $priority = 10, $accepted_args = 1)
150
+ {
151
+ add_action ($action, array (&$this, $function == '' ? $action : $function), $priority, $accepted_args);
152
+ }
153
+
154
+
155
+ /**
156
+ * Register a WordPress filter and map it back to the calling object
157
+ *
158
+ * @param string $action Name of the action
159
+ * @param string $function Function name (optional)
160
+ * @param int $priority WordPress priority (optional)
161
+ * @param int $accepted_args Number of arguments the function accepts (optional)
162
+ * @return void
163
+ **/
164
+
165
+ function add_filter ($filter, $function = '', $priority = 10, $accepted_args = 1)
166
+ {
167
+ add_filter ($filter, array (&$this, $function == '' ? $filter : $function), $priority, $accepted_args);
168
+ }
169
+
170
+
171
+ /**
172
+ * Register a WordPress meta box
173
+ *
174
+ * @param string $id ID for the box, also used as a function name if none is given
175
+ * @param string $title Title for the box
176
+ * @param int $page WordPress priority (optional)
177
+ * @param string $function Function name (optional)
178
+ * @param string $context e.g. 'advanced' or 'core' (optional)
179
+ * @param int $priority Priority, rough effect on the ordering (optional)
180
+ * @return void
181
+ **/
182
+
183
+ function add_meta_box($id, $title, $function = '', $page, $context = 'advanced', $priority = 'default')
184
+ {
185
+ require_once( ABSPATH . 'wp-admin/includes/template.php' );
186
+ add_meta_box( $id, $title, array( &$this, $function == '' ? $id : $function ), $page, $context, $priority );
187
+ }
188
+
189
+ /**
190
+ * Special activation function that takes into account the plugin directory
191
+ *
192
+ * @param string $pluginfile The plugin file location (i.e. __FILE__)
193
+ * @param string $function Optional function name, or default to 'activate'
194
+ * @return void
195
+ **/
196
+
197
+ function register_activation ($pluginfile, $function = '')
198
+ {
199
+ add_action ('activate_'.basename (dirname ($pluginfile)).'/'.basename ($pluginfile), array (&$this, $function == '' ? 'activate' : $function));
200
+ }
201
+
202
+
203
+ /**
204
+ * Special deactivation function that takes into account the plugin directory
205
+ *
206
+ * @param string $pluginfile The plugin file location (i.e. __FILE__)
207
+ * @param string $function Optional function name, or default to 'deactivate'
208
+ * @return void
209
+ **/
210
+
211
+ function register_deactivation ($pluginfile, $function = '')
212
+ {
213
+ add_action ('deactivate_'.basename (dirname ($pluginfile)).'/'.basename ($pluginfile), array (&$this, $function == '' ? 'deactivate' : $function));
214
+ }
215
+
216
+
217
+ /**
218
+ * Renders an admin section of display code
219
+ *
220
+ * @param string $ug_name Name of the admin file (without extension)
221
+ * @param string $array Array of variable name=>value that is available to the display code (optional)
222
+ * @return void
223
+ **/
224
+
225
+ function render_admin ($ug_name, $ug_vars = array ())
226
+ {
227
+ global $plugin_base;
228
+ foreach ($ug_vars AS $key => $val)
229
+ $$key = $val;
230
+
231
+ if (file_exists ("{$this->plugin_base}/view/admin/$ug_name.php"))
232
+ include ("{$this->plugin_base}/view/admin/$ug_name.php");
233
+ else
234
+ echo "<p>Rendering of admin template {$this->plugin_base}/view/admin/$ug_name.php failed</p>";
235
+ }
236
+
237
+
238
+ /**
239
+ * Renders a section of user display code. The code is first checked for in the current theme display directory
240
+ * before defaulting to the plugin
241
+ *
242
+ * @param string $ug_name Name of the admin file (without extension)
243
+ * @param string $array Array of variable name=>value that is available to the display code (optional)
244
+ * @return void
245
+ **/
246
+
247
+ function render ($ug_name, $ug_vars = array ())
248
+ {
249
+ foreach ($ug_vars AS $key => $val)
250
+ $$key = $val;
251
+
252
+ if (file_exists (TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php"))
253
+ include (TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php");
254
+ else if (file_exists ("{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php"))
255
+ include ("{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php");
256
+ else
257
+ echo "<p>Rendering of template $ug_name.php failed</p>";
258
+ }
259
+
260
+
261
+ /**
262
+ * Renders a section of user display code. The code is first checked for in the current theme display directory
263
+ * before defaulting to the plugin
264
+ *
265
+ * @param string $ug_name Name of the admin file (without extension)
266
+ * @param string $array Array of variable name=>value that is available to the display code (optional)
267
+ * @return void
268
+ **/
269
+
270
+ function capture ($ug_name, $ug_vars = array ())
271
+ {
272
+ ob_start ();
273
+ $this->render ($ug_name, $ug_vars);
274
+ $output = ob_get_contents ();
275
+ ob_end_clean ();
276
+ return $output;
277
+ }
278
+
279
+
280
+ /**
281
+ * Captures an admin section of display code
282
+ *
283
+ * @param string $ug_name Name of the admin file (without extension)
284
+ * @param string $array Array of variable name=>value that is available to the display code (optional)
285
+ * @return string Captured code
286
+ **/
287
+
288
+ function capture_admin ($ug_name, $ug_vars = array ())
289
+ {
290
+ ob_start ();
291
+ $this->render_admin ($ug_name, $ug_vars);
292
+ $output = ob_get_contents ();
293
+ ob_end_clean ();
294
+ return $output;
295
+ }
296
+
297
+
298
+ /**
299
+ * Display a standard error message (using CSS ID 'message' and classes 'fade' and 'error)
300
+ *
301
+ * @param string $message Message to display
302
+ * @return void
303
+ **/
304
+
305
+ function render_error ($message)
306
+ {
307
+ ?>
308
+ <div class="fade error" id="message">
309
+ <p><?php echo $message ?></p>
310
+ </div>
311
+ <?php
312
+ }
313
+
314
+
315
+ /**
316
+ * Display a standard notice (using CSS ID 'message' and class 'updated').
317
+ * Note that the notice can be made to automatically disappear, and can be removed
318
+ * by clicking on it.
319
+ *
320
+ * @param string $message Message to display
321
+ * @param int $timeout Number of seconds to automatically remove the message (optional)
322
+ * @return void
323
+ **/
324
+
325
+ function render_message ($message, $timeout = 0)
326
+ {
327
+ ?>
328
+ <div class="updated" id="message" onclick="this.parentNode.removeChild (this)">
329
+ <p><?php echo $message ?></p>
330
+ </div>
331
+ <?php
332
+ }
333
+
334
+
335
+ /**
336
+ * Get the plugin's base directory
337
+ *
338
+ * @return string Base directory
339
+ **/
340
+
341
+ function dir ()
342
+ {
343
+ return $this->plugin_base;
344
+ }
345
+
346
+
347
+ /**
348
+ * Get a URL to the plugin. Useful for specifying JS and CSS files
349
+ *
350
+ * For example, <img src="<?php echo $this->url () ?>/myimage.png"/>
351
+ *
352
+ * @return string URL
353
+ **/
354
+
355
+ function url ($url = '')
356
+ {
357
+ if ($url)
358
+ return str_replace ('\\', urlencode ('\\'), str_replace ('&amp;amp', '&amp;', str_replace ('&', '&amp;', $url)));
359
+ else
360
+ {
361
+ $root = ABSPATH;
362
+ if (defined ('WP_PLUGIN_DIR'))
363
+ $root = WP_PLUGIN_DIR;
364
+
365
+ $url = substr ($this->plugin_base, strlen ($this->realpath ($root)));
366
+ if (DIRECTORY_SEPARATOR != '/')
367
+ $url = str_replace (DIRECTORY_SEPARATOR, '/', $url);
368
+
369
+ if (defined ('WP_PLUGIN_URL'))
370
+ $url = WP_PLUGIN_URL.'/'.ltrim ($url, '/');
371
+ else
372
+ $url = get_bloginfo ('wpurl').'/'.ltrim ($url, '/');
373
+
374
+ // Do an SSL check - only works on Apache
375
+ global $is_IIS;
376
+ if (isset ($_SERVER['HTTPS']) && !$is_IIS)
377
+ $url = str_replace ('http://', 'https://', $url);
378
+ }
379
+ return $url;
380
+ }
381
+
382
+ /**
383
+ * Performs a version update check using an RSS feed. The function ensures that the feed is only
384
+ * hit once every given number of days, and the data is cached using the WordPress Magpie library
385
+ *
386
+ * @param string $url URL of the RSS feed
387
+ * @param int $days Number of days before next check
388
+ * @return string Text to display
389
+ **/
390
+
391
+ function version_update ($url, $days = 7)
392
+ {
393
+ if (!function_exists ('fetch_rss'))
394
+ {
395
+ if (!file_exists (ABSPATH.'wp-includes/rss.php'))
396
+ return '';
397
+ include (ABSPATH.'wp-includes/rss.php');
398
+ }
399
+
400
+ $now = time ();
401
+
402
+ $checked = get_option ('plugin_urbangiraffe_rss');
403
+
404
+ // Use built-in Magpie caching
405
+ if (function_exists ('fetch_rss') && (!isset ($checked[$this->plugin_name]) || $now > $checked[$this->plugin_name] + ($days * 24 * 60 * 60)))
406
+ {
407
+ $rss = fetch_rss ($url);
408
+ if (count ($rss->items) > 0)
409
+ {
410
+ foreach ($rss->items AS $pos => $item)
411
+ {
412
+ if (isset ($checked[$this->plugin_name]) && strtotime ($item['pubdate']) < $checked[$this->plugin_name])
413
+ unset ($rss->items[$pos]);
414
+ }
415
+ }
416
+
417
+ $checked[$this->plugin_name] = $now;
418
+ update_option ('plugin_urbangiraffe_rss', $checked);
419
+ return $rss;
420
+ }
421
+ }
422
+
423
+
424
+ /**
425
+ * Version of realpath that will work on systems without realpath
426
+ *
427
+ * @param string $path The path to canonicalize
428
+ * @return string Canonicalized path
429
+ **/
430
+
431
+ function realpath ($path)
432
+ {
433
+ if (function_exists ('realpath'))
434
+ return realpath ($path);
435
+ else if (DIRECTORY_SEPARATOR == '/')
436
+ {
437
+ $path = preg_replace ('/^~/', $_SERVER['DOCUMENT_ROOT'], $path);
438
+
439
+ // canonicalize
440
+ $path = explode (DIRECTORY_SEPARATOR, $path);
441
+ $newpath = array ();
442
+ for ($i = 0; $i < sizeof ($path); $i++)
443
+ {
444
+ if ($path[$i] === '' || $path[$i] === '.')
445
+ continue;
446
+
447
+ if ($path[$i] === '..')
448
+ {
449
+ array_pop ($newpath);
450
+ continue;
451
+ }
452
+
453
+ array_push ($newpath, $path[$i]);
454
+ }
455
+
456
+ $finalpath = DIRECTORY_SEPARATOR.implode (DIRECTORY_SEPARATOR, $newpath);
457
+ return $finalpath;
458
+ }
459
+
460
+ return $path;
461
+ }
462
+
463
+
464
+ function checked ($item, $field = '')
465
+ {
466
+ if ($field && is_array ($item))
467
+ {
468
+ if (isset ($item[$field]) && $item[$field])
469
+ echo ' checked="checked"';
470
+ }
471
+ else if (!empty ($item))
472
+ echo ' checked="checked"';
473
+ }
474
+
475
+ function select ($items, $default = '')
476
+ {
477
+ if (count ($items) > 0)
478
+ {
479
+ foreach ($items AS $key => $value)
480
+ {
481
+ if (is_array ($value))
482
+ {
483
+ echo '<optgroup label="'.$key.'">';
484
+ foreach ($value AS $sub => $subvalue)
485
+ echo '<option value="'.$sub.'"'.($sub == $default ? ' selected="selected"' : '').'>'.$subvalue.'</option>';
486
+ echo '</optgroup>';
487
+ }
488
+ else
489
+ echo '<option value="'.$key.'"'.($key == $default ? ' selected="selected"' : '').'>'.$value.'</option>';
490
+ }
491
+ }
492
+ }
493
+ }
494
+
495
+ if (!function_exists ('pr'))
496
+ {
497
+ function pr ($thing)
498
+ {
499
+ echo '<pre>';
500
+ print_r ($thing);
501
+ echo '</pre>';
502
+ }
503
+ }
504
+
505
+ if (!class_exists ('Widget_SU'))
506
+ {
507
+ class Widget_SU
508
+ {
509
+ function Widget_SU ($name, $max = 1, $id = '', $args = '')
510
+ {
511
+ $this->name = $name;
512
+ $this->id = $id;
513
+ $this->widget_max = $max;
514
+ $this->args = $args;
515
+
516
+ if ($this->id == '')
517
+ $this->id = strtolower (preg_replace ('/[^A-Za-z]/', '-', $this->name));
518
+
519
+ $this->widget_available = 1;
520
+ if ($this->widget_max > 1)
521
+ {
522
+ $this->widget_available = get_option ('widget_available_'.$this->id ());
523
+ if ($this->widget_available === false)
524
+ $this->widget_available = 1;
525
+ }
526
+
527
+ add_action ('init', array (&$this, 'initialize'));
528
+ }
529
+
530
+ function initialize ()
531
+ {
532
+ // Compatability functions for WP 2.1
533
+ if (!function_exists ('wp_register_sidebar_widget'))
534
+ {
535
+ function wp_register_sidebar_widget ($id, $name, $output_callback, $classname = '')
536
+ {
537
+ register_sidebar_widget($name, $output_callback, $classname);
538
+ }
539
+ }
540
+
541
+ if (!function_exists ('wp_register_widget_control'))
542
+ {
543
+ function wp_register_widget_control($name, $control_callback, $width = 300, $height = 200)
544
+ {
545
+ register_widget_control($name, $control_callback, $width, $height);
546
+ }
547
+ }
548
+
549
+ if (function_exists ('wp_register_sidebar_widget'))
550
+ {
551
+ if ($this->widget_max > 1)
552
+ {
553
+ add_action ('sidebar_admin_setup', array (&$this, 'setup_save'));
554
+ add_action ('sidebar_admin_page', array (&$this, 'setup_display'));
555
+ }
556
+
557
+ $this->load_widgets ();
558
+ }
559
+ }
560
+
561
+ function load_widgets ()
562
+ {
563
+ for ($pos = 1; $pos <= $this->widget_max; $pos++)
564
+ {
565
+ wp_register_sidebar_widget ($this->id ($pos), $this->name ($pos), $pos <= $this->widget_available ? array (&$this, 'show_display') : '', $this->args (), $pos);
566
+
567
+ if ($this->has_config ())
568
+ wp_register_widget_control ($this->id ($pos), $this->name ($pos), $pos <= $this->widget_available ? array (&$this, 'show_config') : '', $this->args (), $pos);
569
+ }
570
+ }
571
+
572
+ function args ()
573
+ {
574
+ if ($this->args)
575
+ return $args;
576
+ return array ('classname' => '');
577
+ }
578
+
579
+ function name ($pos)
580
+ {
581
+ if ($this->widget_available > 1)
582
+ return $this->name.' ('.$pos.')';
583
+ return $this->name;
584
+ }
585
+
586
+ function id ($pos = 0)
587
+ {
588
+ if ($pos == 0)
589
+ return $this->id;
590
+ return $this->id.'-'.$pos;
591
+ }
592
+
593
+ function show_display ($args, $number = 1)
594
+ {
595
+ $config = get_option ('widget_config_'.$this->id ($number));
596
+ if ($config === false)
597
+ $config = array ();
598
+
599
+ $this->load ($config);
600
+ $this->display ($args);
601
+ }
602
+
603
+ function show_config ($position)
604
+ {
605
+ if (isset ($_POST['widget_config_save_'.$this->id ($position)]))
606
+ {
607
+ $data = $_POST[$this->id ()];
608
+ if (count ($data) > 0)
609
+ {
610
+ $newdata = array ();
611
+ foreach ($data AS $item => $values)
612
+ $newdata[$item] = $values[$position];
613
+ $data = $newdata;
614
+ }
615
+
616
+ update_option ('widget_config_'.$this->id ($position), $this->save ($data));
617
+ }
618
+
619
+ $options = get_option ('widget_config_'.$this->id ($position));
620
+ if ($options === false)
621
+ $options = array ();
622
+
623
+ $this->config ($options, $position);
624
+ echo '<input type="hidden" name="widget_config_save_'.$this->id ($position).'" value="1" />';
625
+ }
626
+
627
+ function has_config () { return false; }
628
+ function save ($data)
629
+ {
630
+ return array ();
631
+ }
632
+
633
+ function setup_save ()
634
+ {
635
+ if (isset ($_POST['widget_setup_save_'.$this->id ()]))
636
+ {
637
+ $this->widget_available = intval ($_POST['widget_setup_count_'.$this->id ()]);
638
+ if ($this->widget_available < 1)
639
+ $this->widget_available = 1;
640
+ else if ($this->widget_available > $this->widget_max)
641
+ $this->widget_available = $this->widget_max;
642
+
643
+ update_option ('widget_available_'.$this->id (), $this->widget_available);
644
+
645
+ $this->load_widgets ();
646
+ }
647
+ }
648
+
649
+ function config_name ($field, $pos)
650
+ {
651
+ return $this->id ().'['.$field.']['.$pos.']';
652
+ }
653
+
654
+ function setup_display ()
655
+ {
656
+ ?>
657
+ <div class="wrap">
658
+ <form method="post">
659
+ <h2><?php echo $this->name ?></h2>
660
+ <p style="line-height: 30px;"><?php _e('How many widgets would you like?', $this->id); ?>
661
+ <select name="widget_setup_count_<?php echo $this->id () ?>" value="<?php echo $options; ?>">
662
+ <?php for ( $i = 1; $i <= $this->widget_max; ++$i ) : ?>
663
+ <option value="<?php echo $i ?>"<?php if ($this->widget_available == $i) echo ' selected="selected"' ?>><?php echo $i ?></option>
664
+ <?php endfor; ?>
665
+ </select>
666
+ <span class="submit">
667
+ <input type="submit" name="widget_setup_save_<?php echo $this->id () ?>" value="<?php echo attribute_escape(__('Save', $this->id)); ?>" />
668
+ </span>
669
+ </p>
670
+ </form>
671
+ </div>
672
+ <?php
673
+ }
674
+ }
675
+ }
676
+ ?>
readme.txt ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Custom Post Template ===
2
+ Contributors: simonwheatley
3
+ Donate link: http://www.simonwheatley.co.uk/wordpress/
4
+ Tags: post, template, theme
5
+ Requires at least: 2.6
6
+ Tested up to: 2.6.3
7
+ Stable tag: 0.9b
8
+
9
+ Provides a drop-down to select different templates for posts from the post edit screen. The templates replace single.php for the specified post.
10
+
11
+ == Description ==
12
+
13
+ Provides a drop-down to select different templates for posts from the post edit screen. The templates are defined similarly to page templates, and will replace single.php for the specified post.
14
+
15
+ Post templates, as far as this plugin is concerned, are configured similarly to [page templates](http://codex.wordpress.org/Pages#Creating_Your_Own_Page_Templates) in that they have a particular style of PHP comment at the top of them. Each post template must contain the following, or similar, at the top:
16
+ <code>
17
+ <?php
18
+ /*
19
+ Template Name Posts: Snarfer
20
+ */
21
+ ?>
22
+ </code>
23
+
24
+ Note that *page* templates use "_Template Name:_", whereas *post* templates use "_Template Name Posts:_".
25
+
26
+ Plugin initially produced on behalf of [Words & Pictures](http://www.wordsandpics.co.uk/).
27
+
28
+ Is this plugin lacking a feature you want? I'm happy to discuss ideas, or to accept offers of feature sponsorship: [contact me](http://www.simonwheatley.co.uk/contact-me/) and we can have a chat.
29
+
30
+ Any issues: [contact me](http://www.simonwheatley.co.uk/contact-me/).
31
+
32
+ == Installation ==
33
+
34
+ The plugin is simple to install:
35
+
36
+ 1. Download the plugin, it will arrive as a zip file
37
+ 1. Unzip it
38
+ 1. Upload `custom-post-template.zip` directory to your WordPress Plugin directory
39
+ 1. Go to the plugin management page and enable the plugin
40
+ 1. Upload your post template files (see the Description for details on configuring these), and choose them through the new menu
41
+ 1. Give yourself a pat on the back
42
+
43
+ == Change Log ==
44
+
45
+ = v0.9b 2008/11/26 =
46
+
47
+ * Plugin first released
view/admin/select_post_template.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <label class="hidden" for="page_template"><?php _e( 'Post Template' ); ?></label>
2
+ <input type="hidden" name="custom_post_template_present" value="1" />
3
+ <select name="custom_post_template" id="custom_post_template">
4
+ <option
5
+ value='default'
6
+ <?php
7
+ if ( ! $custom_template ) {
8
+ echo "selected='selected'";
9
+ }
10
+ ?>><?php _e( 'Default Template' ); ?></option>
11
+ <?php foreach( $templates AS $name => $filename ) { ?>
12
+ <option
13
+ value='<?php echo $filename; ?>'
14
+ <?php
15
+ if ( $custom_template == $filename ) {
16
+ echo "selected='selected'";
17
+ }
18
+ ?>><?php echo $name; ?></option>
19
+ <?php } ?>
20
+ </select>
21
+ <p><?php _e( 'Some themes have custom templates you can use for certain posts that might have additional features or custom layouts. If so, you&#8217;ll see them above.' ); ?></p>