├── README.md
├── cfs-options-screens.php
├── index.php
├── readme.txt
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | This is a WordPress plugin, [Official download available on WordPress.org](http://wordpress.org/plugins/cfs-options-screens/)
2 |
3 | # Custom Field Suite Options Screens
4 |
5 | Create any number of options screens powered by [Custom Field Suite](http://customfieldsuite.com)
6 |
7 | ## Documentation
8 |
9 | Begin by creating your Field Group(s) as you normally would. *Unless setting up an [override](#overrides)*, be sure to set **NO Placement Rules**, this is handled automagically.
10 |
11 | Register an Options Screen (with all options)
12 |
13 | ```php
14 | function my_cfs_options_screens( $screens ) {
15 | $screens[] = array(
16 | 'name' => 'options',
17 | 'menu_title' => __( 'Site Options' ),
18 | 'page_title' => __( 'Customize Site Options' ),
19 | 'menu_position' => 100,
20 | 'icon' => 'dashicons-admin-generic', // optional, dashicons-admin-generic is the default
21 | 'field_groups' => array( 'My Field Group' ), // Field Group name(s) of CFS Field Group to use on this page (can also be post IDs)
22 | );
23 |
24 | return $screens;
25 | }
26 |
27 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );
28 | ```
29 |
30 | or register multiple Options Screens
31 |
32 | ```php
33 | function my_cfs_options_screens( $screens ) {
34 |
35 | // Parent
36 | $screens[] = array(
37 | 'name' => 'options',
38 | 'field_groups' => array( 'My Parent Field Group Name' ),
39 | );
40 |
41 | // Child
42 | $screens[] = array(
43 | 'name' => 'options-nav',
44 | 'parent' => 'options', // name of the parent
45 | 'field_groups' => array( 'My Child Field Group Name' ),
46 | );
47 |
48 | return $screens;
49 | }
50 |
51 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );
52 | ```
53 |
54 | Once your options screen(s) have been registered you can attach CFS Field Groups to them. Done!
55 |
56 | ### Overrides
57 |
58 | You can also use CFS Options Screens to set up Field Group overrides, allowing a Field Group to appear both on a CFS Options Screen and a post edit screen. The CFS Options Screen will act as the default/fallback and the post edit screen will override those defaults.
59 |
60 | ```php
61 | function my_cfs_options_screens( $screens ) {
62 | $screens[] = array(
63 | 'name' => 'options',
64 | 'menu_title' => __( 'Site Options' ),
65 | 'page_title' => __( 'Customize Site Options' ),
66 | 'menu_position' => 100,
67 | 'icon' => 'dashicons-admin-generic', // optional, dashicons-admin-generic is the default
68 | 'field_groups' => array(
69 | array(
70 | 'title' => 'My CFS Field Group Name',
71 | 'has_overrides' => true,
72 | ),
73 | ),
74 | );
75 |
76 | return $screens;
77 | }
78 |
79 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );
80 | ```
81 |
82 | Check out the `cfs_options_screens_override_note_default` and `cfs_options_screens_override_note_override` filters to customize the messaging for CFS Options Screens overrides.
83 |
84 | ## Retrieve options
85 |
86 | Option retrieval requires the screen and field names, it's as easy as:
87 |
88 | ```php
89 | $value = cfs_get_option( 'options_screen_name', 'field_name_from_field_group' );
90 | ```
91 |
--------------------------------------------------------------------------------
/cfs-options-screens.php:
--------------------------------------------------------------------------------
1 | .
25 | */
26 |
27 | // exit if accessed directly
28 | if ( ! defined( 'ABSPATH' ) ) {
29 | exit;
30 | }
31 |
32 | class CFS_Options_Screens {
33 |
34 | /**
35 | * @var CFS_Options_Screens Singleton
36 | */
37 | private static $instance;
38 |
39 | /**
40 | * @var array Options screens to create and utilize
41 | */
42 | public $screens = array();
43 |
44 | /**
45 | * @var string Post Type that powers options screens
46 | */
47 | public $post_type = 'options';
48 |
49 | /**
50 | * @var string Meta key used to store options screen name
51 | */
52 | public $meta_key = '_cfs_options_screen_name';
53 |
54 | /**
55 | * @var bool Whether we are applicable on this page load
56 | */
57 | private $applicable = false;
58 |
59 | function __construct() {
60 | add_action( 'init', array( $this, 'init' ) );
61 | add_action( 'admin_print_scripts', array( $this, 'admin_inline_css' ) );
62 |
63 | add_action( 'cfs_matching_groups', array( $this, 'cfs_rule_override' ), 10, 3 );
64 | add_action( 'cfs_form_before_fields', array( $this, 'output_override_note' ) );
65 | }
66 |
67 | /**
68 | * Output some markup above all Field Group fields in override cases, explaining
69 | * that editing these fields will override the defaults
70 | *
71 | * @since 1.2
72 | *
73 | * @param $params
74 | *
75 | * @return void
76 | */
77 | function output_override_note( $params ) {
78 |
79 | if ( empty( $params['field_groups'] ) ) {
80 | return;
81 | }
82 |
83 | $screens = $this->get_screens_from_field_group_id( $params['field_groups'] );
84 |
85 | foreach ( $screens as $screen ) {
86 | foreach ( $screen['field_groups'] as $field_group ) {
87 | if (
88 | is_array( $field_group )
89 | && array_key_exists( 'id', $field_group )
90 | && $params['field_groups'] == $field_group['id']
91 | && array_key_exists( 'has_overrides', $field_group )
92 | && ! empty( $field_group['has_overrides'] ) ) {
93 |
94 | // set up the note when editing the default
95 | $editing_default_note = __( 'Note: These defaults can be overridden when editing the applicable page.',
96 | 'cfsos' );
97 | $editing_default_note = apply_filters( 'cfs_options_screens_override_note_default',
98 | '
' . $editing_default_note . '
',
99 | $screen
100 | );
101 |
102 | // set up the note when editing the override
103 | /** @noinspection HtmlUnknownTarget */
104 | $editing_override_note = sprintf(
105 | __( 'Optional: Editing these fields will override %s which will be used if these fields are left empty',
106 | 'cfsos' ),
107 | esc_url( admin_url() . $this->get_options_screen_edit_slug( $screen['id'] ) ),
108 | esc_html( $screen['menu_title'] )
109 | );
110 | $editing_override_note = apply_filters( 'cfs_options_screens_override_note_override',
111 | '' . $editing_override_note . '
',
112 | $screen
113 | );
114 |
115 | $note = $this->applicable ? $editing_default_note : $editing_override_note;
116 |
117 | echo wp_kses_post(
118 | apply_filters( 'cfs_options_screens_override_note',
119 | $note,
120 | $screen,
121 | $this->applicable // indicates whether editing the default (when true) or the override (when false)
122 | )
123 | );
124 |
125 | break;
126 | }
127 | }
128 | }
129 | }
130 |
131 | /**
132 | * Retrieve an array of Options Screens models that utilize a Field Group ID
133 | *
134 | * @since 1.2
135 | * @param $field_group_id
136 | *
137 | * @return array
138 | */
139 | function get_screens_from_field_group_id( $field_group_id ) {
140 |
141 | $field_group_id = absint( $field_group_id );
142 | $screens = array();
143 |
144 | foreach ( $this->screens as $screen ) {
145 |
146 | $screen_field_groups = $this->get_field_group_ids( $screen['field_groups'] );
147 |
148 | if ( in_array( $field_group_id, $screen_field_groups ) ) {
149 | $screens[] = $screen;
150 | }
151 | }
152 |
153 | return $screens;
154 | }
155 |
156 | /**
157 | * Singleton
158 | *
159 | * @return CFS_Options_Screens
160 | */
161 | public static function instance() {
162 | if ( ! isset( self::$instance ) && ! ( self::$instance instanceof CFS_Options_Screens ) ) {
163 | self::$instance = new CFS_Options_Screens;
164 | }
165 | return self::$instance;
166 | }
167 |
168 | /**
169 | * Initialize everything
170 | */
171 | function init() {
172 |
173 | // hide the 'Edit Post' title, 'Add New' button, and 'updated' notification when editing all options screens
174 | add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) );
175 |
176 | // reinstate the 'updated' notification
177 | add_action( 'admin_notices', array( $this, 'maybe_updated_notice' ) );
178 |
179 | // let developers customize the post type used
180 | $this->post_type = apply_filters( 'cfs_options_screens_post_type', $this->post_type );
181 |
182 | // register our custom post type
183 | $this->register_cpt();
184 |
185 | // allow registration of options screens
186 | $this->screens = apply_filters( 'cfs_options_screens', $this->screens );
187 |
188 | // make sure our posts exist
189 | $this->init_screens();
190 |
191 | // add menus
192 | add_action( 'admin_menu', array( $this, 'maybe_add_menus' ) );
193 | }
194 |
195 | /**
196 | * Maybe enqueue our stylesheet
197 | * @param $hook
198 | */
199 | function assets( $hook ) {
200 | global $post;
201 |
202 | if ( 'post.php' == $hook && $this->post_type == $post->post_type ) {
203 | wp_enqueue_style( 'cfs-options-screen', plugin_dir_url( __FILE__ ) . 'style.css' );
204 | $this->applicable = true;
205 | }
206 |
207 | return;
208 | }
209 |
210 | /**
211 | * Output CSS in the footer that will customize the page title
212 | */
213 | function admin_inline_css() {
214 | global $post;
215 |
216 | $heading = __( 'Options' );
217 |
218 | // determine which screen we're on
219 | if ( isset( $this->screens ) && is_object( $post ) ) {
220 | foreach ( $this->screens as $screen ) {
221 | if ( $post->ID == $screen['id'] ) {
222 | $heading = $screen['page_title'];
223 | }
224 | }
225 | }
226 |
227 | if ( $this->applicable ) { ?>
228 |
234 | post_type ) || $this->post_type !== $screen->post_type ) {
247 | return;
248 | }
249 |
250 | if ( isset( $_GET['message'] ) && $this->post_type == $post->post_type ) {
251 | ?>
252 |
253 | screens ) ) {
262 | foreach ( $this->screens as $screen_key => $screen_meta ) {
263 | $this->screens[ $screen_key ]['name'] = isset( $screen_meta['name'] ) ? $screen_meta['name'] : 'options';
264 | $this->screens[ $screen_key ]['page_title'] = isset( $screen_meta['page_title'] ) ? $screen_meta['page_title'] : ucfirst( (string) $this->screens[ $screen_key ]['name'] );
265 | $this->screens[ $screen_key ]['menu_title'] = isset( $screen_meta['menu_title'] ) ? $screen_meta['menu_title'] : ucfirst( (string) $this->screens[ $screen_key ]['name'] );
266 | $this->screens[ $screen_key ]['menu_icon'] = isset( $screen_meta['icon'] ) ? $screen_meta['icon'] : 'dashicons-admin-generic';
267 | $this->screens[ $screen_key ]['menu_position'] = isset( $screen_meta['menu_position'] ) ? $screen_meta['menu_position'] : 100;
268 | $this->screens[ $screen_key ]['field_groups'] = isset( $screen_meta['field_groups'] ) ? $screen_meta['field_groups'] : array();
269 |
270 | $this->screens[ $screen_key ]['capability'] = apply_filters( 'cfs_options_screens_capability', 'manage_options', $screen_meta );
271 |
272 | // check to see if the post for this screen exists
273 | $screen = get_page_by_title( $this->screens[ $screen_key ]['name'], 'OBJECT', $this->post_type );
274 |
275 | if ( empty( $screen ) ) {
276 | // post doesn't exist, create and flag it
277 | $this->screens[ $screen_key ]['id'] = wp_insert_post(
278 | array(
279 | 'post_title' => sanitize_text_field( $this->screens[ $screen_key ]['name'] ),
280 | 'post_type' => sanitize_text_field( $this->post_type )
281 | )
282 | );
283 | } else {
284 | $this->screens[ $screen_key ]['id'] = absint( $screen->ID );
285 | }
286 | }
287 | }
288 | }
289 |
290 | /**
291 | * Registers the CPT that powers everything
292 | */
293 | function register_cpt() {
294 | $args = array(
295 | 'label' => __( 'CFS Options Screen', '' ),
296 | 'public' => false,
297 | 'publicly_queryable' => false,
298 | 'show_ui' => true,
299 | 'show_in_nav_menus' => false,
300 | 'show_in_menu' => false,
301 | 'query_var' => false,
302 | 'rewrite' => false,
303 | 'supports' => false,
304 | );
305 |
306 | $args = apply_filters( 'cfs_options_screens_post_type_args', $args );
307 |
308 | register_post_type( $this->post_type, $args );
309 | }
310 |
311 | /**
312 | * Retrieve the slug for an Options Screen edit URL
313 | *
314 | * @since 1.2
315 | *
316 | * @param $screen_id
317 | *
318 | * @return mixed
319 | */
320 | function get_options_screen_edit_slug( $screen_id ) {
321 | $url = add_query_arg(
322 | array(
323 | 'post' => absint( $screen_id ),
324 | 'action' => 'edit',
325 | ),
326 | admin_url( 'post.php' )
327 | );
328 |
329 | $url = esc_url( $url );
330 |
331 | return str_replace( admin_url(), '', $url );
332 | }
333 |
334 | /**
335 | * Add applicable Admin menus
336 | */
337 | function maybe_add_menus() {
338 |
339 | if ( empty( $this->screens ) ) {
340 | return;
341 | }
342 |
343 | // screens were registered during init so the ID is already prepped and the post exists
344 | foreach ( $this->screens as $screen ) {
345 | $edit_link = $this->get_options_screen_edit_slug( $screen['id'] );
346 |
347 | // if this screen doesn't have a parent, it IS a parent
348 | if ( empty( $screen['parent'] ) ) {
349 | add_menu_page(
350 | $screen['page_title'],
351 | $screen['menu_title'],
352 | $screen['capability'],
353 | $edit_link,
354 | '',
355 | $screen['menu_icon'],
356 | $screen['menu_position']
357 | );
358 | } else {
359 | // it's a sub-menu, so add it to the parent
360 | $parent = (string) $screen['parent'];
361 |
362 | foreach ( $this->screens as $maybe_parent_screen ) {
363 |
364 | if ( $parent == $maybe_parent_screen['name'] ) {
365 |
366 | $parent_slug = $this->get_options_screen_edit_slug( $maybe_parent_screen['id'] );
367 |
368 | add_submenu_page(
369 | $parent_slug,
370 | $screen['page_title'],
371 | $screen['menu_title'],
372 | $screen['capability'],
373 | $edit_link,
374 | ''
375 | );
376 |
377 | break;
378 | }
379 | }
380 | }
381 | }
382 | }
383 |
384 | /**
385 | * By default CFS Options Screens only supports Field Groups with no placement rules
386 | * 'Overrides' are for the cases where you want to use a Field Group to facilitate setting
387 | * defaults on an Options Screen, but also allow for an override for that field data
388 | * on specific edit screens that follow the placement rules of CFS itself
389 | *
390 | * @param $matches
391 | * @param $params
392 | * @param $rule_types
393 | * @param $options_screen
394 | *
395 | * @return mixed
396 | */
397 | function maybe_has_overrides( $matches, /** @noinspection PhpUnusedParameterInspection */ $params, /** @noinspection PhpUnusedParameterInspection */ $rule_types, $options_screen ) {
398 | // didn't find an options screen?
399 | if ( empty( $options_screen ) ) {
400 | return $matches;
401 | }
402 |
403 | // segment defaults
404 | if ( empty( $options_screen['field_groups'] ) ) {
405 | return $matches;
406 | }
407 |
408 | // move over all of these Field Groups into $matches
409 | foreach ( $options_screen['field_groups'] as $field_group ) {
410 | $key = $this->get_field_group_id( $field_group );
411 |
412 | if ( ! array_key_exists( $key, $matches ) ) {
413 | $matches[ $key ] = get_the_title( $key );
414 | }
415 | }
416 |
417 | return $matches;
418 | }
419 |
420 | /**
421 | * Version 1.2 introduced overrides, so we need back compat
422 | *
423 | * @since 1.2
424 | *
425 | * @param $field_group
426 | *
427 | * @return int
428 | */
429 | function get_field_group_id( $field_group ) {
430 |
431 | if ( is_string( $field_group ) ) {
432 |
433 | $field_group = $this->get_field_group_id_from_title( $field_group );
434 |
435 | } elseif ( is_array( $field_group ) ) {
436 |
437 | if ( array_key_exists( 'id', $field_group ) ) {
438 |
439 | $field_group = $field_group['id'];
440 |
441 | } elseif ( array_key_exists( 'title', $field_group ) ) {
442 |
443 | $field_group = $this->get_field_group_id_from_title( $field_group['title'] );
444 |
445 | }
446 |
447 | }
448 |
449 | return absint( $field_group );
450 | }
451 |
452 | /**
453 | * Retrieve CFS Field Group ID from title
454 | *
455 | * @param string $title
456 | *
457 | * @return int
458 | */
459 | function get_field_group_id_from_title( $title = '' ) {
460 | $id = 0;
461 |
462 | $field_group_obj = get_page_by_title( $title, 'OBJECT', 'cfs' );
463 |
464 | if ( $field_group_obj instanceof WP_Post ) {
465 | $id = $field_group_obj->ID;
466 | }
467 |
468 | return $id;
469 | }
470 |
471 | /**
472 | * Retrieve the CFS Options Screen model from its post ID
473 | *
474 | * @param $post_id
475 | *
476 | * @return bool|array
477 | */
478 | function get_options_screen_from_post_id( $post_id ) {
479 | $options_screen = false;
480 |
481 | // we need to validate that this post ID is actually a registered options screen
482 | if ( ! empty( $this->screens ) ) {
483 | foreach ( $this->screens as $screen_key => $screen_meta ) {
484 | if ( isset( $screen_meta['id'] ) && $post_id == $screen_meta['id'] ) {
485 | $options_screen = $screen_meta;
486 | break;
487 | }
488 | }
489 | }
490 |
491 | return $options_screen;
492 | }
493 |
494 | /**
495 | * Retrieve an array of Field Group IDs from a field_groups definition, takes into consideration
496 | * whether you want to include overrides or not
497 | *
498 | * @since 1.2
499 | * @param $field_groups
500 | * @param bool $include_overrides
501 | *
502 | * @return array
503 | */
504 | function get_field_group_ids( $field_groups, $include_overrides = true ) {
505 |
506 | $field_group_ids = array();
507 |
508 | foreach ( $field_groups as $field_group ) {
509 |
510 | if (
511 | ( $include_overrides || is_numeric( $field_group ) ) // include by intention or by legacy field_groups value (pre 1.2)
512 | || (
513 | ! $include_overrides // don't include overrides
514 | && is_array( $field_group ) // 1.2 or later
515 | && array_key_exists( 'has_overrides', $field_group ) && empty( $field_group['has_overrides'] ) // does not have overrides
516 | ) ) {
517 | // include it in the list
518 | $field_group_ids[] = $this->get_field_group_id( $field_group );
519 | } elseif ( is_string( $field_group ) ) {
520 | $field_group = $this->get_field_group_id_from_title( $field_group );
521 | if ( ! empty( $field_group ) ) {
522 | $field_group_ids[] = absint( $field_group );
523 | }
524 | }
525 | }
526 |
527 | return $field_group_ids;
528 | }
529 |
530 |
531 | /**
532 | * Custom Field Suite doesn't support single post IDs for placement rules, so we're going to inject our own.
533 | *
534 | * @param $matches
535 | * @param $params
536 | * @param $rule_types
537 | *
538 | * @return mixed
539 | */
540 | function cfs_rule_override( $matches, $params, $rule_types ) {
541 |
542 | if ( is_array( $params ) || ! is_numeric( $params ) ) {
543 | return $matches;
544 | }
545 |
546 | $post_id = absint( $params );
547 | $options_screen = $this->get_options_screen_from_post_id( $post_id );
548 |
549 | $matches = $this->maybe_has_overrides( $matches, $params, $rule_types, $options_screen );
550 |
551 | // let developers override the matches and parameters
552 | // maybe_has_overrides() use case: setting up 'defaults' for a Field Group - you want the
553 | // same Field Group to appear both in it's defined locations (which when defined omit it
554 | // from $matches from the start) and in the options screen to act as the defaults
555 | $matches = apply_filters( 'cfs_options_screens_rule_matches', $matches, $params, $rule_types, $this );
556 |
557 | if ( $options_screen && is_array( $matches ) && ! empty( $matches ) ) {
558 |
559 | // we need to strip out the Field Groups that are not registered with this options screen
560 | $field_group_ids = $this->get_field_group_ids( $options_screen['field_groups'] );
561 |
562 | foreach ( $matches as $match_key => $match_title ) {
563 | if ( ! in_array( $match_key, $field_group_ids ) ) {
564 | unset( $matches[ $match_key ] );
565 | }
566 | }
567 |
568 | } else {
569 |
570 | // we need to strip out all Field Groups related to Options Screens else they'll show up where we don't want them
571 | $options_screens_field_groups = array();
572 |
573 | foreach ( $this->screens as $screen_meta ) {
574 | $field_group_ids = $this->get_field_group_ids( $screen_meta['field_groups'], false );
575 | $options_screens_field_groups = array_merge( $options_screens_field_groups, $field_group_ids );
576 | }
577 |
578 | foreach ( $matches as $match_key => $match_title ) {
579 | if ( in_array( $match_key, $options_screens_field_groups ) ) {
580 | unset( $matches[ $match_key ] );
581 | }
582 | }
583 | }
584 |
585 | return $matches;
586 | }
587 |
588 | }
589 |
590 | /**
591 | * Retrieve an option from a settings screen
592 | * Usage: $value = cfs_get_option( 'options', 'my_field' );
593 | *
594 | * @param string $screen The options screen name
595 | * @param string $field The field name
596 | *
597 | * @return bool|mixed The field value as returned by the CFS API
598 | */
599 | if ( ! function_exists( 'cfs_get_option' ) ) {
600 | function cfs_get_option( $screen = 'options', $field = '', $post_id = 0 ) {
601 | $value = false;
602 |
603 | if ( ! function_exists( 'CFS' ) ) {
604 | return false;
605 | }
606 |
607 | $cfs_options_screens = CFS_Options_Screens::instance();
608 |
609 | if ( ! empty( $cfs_options_screens->screens ) ) {
610 | foreach ( $cfs_options_screens->screens as $screen_meta ) {
611 | if ( $screen == $screen_meta['name'] ) {
612 |
613 | // support the overrides concept by first checking for the override
614 | // and automatically falling back to the Options Screen value if needed
615 | $post_id = empty( $post_id ) ? get_queried_object_id() : absint( $post_id );
616 |
617 | if ( ! empty( $post_id ) ) {
618 | $value = CFS()->get( $field, absint( $post_id ) );
619 | }
620 |
621 | if ( empty( $value ) ) {
622 | $value = CFS()->get( $field, $screen_meta['id'] );
623 | }
624 |
625 | break;
626 | }
627 | }
628 | }
629 |
630 | return $value;
631 | }
632 | }
633 |
634 |
635 |
636 | /**
637 | * Retrieve all option from a settings screen
638 | * Usage: $value = cfs_get_option( 'options' );
639 | *
640 | * @param string $screen The options screen name
641 | *
642 | * @return bool|mixed The field value as returned by the CFS API
643 | */
644 | if ( ! function_exists( 'cfs_get_options' ) ) {
645 | function cfs_get_options( $screen = 'options' ) {
646 | $value = false;
647 |
648 | if ( ! function_exists( 'CFS' ) ) {
649 | return false;
650 | }
651 |
652 | $cfs_options_screens = CFS_Options_Screens::instance();
653 |
654 | if ( ! empty( $cfs_options_screens->screens ) ) {
655 | foreach ( $cfs_options_screens->screens as $screen_meta ) {
656 | if ( $screen == $screen_meta['name'] ) {
657 | $value = CFS()->get( false, $screen_meta['id'] );
658 | }
659 | }
660 | }
661 |
662 | return $value;
663 | }
664 | }
665 |
666 | /**
667 | * Initializer
668 | *
669 | * @return CFS_Options_Screens
670 | */
671 | if ( ! function_exists( 'cfs_options_screens_init' ) ) {
672 | function cfs_options_screens_init() {
673 | $cfs_options_screens = CFS_Options_Screens::instance();
674 | return $cfs_options_screens;
675 | }
676 | }
677 |
678 | // kickoff
679 | cfs_options_screens_init();
680 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | 'options',
24 | 'menu_title' => __( 'Site Options' ),
25 | 'page_title' => __( 'Customize Site Options' ),
26 | 'menu_position' => 100,
27 | 'icon' => 'dashicons-admin-generic', // optional, dashicons-admin-generic is the default
28 | 'field_groups' => array( 'My Field Group' ), // Field Group name(s) of CFS Field Group to use on this page (can also be post IDs)
29 | );
30 |
31 | return $screens;
32 | }
33 |
34 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );`
35 |
36 | = Retrieve your options like so: =
37 |
38 | `$value = cfs_get_option( 'options_screen_name', 'cfs_field_name_from_field_group' );`
39 |
40 | You can set up multiple top level and/or children options pages by adding a `parent` argument when registering your screen:
41 |
42 | `function my_cfs_options_screens( $screens ) {
43 |
44 | // Parent
45 | $screens[] = array(
46 | 'name' => 'options',
47 | 'field_groups' => array( 'My Parent Field Group Name' ),
48 | );
49 |
50 | // Child
51 | $screens[] = array(
52 | 'name' => 'options-nav',
53 | 'parent' => 'options', // name of the parent
54 | 'field_groups' => array( 'My Child Field Group Name' ),
55 | );
56 |
57 | return $screens;
58 | }
59 |
60 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );`
61 |
62 | You can also use CFS Options Screens to set up Field Group 'defaults', allowing a Field Group to appear both on a CFS Options Screen and a post edit screen. The CFS Options Screen will act as the default/fallback and the post edit screen will override those defaults.
63 |
64 | `function my_cfs_options_screens( $screens ) {
65 | $screens[] = array(
66 | 'name' => 'options',
67 | 'menu_title' => __( 'Site Options' ),
68 | 'page_title' => __( 'Customize Site Options' ),
69 | 'menu_position' => 100,
70 | 'icon' => 'dashicons-admin-generic', // optional, dashicons-admin-generic is the default
71 | 'field_groups' => array(
72 | array(
73 | 'title' => 'My CFS Field Group Name',
74 | 'has_overrides' => true,
75 | ),
76 | ),
77 | );
78 |
79 | return $screens;
80 | }
81 |
82 | add_filter( 'cfs_options_screens', 'my_cfs_options_screens' );`
83 |
84 | Check out the `cfs_options_screens_override_note_default` and `cfs_options_screens_override_note_override` filters to customize the messaging for CFS Options Screens overrides.
85 |
86 | == Installation ==
87 |
88 | 1. Upload `cfs-options-screens` to the `/wp-content/plugins/` directory
89 | 1. Activate the plugin through the 'Plugins' menu in WordPress
90 | 1. Register your options screen(s) using the code snippets from this readme
91 |
92 | == Frequently Asked Questions ==
93 |
94 | = How do I add a Field Group to my options screen? =
95 |
96 | You must specify the Field Group Title(s) in the `field_groups` parameter when using the `cfs_options_screens` hook
97 |
98 | = How do I retrieve saved options? =
99 |
100 | `$value = cfs_get_option( 'options_screen_name', 'field_name_from_field_group' );`
101 |
102 | == Changelog ==
103 |
104 | = 1.2.7 =
105 | * Add support for using CFS Field Group title instead of ID
106 |
107 | = 1.2.5 =
108 | * Better handling of overrides when not viewing a single post
109 |
110 | = 1.2.4 =
111 | * PHP Warning cleanup
112 |
113 | = 1.2.3 =
114 | * Fixed an issue that would output override note if any Field Group on an Options Screen had one
115 | * Fixed an issue where multiple override notes would be output when there were multiple override Field Groups
116 |
117 | = 1.2.1 =
118 | * PHP Warning cleanup for `cfs_get_option`
119 |
120 | = 1.2 =
121 | * Added support for Field Group defaults/overrides where a Field Group can appear both on a CFS Options Screen and a post edit screen, and 'fall back' to the CFS Options Screen where applicable
122 |
123 | = 1.1.2 =
124 | * Refined the arguments for the underlying CPT to hide it from the Admin menu, filterable with `cfs_options_screens_post_type_args`
125 |
126 | = 1.1.1 =
127 | * Fixed an issue resulting in a change in WordPress 4.4 that prevented editing options screens
128 |
129 | = 1.1 =
130 | * Added new `cfs_get_options()` function to retrieve all CFS data for an options screen
131 |
132 | = 1.0.3 =
133 | * Fixed an issue in WordPress 4.3 where customized edit screen titles were not shown
134 |
135 | = 1.0.2 =
136 | * Only show 'Saved' update notice when editing an options screen
137 |
138 | = 1.0.1 =
139 | * Proper page title is now output when editing a screen
140 |
141 | = 1.0 =
142 | * Initial release
143 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | #wpbody-content .wrap > h1,
2 | #wpbody-content .wrap > h2 {
3 | position:relative;
4 | visibility:hidden;
5 | }
6 |
7 | #wpbody-content .wrap > h1:after,
8 | #wpbody-content .wrap > h2:after {
9 | display:block;
10 | position:absolute;
11 | left:0;
12 | top:0.4em;
13 | visibility:visible;
14 | }
15 |
16 | #wpbody-content #message,
17 | #wpbody-content #minor-publishing,
18 | #wpbody-content #submitdiv .handlediv,
19 | #wpbody-content #submitdiv .hndle,
20 | #wpbody-content #delete-action,
21 | #wpbody-content #screen-meta,
22 | #wpbody-content #screen-meta-links,
23 | #wpbody-content #post-body-content {
24 | display:none;
25 | }
26 |
27 | #wpbody-content #major-publishing-actions {
28 | border-top:0;
29 | }
30 |
31 | #wpbody-content .wrap {
32 | padding-top:10px;
33 | }
34 |
--------------------------------------------------------------------------------