Advertisement
firoze

A complete, options page class for WordPress plugin

Nov 18th, 2014
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 22.26 KB | None | 0 0
  1. // source link  http://www.hughlashbrooke.com/2014/02/complete-versatile-options-page-class-wordpress-plugin/
  2.  
  3.  
  4. A complete, versatile options page class for any WordPress plugin
  5.  
  6. Building an options page for a plugin can be a daunting prospect – you want to build it in a way that works for your plugin, but also so that it works well within the WordPress UI. Many plugin authors get this painfully wrong and build incredibly unfriendly options pages that look terrible and really don’t fit into the WordPress dashboard design at all.
  7.  
  8. After putting loads of work into refactoring Seriously Simple Podcasting for the v2.0 release, I’ve developed a single class that will help you to create a versatile and user-friendly options page for your plugin that fits neatly into the WordPress dashboard. All you need to do is add this class to your plugin and modify the array of settings to handle the data that your plugin needs.
  9.  
  10. This isn’t a tutorial post, so I’m not going to walk you through this step by step, but if you use the class below you can create a WordPress options page with every type of field possible with almost no effort on your part. The field types that this class can create are:
  11.  
  12.     Text field
  13.     Password field
  14.     Secret text field (where the saved data is not displayed on the page)
  15.     Text area
  16.     Single checkbox
  17.     Multiple checkboxes
  18.     Select box
  19.     Multiple select box
  20.     Radio buttons
  21.     Number field
  22.     Colour picker (using WordPress’ built-in colour picker script)
  23.     Image upload (that saves the image to your site’s media library)
  24.  
  25. I have included demo fields in the class so you can see how each field type works and what parameters you need to define for each field type – all you need to do is delete these fields and create your own.
  26.  
  27. The class uses all the WordPress Settings API functions, so it does things in the “correct” way. It also includes a mini-navigation that uses Javascript to show & hide the relevant sections.
  28.  
  29. You will find the class, along with its associated Javascript file below, but if you want to see it all in action in the context of a full plugin you can check out my WordPress Plugin Template that includes this same code. For a quick overview of what the resulting options page will look like, here’s a handy screenshot (click to enlarge):
  30. Options pageThe options page that is generated by this class
  31.  
  32. Here is the class in its entirety:
  33. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411    
  34.  
  35. <?php
  36.  
  37. if ( ! defined( 'ABSPATH' ) ) exit;
  38.  
  39. class WordPress_Plugin_Template_Settings {
  40. private $dir;
  41. private $file;
  42. private $assets_dir;
  43. private $assets_url;
  44. private $settings_base;
  45. private $settings;
  46.  
  47. public function __construct( $file ) {
  48. $this->file = $file;
  49. $this->dir = dirname( $this->file );
  50. $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
  51. $this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $this->file ) ) );
  52. $this->settings_base = 'wpt_';
  53.  
  54. // Initialise settings
  55. add_action( 'admin_init', array( $this, 'init' ) );
  56.  
  57. // Register plugin settings
  58. add_action( 'admin_init' , array( $this, 'register_settings' ) );
  59.  
  60. // Add settings page to menu
  61. add_action( 'admin_menu' , array( $this, 'add_menu_item' ) );
  62.  
  63. // Add settings link to plugins page
  64. add_filter( 'plugin_action_links_' . plugin_basename( $this->file ) , array( $this, 'add_settings_link' ) );
  65. }
  66.  
  67. /**
  68. * Initialise settings
  69. * @return void
  70. */
  71. public function init() {
  72. $this->settings = $this->settings_fields();
  73. }
  74.  
  75. /**
  76. * Add settings page to admin menu
  77. * @return void
  78. */
  79. public function add_menu_item() {
  80. $page = add_options_page( __( 'Plugin Settings', 'plugin_textdomain' ) , __( 'Plugin Settings', 'plugin_textdomain' ) , 'manage_options' , 'plugin_settings' , array( $this, 'settings_page' ) );
  81. add_action( 'admin_print_styles-' . $page, array( $this, 'settings_assets' ) );
  82. }
  83.  
  84. /**
  85. * Load settings JS & CSS
  86. * @return void
  87. */
  88. public function settings_assets() {
  89.  
  90. // We're including the farbtastic script & styles here because they're needed for the colour picker
  91. // If you're not including a colour picker field then you can leave these calls out as well as the farbtastic dependency for the wpt-admin-js script below
  92. wp_enqueue_style( 'farbtastic' );
  93. wp_enqueue_script( 'farbtastic' );
  94.  
  95. // We're including the WP media scripts here because they're needed for the image upload field
  96. // If you're not including an image upload then you can leave this function call out
  97. wp_enqueue_media();
  98.  
  99. wp_register_script( 'wpt-admin-js', $this->assets_url . 'js/settings.js', array( 'farbtastic', 'jquery' ), '1.0.0' );
  100. wp_enqueue_script( 'wpt-admin-js' );
  101. }
  102.  
  103. /**
  104. * Add settings link to plugin list table
  105. * @param array $links Existing links
  106. * @return array Modified links
  107. */
  108. public function add_settings_link( $links ) {
  109. $settings_link = '<a href="options-general.php?page=plugin_settings">' . __( 'Settings', 'plugin_textdomain' ) . '</a>';
  110. array_push( $links, $settings_link );
  111. return $links;
  112. }
  113.  
  114. /**
  115. * Build settings fields
  116. * @return array Fields to be displayed on settings page
  117. */
  118. private function settings_fields() {
  119.  
  120. $settings['standard'] = array(
  121. 'title' => __( 'Standard', 'plugin_textdomain' ),
  122. 'description'   => __( 'These are fairly standard form input fields.', 'plugin_textdomain' ),
  123. 'fields'    => array(
  124. array(
  125. 'id' => 'text_field',
  126. 'label' => __( 'Some Text' , 'plugin_textdomain' ),
  127. 'description'   => __( 'This is a standard text field.', 'plugin_textdomain' ),
  128. 'type'  => 'text',
  129. 'default'   => '',
  130. 'placeholder'   => __( 'Placeholder text', 'plugin_textdomain' )
  131. ),
  132. array(
  133. 'id' => 'password_field',
  134. 'label' => __( 'A Password' , 'plugin_textdomain' ),
  135. 'description'   => __( 'This is a standard password field.', 'plugin_textdomain' ),
  136. 'type'  => 'password',
  137. 'default'   => '',
  138. 'placeholder'   => __( 'Placeholder text', 'plugin_textdomain' )
  139. ),
  140. array(
  141. 'id' => 'secret_text_field',
  142. 'label' => __( 'Some Secret Text' , 'plugin_textdomain' ),
  143. 'description'   => __( 'This is a secret text field - any data saved here will not be displayed after the page has reloaded, but it will be saved.', 'plugin_textdomain' ),
  144. 'type'  => 'text_secret',
  145. 'default'   => '',
  146. 'placeholder'   => __( 'Placeholder text', 'plugin_textdomain' )
  147. ),
  148. array(
  149. 'id' => 'text_block',
  150. 'label' => __( 'A Text Block' , 'plugin_textdomain' ),
  151. 'description'   => __( 'This is a standard text area.', 'plugin_textdomain' ),
  152. 'type'  => 'textarea',
  153. 'default'   => '',
  154. 'placeholder'   => __( 'Placeholder text for this textarea', 'plugin_textdomain' )
  155. ),
  156. array(
  157. 'id' => 'single_checkbox',
  158. 'label' => __( 'An Option', 'plugin_textdomain' ),
  159. 'description'   => __( 'A standard checkbox - if you save this option as checked then it will store the option as \'on\', otherwise it will be an empty string.', 'plugin_textdomain' ),
  160. 'type'  => 'checkbox',
  161. 'default'   => ''
  162. ),
  163. array(
  164. 'id' => 'select_box',
  165. 'label' => __( 'A Select Box', 'plugin_textdomain' ),
  166. 'description'   => __( 'A standard select box.', 'plugin_textdomain' ),
  167. 'type'  => 'select',
  168. 'options'   => array( 'drupal' => 'Drupal', 'joomla' => 'Joomla', 'wordpress' => 'WordPress' ),
  169. 'default'   => 'wordpress'
  170. ),
  171. array(
  172. 'id' => 'radio_buttons',
  173. 'label' => __( 'Some Options', 'plugin_textdomain' ),
  174. 'description'   => __( 'A standard set of radio buttons.', 'plugin_textdomain' ),
  175. 'type'  => 'radio',
  176. 'options'   => array( 'superman' => 'Superman', 'batman' => 'Batman', 'ironman' => 'Iron Man' ),
  177. 'default'   => 'batman'
  178. ),
  179. array(
  180. 'id' => 'multiple_checkboxes',
  181. 'label' => __( 'Some Items', 'plugin_textdomain' ),
  182. 'description'   => __( 'You can select multiple items and they will be stored as an array.', 'plugin_textdomain' ),
  183. 'type'  => 'checkbox_multi',
  184. 'options'   => array( 'square' => 'Square', 'circle' => 'Circle', 'rectangle' => 'Rectangle', 'triangle' => 'Triangle' ),
  185. 'default'   => array( 'circle', 'triangle' )
  186. )
  187. )
  188. );
  189.  
  190. $settings['extra'] = array(
  191. 'title' => __( 'Extra', 'plugin_textdomain' ),
  192. 'description'   => __( 'These are some extra input fields that maybe aren\'t as common as the others.', 'plugin_textdomain' ),
  193. 'fields'    => array(
  194. array(
  195. 'id' => 'number_field',
  196. 'label' => __( 'A Number' , 'plugin_textdomain' ),
  197. 'description'   => __( 'This is a standard number field - if this field contains anything other than numbers then the form will not be submitted.', 'plugin_textdomain' ),
  198. 'type'  => 'number',
  199. 'default'   => '',
  200. 'placeholder'   => __( '42', 'plugin_textdomain' )
  201. ),
  202. array(
  203. 'id' => 'colour_picker',
  204. 'label' => __( 'Pick a colour', 'plugin_textdomain' ),
  205. 'description'   => __( 'This uses WordPress\' built-in colour picker - the option is stored as the colour\'s hex code.', 'plugin_textdomain' ),
  206. 'type'  => 'color',
  207. 'default'   => '#21759B'
  208. ),
  209. array(
  210. 'id' => 'an_image',
  211. 'label' => __( 'An Image' , 'plugin_textdomain' ),
  212. 'description'   => __( 'This will upload an image to your media library and store the attachment ID in the option field. Once you have uploaded an imge the thumbnail will display above these buttons.', 'plugin_textdomain' ),
  213. 'type'  => 'image',
  214. 'default'   => '',
  215. 'placeholder'   => ''
  216. ),
  217. array(
  218. 'id' => 'multi_select_box',
  219. 'label' => __( 'A Multi-Select Box', 'plugin_textdomain' ),
  220. 'description'   => __( 'A standard multi-select box - the saved data is stored as an array.', 'plugin_textdomain' ),
  221. 'type'  => 'select_multi',
  222. 'options'   => array( 'linux' => 'Linux', 'mac' => 'Mac', 'windows' => 'Windows' ),
  223. 'default'   => array( 'linux' )
  224. )
  225. )
  226. );
  227.  
  228. $settings = apply_filters( 'plugin_settings_fields', $settings );
  229.  
  230. return $settings;
  231. }
  232.  
  233. /**
  234. * Register plugin settings
  235. * @return void
  236. */
  237. public function register_settings() {
  238. if( is_array( $this->settings ) ) {
  239. foreach( $this->settings as $section => $data ) {
  240.  
  241. // Add section to page
  242. add_settings_section( $section, $data['title'], array( $this, 'settings_section' ), 'plugin_settings' );
  243.  
  244. foreach( $data['fields'] as $field ) {
  245.  
  246. // Validation callback for field
  247. $validation = '';
  248. if( isset( $field['callback'] ) ) {
  249. $validation = $field['callback'];
  250. }
  251.  
  252. // Register field
  253. $option_name = $this->settings_base . $field['id'];
  254. register_setting( 'plugin_settings', $option_name, $validation );
  255.  
  256. // Add field to page
  257. add_settings_field( $field['id'], $field['label'], array( $this, 'display_field' ), 'plugin_settings', $section, array( 'field' => $field ) );
  258. }
  259. }
  260. }
  261. }
  262.  
  263. public function settings_section( $section ) {
  264. $html = '<p> ' . $this->settings[ $section['id'] ]['description'] . '</p>' . "\n";
  265. echo $html;
  266. }
  267.  
  268. /**
  269. * Generate HTML for displaying fields
  270. * @param array $args Field data
  271. * @return void
  272. */
  273. public function display_field( $args ) {
  274.  
  275. $field = $args['field'];
  276.  
  277. $html = '';
  278.  
  279. $option_name = $this->settings_base . $field['id'];
  280. $option = get_option( $option_name );
  281.  
  282. $data = '';
  283. if( isset( $field['default'] ) ) {
  284. $data = $field['default'];
  285. if( $option ) {
  286. $data = $option;
  287. }
  288. }
  289.  
  290. switch( $field['type'] ) {
  291.  
  292. case 'text':
  293. case 'password':
  294. case 'number':
  295. $html .= '<input id="' . esc_attr( $field['id'] ) . '" type="' . $field['type'] . '" name="' . esc_attr( $option_name ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" value="' . $data . '"/>' . "\n";
  296. break;
  297.  
  298. case 'text_secret':
  299. $html .= '<input id="' . esc_attr( $field['id'] ) . '" type="text" name="' . esc_attr( $option_name ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" value=""/>' . "\n";
  300. break;
  301.  
  302. case 'textarea':
  303. $html .= '<textarea id="' . esc_attr( $field['id'] ) . '" rows="5" cols="50" name="' . esc_attr( $option_name ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '">' . $data . '</textarea><br/>'. "\n";
  304. break;
  305.  
  306. case 'checkbox':
  307. $checked = '';
  308. if( $option && 'on' == $option ){
  309. $checked = 'checked="checked"';
  310. }
  311. $html .= '<input id="' . esc_attr( $field['id'] ) . '" type="' . $field['type'] . '" name="' . esc_attr( $option_name ) . '" ' . $checked . '/>' . "\n";
  312. break;
  313.  
  314. case 'checkbox_multi':
  315. foreach( $field['options'] as $k => $v ) {
  316. $checked = false;
  317. if( in_array( $k, $data ) ) {
  318. $checked = true;
  319. }
  320. $html .= '<label for="' . esc_attr( $field['id'] . '_' . $k ) . '"><input type="checkbox" ' . checked( $checked, true, false ) . ' name="' . esc_attr( $option_name ) . '[]" value="' . esc_attr( $k ) . '" id="' . esc_attr( $field['id'] . '_' . $k ) . '" /> ' . $v . '</label> ';
  321. }
  322. break;
  323.  
  324. case 'radio':
  325. foreach( $field['options'] as $k => $v ) {
  326. $checked = false;
  327. if( $k == $data ) {
  328. $checked = true;
  329. }
  330. $html .= '<label for="' . esc_attr( $field['id'] . '_' . $k ) . '"><input type="radio" ' . checked( $checked, true, false ) . ' name="' . esc_attr( $option_name ) . '" value="' . esc_attr( $k ) . '" id="' . esc_attr( $field['id'] . '_' . $k ) . '" /> ' . $v . '</label> ';
  331. }
  332. break;
  333.  
  334. case 'select':
  335. $html .= '<select name="' . esc_attr( $option_name ) . '" id="' . esc_attr( $field['id'] ) . '">';
  336. foreach( $field['options'] as $k => $v ) {
  337. $selected = false;
  338. if( $k == $data ) {
  339. $selected = true;
  340. }
  341. $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '">' . $v . '</option>';
  342. }
  343. $html .= '</select> ';
  344. break;
  345.  
  346. case 'select_multi':
  347. $html .= '<select name="' . esc_attr( $option_name ) . '[]" id="' . esc_attr( $field['id'] ) . '" multiple="multiple">';
  348. foreach( $field['options'] as $k => $v ) {
  349. $selected = false;
  350. if( in_array( $k, $data ) ) {
  351. $selected = true;
  352. }
  353. $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '" />' . $v . '</label> ';
  354. }
  355. $html .= '</select> ';
  356. break;
  357.  
  358. case 'image':
  359. $image_thumb = '';
  360. if( $data ) {
  361. $image_thumb = wp_get_attachment_thumb_url( $data );
  362. }
  363. $html .= '<img id="' . $option_name . '_preview" class="image_preview" src="' . $image_thumb . '" /><br/>' . "\n";
  364. $html .= '<input id="' . $option_name . '_button" type="button" data-uploader_title="' . __( 'Upload an image' , 'plugin_textdomain' ) . '" data-uploader_button_text="' . __( 'Use image' , 'plugin_textdomain' ) . '" class="image_upload_button button" value="'. __( 'Upload new image' , 'plugin_textdomain' ) . '" />' . "\n";
  365. $html .= '<input id="' . $option_name . '_delete" type="button" class="image_delete_button button" value="'. __( 'Remove image' , 'plugin_textdomain' ) . '" />' . "\n";
  366. $html .= '<input id="' . $option_name . '" class="image_data_field" type="hidden" name="' . $option_name . '" value="' . $data . '"/><br/>' . "\n";
  367. break;
  368.  
  369. case 'color':
  370. ?><div class="color-picker" style="position:relative;">
  371. <input type="text" name="<?php esc_attr_e( $option_name ); ?>" class="color" value="<?php esc_attr_e( $data ); ?>" />
  372. <div style="position:absolute;background:#FFF;z-index:99;border-radius:100%;" class="colorpicker"></div>
  373. </div>
  374. <?php
  375. break;
  376.  
  377. }
  378.  
  379. switch( $field['type'] ) {
  380.  
  381. case 'checkbox_multi':
  382. case 'radio':
  383. case 'select_multi':
  384. $html .= '<br/><span class="description">' . $field['description'] . '</span>';
  385. break;
  386.  
  387. default:
  388. $html .= '<label for="' . esc_attr( $field['id'] ) . '"><span class="description">' . $field['description'] . '</span></label>' . "\n";
  389. break;
  390. }
  391.  
  392. echo $html;
  393. }
  394.  
  395. /**
  396. * Validate individual settings field
  397. * @param string $data Inputted value
  398. * @return string Validated value
  399. */
  400. public function validate_field( $data ) {
  401. if( $data && strlen( $data ) > 0 && $data != '' ) {
  402. $data = urlencode( strtolower( str_replace( ' ' , '-' , $data ) ) );
  403. }
  404. return $data;
  405. }
  406.  
  407. /**
  408. * Load settings page content
  409. * @return void
  410. */
  411. public function settings_page() {
  412.  
  413. // Build page HTML
  414. $html = '<div class="wrap" id="plugin_settings">' . "\n";
  415. $html .= '<h2>' . __( 'Plugin Settings' , 'plugin_textdomain' ) . '</h2>' . "\n";
  416. $html .= '<form method="post" action="options.php" enctype="multipart/form-data">' . "\n";
  417.  
  418. // Setup navigation
  419. $html .= '<ul id="settings-sections" class="subsubsub hide-if-no-js">' . "\n";
  420. $html .= '<li><a class="tab all current" href="#all">' . __( 'All' , 'plugin_textdomain' ) . '</a></li>' . "\n";
  421.  
  422. foreach( $this->settings as $section => $data ) {
  423. $html .= '<li>| <a class="tab" href="#' . $section . '">' . $data['title'] . '</a></li>' . "\n";
  424. }
  425.  
  426. $html .= '</ul>' . "\n";
  427.  
  428. $html .= '<div class="clear"></div>' . "\n";
  429.  
  430. // Get settings fields
  431. ob_start();
  432. settings_fields( 'plugin_settings' );
  433. do_settings_sections( 'plugin_settings' );
  434. $html .= ob_get_clean();
  435.  
  436. $html .= '<p class="submit">' . "\n";
  437. $html .= '<input name="Submit" type="submit" class="button-primary" value="' . esc_attr( __( 'Save Settings' , 'plugin_textdomain' ) ) . '" />' . "\n";
  438. $html .= '</p>' . "\n";
  439. $html .= '</form>' . "\n";
  440. $html .= '</div>' . "\n";
  441.  
  442. echo $html;
  443. }
  444.  
  445. }
  446.  
  447. view raw class.php hosted with ❤ by GitHub
  448.  
  449. And here is the Javascript file that you will need to manage everything. You will need to save this inside your plugin in this folder: /assets/js/admin.js
  450. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103    
  451.  
  452. jQuery(document).ready(function($) {
  453.  
  454. /***** Colour picker *****/
  455.  
  456. $('.colorpicker').hide();
  457. $('.colorpicker').each( function() {
  458. $(this).farbtastic( $(this).closest('.color-picker').find('.color') );
  459. });
  460.  
  461. $('.color').click(function() {
  462. $(this).closest('.color-picker').find('.colorpicker').fadeIn();
  463. });
  464.  
  465. $(document).mousedown(function() {
  466. $('.colorpicker').each(function() {
  467. var display = $(this).css('display');
  468. if ( display == 'block' )
  469. $(this).fadeOut();
  470. });
  471. });
  472.  
  473.  
  474. /***** Uploading images *****/
  475.  
  476. var file_frame;
  477.  
  478. jQuery.fn.uploadMediaFile = function( button, preview_media ) {
  479. var button_id = button.attr('id');
  480. var field_id = button_id.replace( '_button', '' );
  481. var preview_id = button_id.replace( '_button', '_preview' );
  482.  
  483. // If the media frame already exists, reopen it.
  484. if ( file_frame ) {
  485. file_frame.open();
  486. return;
  487. }
  488.  
  489. // Create the media frame.
  490. file_frame = wp.media.frames.file_frame = wp.media({
  491. title: jQuery( this ).data( 'uploader_title' ),
  492. button: {
  493. text: jQuery( this ).data( 'uploader_button_text' ),
  494. },
  495. multiple: false
  496. });
  497.  
  498. // When an image is selected, run a callback.
  499. file_frame.on( 'select', function() {
  500. attachment = file_frame.state().get('selection').first().toJSON();
  501. jQuery("#"+field_id).val(attachment.id);
  502. if( preview_media ) {
  503. jQuery("#"+preview_id).attr('src',attachment.sizes.thumbnail.url);
  504. }
  505. });
  506.  
  507. // Finally, open the modal
  508. file_frame.open();
  509. }
  510.  
  511. jQuery('.image_upload_button').click(function() {
  512. jQuery.fn.uploadMediaFile( jQuery(this), true );
  513. });
  514.  
  515. jQuery('.image_delete_button').click(function() {
  516. jQuery(this).closest('td').find( '.image_data_field' ).val( '' );
  517. jQuery( '.image_preview' ).remove();
  518. return false;
  519. });
  520.  
  521.  
  522. /***** Navigation for settings page *****/
  523.  
  524. // Make sure each heading has a unique ID.
  525. jQuery( 'ul#settings-sections.subsubsub' ).find( 'a' ).each( function ( i ) {
  526. var id_value = jQuery( this ).attr( 'href' ).replace( '#', '' );
  527. jQuery( 'h3:contains("' + jQuery( this ).text() + '")' ).attr( 'id', id_value ).addClass( 'section-heading' );
  528. });
  529.  
  530. // Create nav links for settings page
  531. jQuery( '#plugin_settings .subsubsub a.tab' ).click( function ( e ) {
  532. // Move the "current" CSS class.
  533. jQuery( this ).parents( '.subsubsub' ).find( '.current' ).removeClass( 'current' );
  534. jQuery( this ).addClass( 'current' );
  535.  
  536. // If "All" is clicked, show all.
  537. if ( jQuery( this ).hasClass( 'all' ) ) {
  538. jQuery( '#plugin_settings h3, #plugin_settings form p, #plugin_settings table.form-table, p.submit' ).show();
  539.  
  540. return false;
  541. }
  542.  
  543. // If the link is a tab, show only the specified tab.
  544. var toShow = jQuery( this ).attr( 'href' );
  545.  
  546. // Remove the first occurance of # from the selected string (will be added manually below).
  547. toShow = toShow.replace( '#', '', toShow );
  548.  
  549. jQuery( '#plugin_settings h3, #plugin_settings form > p:not(".submit"), #plugin_settings table' ).hide();
  550. jQuery( 'h3#' + toShow ).show().nextUntil( 'h3.section-heading', 'p, table, table p' ).show();
  551.  
  552. return false;
  553. });
  554. });
  555.  
  556. view raw settings.js hosted with ❤ by GitHub
  557.  
  558. To add this options page to your plugin, simply add this line to your plugin’s index file after you have added an include for the class file:
  559. 1 2 3  
  560.  
  561. <?php
  562. $settings = new WordPress_Plugin_Template_Settings( __FILE__ );
  563. ?>
  564.  
  565. view raw index.php hosted with ❤ by GitHub
  566.  
  567. Once you have added all this code you will find the new options page in the dashboard menu by going to Settings > Plugin Settings.
  568.  
  569. The options that are saved from this page use the $settings_base variable in the class (in this case, ‘wpt_‘)followed by the id field of each setting for their name. So the option name for the first field would be ‘wpt_text_field‘, which you can fetch using get_option( 'wpt_text_field' );.
  570.  
  571. If you can think of any other field types that you think should be included in this class then let me know in the comments.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement