'Date_Picker_Custom_Control', 'layout/layout-picker' => 'Layout_Picker_Custom_Control', 'select/category-dropdown' => 'Category_Dropdown_Custom_Control', 'select/google-font-dropdown' => 'Google_Font_Dropdown_Custom_Control', 'select/menu-dropdown' => 'Menu_Dropdown_Custom_Control', 'select/post-dropdown' => 'Post_Dropdown_Custom_Control', 'select/post-type-dropdown' => 'Post_Type_Dropdown_Custom_Control', 'select/tags-dropdown' => 'Tags_Dropdown_Custom_Control', 'select/taxonomy-dropdown' => 'Taxonomy_Dropdown_Custom_Control', 'select/user-dropdown' => 'User_Dropdown_Custom_Control', 'text/textarea' => 'Textarea_Custom_Control', 'text/text-editor' => 'Text_Editor_Custom_Control' ); // 2.0.9: use apply_filters for user load of controls (default: load none) // TODO: maybe use spl_autoload_register here instead? $loadcontrols = apply_filters('options_customizer_extra_controls', array()); foreach ($customcontrols as $controlkey => $controlclass) { // 2.0.9: use file hierarchy here to allow child theme overrides if (in_array($controlkey, $loadcontrols)) { // TODO: allow for alternative includes directory ? $controlfile = bioship_file_hierarchy('file', $controlkey.'-custom-control.php', array('includes/customizer-controls')); if ($controlfile) {include($controlfile);} } } // Kirki Config URL Filter // ----------------------- if (!function_exists('bioship_customizer_kirki_url')) { // 2.1.1: move add_filter internally for consistency add_filter('kirki/config', 'bioship_customizer_kirki_url'); function bioship_customizer_kirki_url($config) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} $config['url_path'] = THEMEKIRKIURL; return $config; } } } } // ---------------------------- // === Kirki Library Loader === // ---------------------------- // ref: https://kirki.org/docs/advanced/integration.html // 2.0.9: separated loader for Kirki if (!function_exists('bioship_kirki_loader')) { function bioship_kirki_loader() { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE);} // --- check Kirki version --- // 2.0.9: added a Kirki version global (and loading filter) // 2.0.9: add PHP version test as apparently Kirki requires PHP 5.2+ global $vkirkiversion; $vkirkiversion = '3'; if (version_compare(PHP_VERSION, '5.2.0') >= 0) {$vkirkiversion = '0';} $vkirkiversion = bioship_apply_filters('options_customizer_kirki_version', $vkirkiversion); if ($vkirkiversion && ($vkirkiversion > 0)) { // TODO: allow for alternative includes directory $kirkidirs = array('includes/kirki'.$vkirkiversion, 'kirki'.$vkirkiversion, 'kirki'); $kirki = bioship_file_hierarchy('both', 'kirki.php', $kirkidirs); bioship_debug("Kirki Filepath", $kirki); } // 1.8.5: fix to Kirki check for new file hierarchy syntax if (isset($kirki) && is_array($kirki)) { // --- find and initialize Kirki --- $kirkiurlpath = str_replace('kirki.php', '', $kirki['url']); echo "***".$kirkiurlpath."***"; define('THEMEKIRKIURL', $kirkiurlpath); define('THEMEKIRKI', true); include($kirki['file']); bioship_debug("Kirki URL", THEMEKIRKIURL); // --- backwards compatible for Kirki 2 --- if ($vkirkiversion == '2') { // need to fire this right now, as we missed after_theme_setup hook..! if (function_exists('kirki_filtered_url')) {kirki_filtered_url();} // 1.8.5: not enough, must manually override to fix script paths also Kirki::$url = THEMEKIRKIURL; bioship_debug("Kirki Set URL", Kirki::$url); // as we really aren't using the Code control, remove codemirror script to avoid bloat // 1.9.5: use script loader tag filter to remove the codemirror scripts // TEMP: disabled while debugging Kirki load // if (!function_exists('bioship_customizer_remove_codemirror_scripts')) { // add_filter('script_loader_tag', 'bioship_customizer_remove_codemirror_scripts', 11, 2); // function bioship_customizer_remove_codemirror_scripts($tag, $handle) { // if (strstr($tag, 'vendor/codemirror')) {return '';} // return $tag; // } // } } } else { // 2.0.9: added a standalone multicheck control for no Kirki define('THEMEKIRKI', false); } // manually do the Kirki_Init (for Kirki 2) // ---------------------------------------- // note: as we are conditionally loading Kirki inside customize_register, // - so that Kirki is not loaded unnecessarily outside the Customizer - // so we need to fire some init actions that have already missed out on... // again fire these now, as we have missed wp_loaded also..! // 2.0.9: only do this for Kirki 2 loading if ( ($vkirkiversion == '2') && (class_exists('Kirki_Init')) ) { // (modified copy of Kirki_Init::add_to_customizer) Kirki_Init::fields_from_filters(); add_action('customizer_register', array('Kirki_Init', 'register_control_types')); // note: we are not using Kirki to add panels or sections add_action('customize_register', array('Kirki_Init', 'add_panels'), 97); add_action('customize_register', array('Kirki_Init', 'add_sections'), 98); // ...but we are definitely using the Kirki fields add_action('customize_register', array('Kirki_Init', 'add_fields'), 99); // 1.9.5: change of class name for Kirki 2.3.5 if (class_exists('Kirki_Scripts_Loading')) {new Kirki_Scripts_Loading();} elseif (class_exists('Kirki_Customizer_Scripts_Loading')) {new Kirki_Customizer_Scripts_Loading();} } // Format Filter for the Kirki Font Stacks // --------------------------------------- // note: as we are not using Kirki Typography Control, do not need this yet if (!function_exists('bioship_customizer_kirki_font_stacks')) { add_filter('kirki/fonts/standard_fonts', 'bioship_customizer_kirki_font_stacks'); function bioship_customizer_kirki_font_stacks() { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__);} $fonts = bioship_options_web_font_stacks(array()); $fontstacks = array(); foreach ($fonts as $fontstack => $display) { // format: array['fontkey'] = array('label' => 'font', 'stack' => 'stack')); // note: it looks like fontkey should be the first 'font' in the stack for Kirki ? // 1.9.8: fix to fontstack and label variable typos // 2.0.9: refix to fontstacks array variable typo $fontstacks[$fontstack] = array('label' => $display, 'stack' => $fontstack); } return $fontstacks; } } // Format Filter for the Kirki Google Fonts // ---------------------------------------- // [not implemented] as not using Kirki Typography Control, do not need this... if (!function_exists('bioship_customizer_kirki_google_fonts')) { add_filter('kirki/fonts/google_fonts', 'bioship_customizer_kirki_google_fonts'); function bioship_customizer_kirki_google_fonts($kirkifonts) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} $fonts = bioship_options_title_fonts(); $googlefonts = array(); foreach ($fonts as $font => $display) { // TODO: Google font variants / subsets / categories for Kirki ? $googlefonts[$font] = array( 'label' => $display, 'variants' => array(), 'subsets' => array(), 'category' => array() ); } return $googlefonts; } } // Stylize the Customizer with Kirki // --------------------------------- // ref: https://kirki.org/docs/advanced/styling-the-customizer.html if (!function_exists('bioship_customizer_kirki_styling')) { add_filter('kirki/config', 'bioship_customizer_kirki_styling'); function bioship_customizer_kirki_styling($config) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} // --- set custom loading logo image --- // 1.9.9: cache logo value to prevent multiple hierarchy calls // 2.1.1: removed unnecessary global declaration of customlogoimage if (!isset($customlogoimage)) { // 2.0.9: extend possible logo image paths to icons and assets/img $imagepaths = array('', 'images', 'img', 'icons', 'assets/img'); $customlogoimage = bioship_file_hierarchy('url', 'theme-logo.png', $imagepaths); } // --- set preview notice --- $previewnotice = ''; $previewnotice .= sprintf( __('You are customizing %s', 'bioship'), ''.get_bloginfo('name').''); $previewnotice .= ''; // --- filter the config options --- $config['description'] = bioship_apply_filters('options_customizer_description', $previewnotice); $config['logo_image'] = bioship_apply_filters('options_customizer_logo_image', $customlogoimage); $config['color_accent'] = bioship_apply_filters('options_customizer_color_accent', '#99BBDD'); $config['color_back'] = bioship_apply_filters('options_customizer_color_back', '#E0E0EE'); $config['width'] = bioship_apply_filters('options_customizer_panel_width', '20%'); return $config; } } // load Kirki Internationalization Filter // -------------------------------------- // 1.8.5: added this filter // 1.9.9: load as filter as intended add_filter('kirki/bioship/l10n', 'bioship_customizer_i10n'); // maybe use Fallback Customizer Styling Class // ------------------------------------------- // 2.0.9: add this for if Kirki is not loaded if (!THEMEKIRKI) { global $vthemedirs; // loads Kirki_Modules_Customizer_Styling and ariColor classes $styling = bioship_file_hierarchy('file', 'styling.php', $vthemedirs['admin']); if ($styling) {include($styling); new Kirki_Modules_Customizer_Styling();} } } } // ----------------------- // Add Info Custom Control // ----------------------- if (!function_exists('bioship_customizer_register_info_control')) { function bioship_customizer_register_info_control() { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__);} // --- declare Info Control Class --- // control class outputs label and description for info/note option type // ...also used to echo expand/collapse links for Typography Controls class Info_Custom_Control extends WP_Customize_Control { public function render_content() { echo ''; } } // --- load info control script in the footer --- // 2.0.9: moved here from functions.php loading add_action('customize_controls_print_footer_scripts', 'bioship_customizer_font_script'); // --- register info control via Kirki --- // note: before initializing Kirki if (!function_exists('bioship_add_control_types')) { add_filter('kirki/control_types', 'bioship_kirki_add_info_control'); function bioship_kirki_add_info_control($controls) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} $controls['info'] = $controls['note'] = 'Info_Custom_Control'; return $controls; } } } } // ------------------------------- // Add a Multicheck Custom Control // ------------------------------- // 2.0.9: standalone multicheck controller (via Titan Framework) if (!function_exists('bioship_customizer_register_multicheck_control')) { function bioship_customizer_register_multicheck_control() { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__);} class Multicheck_Custom_Control extends WP_Customize_Control { public $description; public $options; public function render_content() { // the saved value is an array, convert it to csv $savedValueCSV = ''; if (is_array($this->value())) { $savedvalues = array(); foreach ($this->value() as $key => $value) { if ($value == '1') {$savedvalues[] = $key;} } if (count($savedvalues) > 1) {$savedValueCSV = (string)implode(',', $savedvalues);} elseif (count($savedvalues) == 1) {$savedValueCSV = (string)$savedvalues[0];} $values = $savedvalues; } else { $savedValueCSV = (string)$this->value(); $values = explode(',', $this->value()); } $description = ''; if (!empty($this->description)) { $description = '
'.$this->description.'
'; } echo ''; } } // --- load multicheck control script in footer --- // 2.0.9: load control script in footer add_action('customize_controls_print_footer_scripts', 'bioship_customizer_multicheck_script'); // --- register multicheck control via Kirki --- // note: before initializing Kirki if (!function_exists('bioship_add_control_types')) { add_filter('kirki/control_types', 'bioship_kirki_add_multicheck_control'); function bioship_kirki_add_multicheck_control($controls) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} $controls['multicheck'] = 'Multicheck_Custom_Control'; return $controls; } } } } // ------------------------------------ // === Register Customizer Controls === // ------------------------------------ if (!function_exists('bioship_customizer_load_control_options')) { function bioship_customizer_load_control_options($wp_customize) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} global $vthemesettings, $vthemename, $vthemeoptions; global $vkirkiversion, $typocontrolids, $controllerids; // --- check which options to show --- // 1.9.9: show only basic options only in customizer by default $optionspage = 'basic'; if (isset($_REQUEST['options']) && ($_REQUEST['options'] == 'advanced')) {$optionspage = 'advanced';} if (isset($_REQUEST['options']) && ($_REQUEST['options'] == 'all')) {$optionspage = 'all';} bioship_debug("Customizer Options Page Value", $optionspage); // --- check if splitting options --- // 1.9.9: filter whether to split options // 2.1.1: moved outside of below loop to check once only $splitoptions = bioship_apply_filters('options_customizer_split_options', true); // Convert all options to Layer Options // ------------------------------------ $i = $j = $k = $l = $m = 0; foreach ($vthemeoptions as $optionkey => $optionvalues) { // --- set skip keys for WordPress.Org version --- // 2.0.9: avoid duplicate settings for custom theme supports $skip = false; if (THEMEWPORG) { global $wp_version; $skipkeys = array( // --- Custom Background (custom_background) 'background_image' => '', 'background_position' => '', 'background_size' => '', 'background_repeat' => '', 'background_attachment' => '', // --- Custom Logo (custom_logo) --- 'header_logo' => '4.5-alpha', // --- Custom Header (custom_header) --- // note: support feature mismatch* // 'header_background_image' => '', // 'header_background_position' => '', // 'header_background_size' => '', // 'header_background_repeat' => '', ); foreach ($skipkeys as $skipkey => $wpversion) { if ($optionkey == $skipkey) { if ($wpversion != '') { if (version_compare($wp_version, $wpversion, '<')) {$skip = true;} // '> } else {$skip = true;} } } } if (!$skip) { // --- set option class layers --- // 1.8.5: fix heading type (missing class) if using Options Framework $layers = array('skin', 'muscle', 'skeleton'); if (isset($optionvalues['id'])) { if (in_array($optionvalues['id'], $layers)) { $optionvalues['class'] = $optionvalues['id']; $optionvalues['id'] = $optionvalues['name']; } if (THEMEDEBUG) {echo "";} } // --- check page display --- // 1.9.9: check new customizer page display value if (isset($optionvalues['page'])) {$forpage = $optionvalues['page'];} else { $forpage = 'both'; if (THEMEDEBUG) {echo '';} } // --- check Customizer page conditions --- // 1.9.9: match conditions for this customizer page if (!$splitoptions || ($optionspage == 'all') || ($forpage == 'both') || ( ($forpage == 'basic') && ($optionspage == 'basic') ) || ( ($forpage == 'advanced') && ($optionspage == 'advanced') ) ) { if (strstr($optionvalues['class'], 'skin')) {$skinoptions[$i] = $optionvalues; $i++;} elseif (strstr($optionvalues['class'], 'muscle')) {$muscleoptions[$j] = $optionvalues; $j++;} elseif (strstr($optionvalues['class'], 'skeleton')) {$skeletonoptions[$k] = $optionvalues; $k++;} else {$hiddenoptions[$l] = $optionvalues; $l++;} } } } // --- debug layer options --- // 2.0.9: use simpler debug function bioship_debug("Skin Options", $skinoptions); bioship_debug("Muscle Options", $muscleoptions); bioship_debug("Skeleton Options", $skeletonoptions); bioship_debug("Hidden Options", $hiddenoptions); // --- Settings Default Types --- $defaulttypes = array('checkbox', 'textarea', 'radio', 'select', 'page-dropdown', 'text', 'hidden'); $typography = array('color', 'font-size', 'font-family', 'font-style'); // --- Set Settings Prefix --- if (THEMEOPT) {$settingsprefix = THEMEKEY.'_customize';} else {$settingsprefix = str_replace('_options', '_customize', THEMEKEY);} // --- Create Copy of Theme Options --- // ...(re)set a dummy unserialized array - for use by the Customizer only... delete_option($settingsprefix); add_option($settingsprefix, $vthemesettings); // --- extra Typography options for Titan --- if (!THEMEOPT) { $typography[] = 'font-weight'; $typography[] = 'line-height'; $typography[] = 'letter-spacing'; $typography[] = 'text-transform'; $typography[] = 'font-variant'; // --- add typography options --- // (from titan/includes/class-option-font.php) $titantypography = array(); $titantypography['websafefonts'] = bioship_options_web_font_stacks(array()); $titantypography['googlefonts'] = bioship_options_title_fonts(); $titantypography['allfonts'] = array_merge($titantypography['websafefonts'], $titantypography['googlefonts']); $fontsizeoptions[] = 'inherit'; // 1.8.5: doubled choice arrays to value-label pairs for ($n = 1; $n <= 150; $n++) {$fontsizeoptions[$n.'px'] = $n.'px';} $titantypography['font-size'] = $fontsizeoptions; $titantypography['font-weight'] = array('normal' => 'normal', 'bold' => 'bold', 'bolder' => 'bolder', 'lighter' => 'lighter', '100' => '100', '200' => '200', '300' => '300', '400' => '400', '500' => '500', '600' => '600', '700' => '700', '800' => '800', '900' => '900'); $titantypography['font-style'] = array('normal' => 'normal', 'italic' => 'italic'); for ($n = .5; $n <= 3; $n += 0.1) {$lineheightoptions[$n.'em'] = $n.'em';} $titantypography['line-height'] = $lineheightoptions; // --- letter spacing, text transform, font variant --- for ($n = -20; $n <= 20; $n++) {$letterspacingoptions[$n.'px'] = $n.'px';} $titantypography['letter-spacing'] = $letterspacingoptions; $titantypography['text-transform'] = array('none' => 'none', 'capitalize' => 'capitalize', 'uppercase' => 'uppercase', 'lowercase' => 'lowercase'); $titantypography['font-variant'] = array('normal' => 'normal', 'small-caps' => 'small-caps'); // note: there are text shadow options also(not implemented) } // --- set Typography Sanitization Callbacks --- // 1.8.5: added these sanitization fallbacks $typosanitize['color'] = 'bioship_fallback_sanitize_color'; $typosanitize['font-size'] = 'bioship_fallback_sanitize_css_size'; $typosanitize['font-family'] = 'bioship_fallback_sanitize_select'; $typosanitize['font-style'] = 'bioship_fallback_sanitize_select'; $typosanitize['font-weight'] = 'bioship_fallback_sanitize_css_size'; $typosanitize['line-height'] = 'bioship_fallback_sanitize_css_size'; $typosanitize['letter-spacing'] = 'bioship_fallback_sanitize_css_size'; $typosanitize['text-transform'] = 'bioship_fallback_sanitize_select'; $typosanitize['font-variant'] = 'bioship_fallback_sanitize_select'; // --- Set Kirki basic config --- // (probably not even need to do this but what the heck...) // 1.8.5: added disable_output argument for Kirki update if (class_exists('Kirki')) { Kirki::add_config('bioship', array( 'capability' => 'edit_theme_options', 'option_type' => 'option', 'option_name' => $settingsprefix, 'disable_output' => true) ); } // Modify Customize Sections // ------------------------- $wp_customize->get_section('themes')->priority = 999; // shift to bottom $wp_customize->get_section('title_tagline')->title = __('Site Options', 'bioship'); // generalize $wp_customize->get_section('title_tagline')->priority = 10; // set live preview transport to postMessage for title and tagline $wp_customize->get_setting('blogname')->transport = 'postMessage'; $wp_customize->get_setting('blogdescription')->transport = 'postMessage'; // 2.0.9: always remove header_image theme support (background header image mismatch) $wp_customize->remove_section('header_image'); // --- split off some advanced options --- // 1.9.9: clear basic sections (from advanced options page only) if ($optionspage == 'advanced') { // -- remove some sections --- $wp_customize->remove_section('title_tagline'); $wp_customize->remove_section('themes'); // 2.0.8: only remove unused sections from advanced page (for WordPress.org compliance) $wp_customize->remove_section('colors'); $wp_customize->remove_section('background_image'); // --- remove widgets and nav menus from advanced options --- // 2.0.9: remove widgets section from advanced page // 2.1.1: use filter instead of remove_panel // $wp_customize->remove_panel('widgets'); // $wp_customize->remove_panel('nav_menus'); if (!function_exists('bioship_customizer_advanced_remove_panels')) { add_filter('customize_loaded_components', 'bioship_customizer_advanced_remove_panels'); function bioship_customizer_advanced_remove_panels($components) { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__,func_get_args());} $remove = array('widgets', 'nav_menus'); if (count($components) > 0) { foreach ($components as $i => $component) { if (in_array($component, $remove)) {unset($components[$i]);} } } return $components; } } } // --- custom CSS section --- if ( ($optionspage == 'advanced') || !THEMEWPORG) { // 2.0.5: remove new custom CSS section (not implemented) // TODO: maybe synchronize custom CSS control with existing theme option ? $wp_customize->remove_section('custom_css'); } // --- Customize Default Sections --- // neatness: move static_front_page controls to a title_tagline 'section' $wp_customize->get_control('show_on_front')->section = 'title_tagline'; $wp_customize->get_control('page_on_front')->section = 'title_tagline'; $wp_customize->get_control('page_for_posts')->section = 'title_tagline'; $wp_customize->remove_section('static_front_page'); // remove section // --- Handle Kirki Control names --- $prefixedcontrols = $ignorecontrols = $kirkicontrols = array(); if ($vkirkiversion == '2') {$kirkicontrols = bioship_kirki_control_types();} elseif ($vkirkiversion == '3') { $kirkicontrols = apply_filters('kirki/control_types', array()); // 2.0.9: set to ignore Kirki 3 controls that are not working properly $ignorecontrols = array('select', 'multicheck'); } // 2.0.9: check kirki- prefixed controls if (count($kirkicontrols) > 0) { foreach ($kirkicontrols as $key => $controlclass) { if (substr($key, 0, strlen('kirki-')) == 'kirki-') { $prefixedcontrols[] = str_replace('kirki-', '', $key); } } } bioship_debug("Kirki Controls", $kirkicontrols); bioship_debug("Prefixed Controls", $prefixedcontrols); // Loop through the Layer Options // ------------------------------ for ($i = 0; $i < 3; $i++) { // --- Set Data for this Layer Panel --- $theseoptions = array(); if ($i == 0) { $theseoptions = $skinoptions; $panelslug = 'skinoptions'; $args = array('title' => __('Skin Options','bioship'), 'priority' => 180); $args['description'] = __('All the Skin Layer Options','bioship'); } elseif ($i == 1) { $theseoptions = $muscleoptions; $panelslug = 'muscleoptions'; $args = array('title' => __('Muscle Options','bioship'), 'priority' => 190); $args['description'] = __('All the Muscle Layer Options','bioship'); } elseif ($i == 2) { $theseoptions = $skeletonoptions; $panelslug = 'skeletonoptions'; $args = array('title' => __('Skeleton Options','bioship'), 'priority' => 200); $args['description'] = __('All the Skeleton Layer Options','bioship'); } // note: no nede ti handle the hidden options as only changed values are saved bioship_debug("Panel", $panelslug); bioship_debug("Panel Options", $theseoptions); // --- Add the Layer Panel --- $wp_customize->add_panel($panelslug, $args); // Kirki::add_panel($panelslug, $args); // not working! // Loop through Layer Options // -------------------------- $typocontrols = $sectionpriority = 10; $types = array(); foreach ($theseoptions as $thisoption) { bioship_debug("Option Type", $thisoption['type']); $controltypes = array(); if (!in_array($thisoption['type'], $types)) {$types[] = $thisoption['type'];} // Add a Customizer Section for each Heading // ----------------------------------------- if ($thisoption['type'] == 'heading') { // --- convert heading to section --- bioship_debug("Customizer Section", $thisoption); $sectionslug = $vthemename.'_'.strtolower($thisoption['name']); $args = array('panel' => $panelslug, 'title' => $thisoption['name'], 'priority' => $sectionpriority); if (isset($thisoption['desc'])) {$args['description'] = $thisoption['desc'];} $wp_customize->add_section($sectionslug, $args); // Kirki::add_section($sectionslug, $args); // not working $sectionpriority++; $priority = 10; } elseif ( ($thisoption['type'] == 'typography') || ($thisoption['type'] == 'font') ) { // Typography Controls // ------------------- // - Kirki Library Typography Control ? // - Justin Tadlocks Customizer-Typography prototype ? // - Titan Framework Typography Control ? // - Google_Font_Dropdown_Custom_Control ? // ...going for individual controls with expand/collapse... // Add a simple info type 'setting' and 'control' as a Typography label header $settingid = $settingsprefix.'['.$thisoption['id'].']'; $settingargs = array('type' => 'option', 'capability' => 'edit_theme_options'); $controlargs = array('type' => 'info', 'priority' => $priority, 'section' => $sectionslug, 'label' => $thisoption['name'], 'description' => $thisoption['desc'], 'setting' => $settingid ); // TONOTDO: maybe adapt a Kirki Typography control to Titan Typography? // - not used as currently the settings do not quite match up correctly // if (class_exists('Kirki')) { // $controlargs['type'] = 'typography'; // $args = array_merge($settingargs, $controlargs); // Kirki::add_field('bioship', $args); // } // else { // Typography Expand/Collapse // -------------------------- // this is a kind of dummy Control wrapper using our Info Control // to show/hide all the typography options for a particular element // Set subcontroller element list for javascript expand/collapse $j = 0; $typocontrolids[$typocontrols] = $thisoption['id']; foreach ($typography as $typooption) { $typocontrolid = 'customize-control-'.$settingsprefix.'-'.$thisoption['id'].'-'.$typooption; $controllerids[$thisoption['id']][$j] = $typocontrolid; $j++; } $controlargs['description'] = 'typography_controller'; $typocontrols++; // --- add the Info Control to echo the expand/collapse javascript --- $typoid = $settingid.'[helper]'; // dummy option // 2.0.7: fix dummy sanitization callback for requirement check $wp_customize->add_setting($typoid, array( 'type' => $settingargs['type'], 'capability' => $settingargs['capability'], 'sanitize_callback' => 'bioship_fallback_sanitize_unfiltered' ) ); $wp_customize->add_control(new Info_Custom_Control($wp_customize, $typoid, $controlargs)); $priority++; // Loop through the Typography options // ----------------------------------- foreach ($typography as $typooption) { $default = ''; // TODO: check for Options Framework specifically instead ? if (!THEMETITAN) { // --- set to Options Framework typography defaults --- if ($typooption == 'color') {$default = $thisoption['std']['color'];} elseif ($typooption == 'font-size') {$default = $thisoption['std']['size'];} elseif ($typooption == 'font-family') {$default = $thisoption['std']['font'];} elseif ($typooption == 'font-style') {$default = $thisoption['std']['style'];} $choices = array(); // TODO: recheck font control size value consistency (without Titan) $choices['font-size'] = $thisoption['options']['sizes']; $choices['font-family'] = $thisoption['options']['faces']; $choices['font-style'] = $thisoption['options']['styles']; // note: color option always assumed to be true here } else { // --- set choices to the Titan typography options --- if (isset($thisoption['default'][$typooption])) {$default = $thisoption['default'][$typooption];} $choices = $titantypography; // note: just assume value to be false if set if (isset($thisoption['show_websafe_fonts'])) {$fontoptions = $titantypography['googlefonts'];} elseif (isset($thisoption['show_google_fonts'])) {$fontoptions = $titantypography['websafefonts'];} else {$fontoptions = $titantypography['allfonts'];} $choices['font-family'] = $fontoptions; } // --- set default fallback values --- if ($default == '') { if ($typooption == 'color') {$default = '#999999';} if ($typooption == 'font-family') { foreach ($choices['font-family'] as $fontkey => $fontlabel) { $default = $fontkey; continue; // use first font as default } } if ($typooption == 'font-size') {$default = '14px';} if ($typooption == 'font-weight') {$default = 'normal';} if ($typooption == 'font-style') {$default = 'normal';} if ($typooption == 'line-height') {$default = '1.4em';} if ($typooption == 'letter-spacing') {$default = '0px';} if ($typooption == 'font-variant') {$default = 'normal';} if ($typooption == 'text-transform') {$default = 'none';} } // --- setup Setting and Control Arguments --- $settingid = $settingsprefix.'['.$thisoption['id'].']['.$typooption.']'; $settingargs = array('type' => 'option', 'capability' => 'edit_theme_options', 'default' => $default, 'transport' => 'postMessage'); $label = str_replace('-',' ',$typooption); $label = strtoupper(substr($label, 0, 1)).substr($label, 1, strlen($label)); $controlargs = array('type' => 'select', 'priority' => $priority, 'section' => $sectionslug, 'label' => $label, 'description' => '', 'setting' => $settingid); // 1.8.5: set default typography sanitization callbacks $settingargs['sanitize_callback'] = $typosanitize[$typooption]; // -- add this Typography Customizer Setting and Control --- // 2.0.7: fix to for sanitization callback requirement check $wp_customize->add_setting($settingid, array( 'type' => $settingargs['type'], 'capability' => $settingargs['capability'], 'default' => $settingargs['default'], 'transport' => $settingargs['transport'], 'sanitize_callback' => $settingargs['sanitize_callback'] ) ); // $value = $wp_customize->get_setting($settingid)->value(); // debug point // typography control styling // TODO: fix this? the right styling - but it is just being completely ignored? :-/ // $controlargs['input_attrs'] = array('style' => 'float:right; margin-top:-30px;'); // --- add the Customizer Control --- if ($typooption == 'color') { $controlargs['type'] = 'color'; // use color picker control here not select $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, $settingid, $controlargs)); } else { $controlargs['choices'] = $choices[$typooption]; $wp_customize->add_control($settingid, $controlargs); } $priority++; } // } // close unused Kirki Typography check } else { // --- get option type --- $type = $thisoption['type']; // --- set setting ID --- if ( ($type == 'info') || ($type == 'note') ) {$settingid = $settingsprefix."[info]";} // dummy value else {$settingid = $settingsprefix."[".$thisoption['id']."]";} // --- set option default --- if (isset($thisoption['default'])) {$default = $thisoption['default'];} elseif (isset($thisoption['std'])) {$default = $thisoption['std'];} else {$default = '';} // clear for loop if default is empty // --- set settings args --- $settingargs = array('type' => 'option', 'capability' => 'edit_theme_options', 'default' => $default, 'transport' => 'postMessage'); bioship_debug("Control Settings", $settingargs); // note: set to postMessage by default to prevent unnecessary page refreshes // (only layout options and script loads should really force a refresh - // these are defined in the options array by setting transport to refresh) // --- set control transport --- if ( (isset($thisoption['transport'])) && ($thisoption['transport'] == 'refresh') ) {$settingargs['transport'] = 'refresh';} // this one not used here, but included for completeness anyway if (isset($thisoption['theme_supports'])) {$settingargs['theme_supports'] = $thisoption['theme_supports'];} // setup Customizer Control for each Option // ---------------------------------------- // standard inputs: checkbox, radio, text, textarea, select // non-standard: info/note, color, multicheck $controlargs = array('type' => $type, 'priority' => $priority, 'section' => $sectionslug, 'label' => $thisoption['name'], 'description' => $thisoption['desc'], 'setting' => $settingid); // --- set options to choices for multiple choice input types --- if (isset($thisoption['options'])) { // 2.0.9: set options key as well for cross-control compatability $controlargs['choices'] = $controlargs['options'] = $thisoption['options']; } // [not working] set input attributes for some default input types... // it seems like the 'style' attribute here does absolutely nothing! // note: class and placeholder fields have not been tested here yet... // eg... 'input_attrs' => array('class' => '', 'style' => '', 'placeholder' => ''); if ($type == 'textarea') {$thisoption['input_attrs']['style'] = 'height:300px;';} // ...allow for predefined option-specific override too... if (isset($thisoption['input_attrs'])) {$controlargs['input_attrs'] = $thisoption['input_attrs'];} // --- maybe set active_callback argument --- // note: postMessage and active_callback are mutually exclusive methods // because active_callback relies on using the refresh transport... // for the now not using active_callback argument anyway... so whatevs // ref: comments on http://ottopress.com/2015/whats-new-with-the-customizer/ if (isset($thisoption['active_callback'])) {$controlargs['active_callback'] = $thisoption['active_callback'];} // --- maybe set sanitization_callback override --- // 1.8.5: allow for explicit sanitization callback override if (isset($thisoption['sanitize_callback'])) {$settingsargs['sanitize_callback'] = $thisoption['sanitize_callback'];} // --- Kirki controls recheck --- // 2.0.9: make sure the matching control type explicitly still exists in Kirki if ( class_exists('Kirki') && !in_array($type, $ignorecontrols) && (in_array($type, $kirkicontrols) || in_array($type, $prefixedcontrols)) ) { // --- use Kirki Controls for the option fields --- // 2.0.9: fix for Kirki 3: maybe add the kirki- prefix to control type if ( ($kirkiversion == '3') && (in_array($type, $prefixedcontrols)) ) { $controlargs[$type] = 'kirki-'.$type; } bioship_debug("Kirki Control", $kirkicontrols[$controlargs[$type]]); // --- option to use a help icon instead of full description --- if ( (isset($thisoption['help'])) && ($thisoption['help']) ) { $controlargs['help'] = $controlargs['description']; unset($controlargs['description']); } // note Kirki extra options: output, js_vars, required // but Kirki documentation is still a bit sketchy on their usage // 1.8.5: fix for 'type' conflict - as already set by Kirki config // 1.9.8: but only attempt unset if array index is already set if (isset($settingargs['type'])) {unset($settingargs['type']);} if (isset($settingargs['capability'])) {unset($settingargs['capability']);} $controlargs = array_merge($settingargs, $controlargs); // 1.9.5: do not use settingsprefix for Kirki 2.3.5 update $controlargs['setting'] = $thisoption['id']; // 2.0.9: set settings key (plural) for option ID $controlargs['settings'] = $thisoption['id']; bioship_debug("Kirki Field", $controlargs); Kirki::add_field(THEMEPREFIX, $controlargs); } else { // --- fallbacks to default Customizer Controls --- // 1.8.5: only for when Kirki is not loaded // 2.0.7: fix to key setting typo (sanitization_callback) if (!isset($settingargs['sanitize_callback'])) { $callback = ''; if ( ($type == 'info') || ($type == 'note') || ($type == 'hidden') || ($type == 'code') ) { $callback = 'bioship_fallback_sanitize_unfiltered'; } elseif ($type == 'select') {$callback = 'bioship_fallback_sanitize_select';} elseif ( ($type == 'radio') || ($type == 'images') || ($type == 'radio-images') ) {$callback = 'bioship_fallback_sanitize_radio';} elseif ($type == 'checkbox') {$callback = 'bioship_fallback_sanitize_checkbox';} elseif ($type == 'multicheck') {$callback = 'bioship_fallback_sanitize_multicheck';} elseif ( ($type == 'color') || ($type == 'colorpicker') || ($type == 'color-palette') ) {$callback = 'bioship_fallback_sanitize_color';} elseif ( ($type == 'rgba') || ($type == 'color-alpha') ) {$callback = 'bioship_fallback_sanitize_rgba';} elseif ( ($type == 'upload') || ($type == 'image') || ($type == 'audio') ) {$callback = 'bioship_fallback_sanitize_url';} elseif ($type == 'page-dropdown') {$callback = 'bioship_fallback_sanitize_pagedropdown';} elseif ($type == 'textarea') {$callback = 'bioship_fallback_sanitize_textarea';} elseif ($type == 'text') {$callback = 'bioship_fallback_sanitize_unfiltered';} if (THEMEDEBUG && ($callback == '')) { echo ""; } $settingargs['sanitize_callback'] = $callback; } // --- add the Customizer Setting --- // 2.0.7: fix to for sanitization callback requirement check $wp_customize->add_setting($settingid, array( 'type' => $settingargs['type'], 'capability' => $settingargs['capability'], 'default' => $settingargs['default'], 'sanitize_callback' => $settingargs['sanitize_callback'] ) ); // --- add the Customizer Control --- if (!in_array($type, $defaulttypes)) { // --- info / note --- if ( ($type == 'info') || ($type == 'note') ) { // use our simple Info control class to output the label and description text $wp_customize->add_control(new Info_Custom_Control($wp_customize, $settingid, $controlargs)); } // --- color / colorpicker --- if ( ($type == 'color') || ($type == 'colorpicker') ) { $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, $settingid, $controlargs)); } // --- upload / image --- if ( ($type == 'upload') || ($type == 'image') ) { // TEST: could test the various image control options here... // add/modify one that also allows for simply pasting an URL as well?! // note: one cool idea is to add a *context* to the uploaded images also: // ref: https://gist.github.com/eduardozulian/4739075 if (class_exists('WP_Customize_Media_Control')) { if ($type == 'image') {$args['mime_type'] = 'image';} // note: WP 4.1+ ... so maybe use version_compare? $wp_customize->add_control(new WP_Customize_Media_Control($wp_customize, $settingid, $controlargs)); } elseif ($type == 'upload') { $wp_customize->add_control(new WP_Customize_Upload_Control($wp_customize, $settingid, $controlargs)); } elseif ($type == 'image') { $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, $settingid, $controlargs)); } } // --- audio upload --- elseif ($type == 'audio') { // not used here anyways, but added just for good old reference sake // $wp_customize->add_control(new WP_Customize_Upload_Control($wp_customize, $settingid, $controlargs)); $controlargs['mime_type'] = 'audio'; // note: WP 4.1+ ... so maybe use version_compare ? $wp_customize->add_control(new WP_Customize_Media_Control($wp_customize, $settingid, $controlargs)); } // --- multicheck --- if ($type == 'multicheck') { // this is (was) the Multicheck Control from Hybrid Core... // since a multicheck control is not a default WordPress one - madness! // ...but Hybrid Customize multicheck control not working either? :-/ // $wp_customize->add_control(new Hybrid_Customize_Control_Checkbox_Multiple($wp_customize, $settingid, $controlargs)); // 2.0.9: add standalone multicheck control class here instead $wp_customize->add_control(new Multicheck_Custom_Control($wp_customize, $settingid, $controlargs)); } // --- textarea --- if ($type == 'textarea') { // replacement textarea control, but should be fine either way if (class_exists('Textarea_Custom_Control')) { $wp_customize->add_control(new Textarea_Custom_Control($wp_customize, $settingid, $controlargs)); } else {$wp_customize->add_control($settingid, $args);} } // if ( ($type == 'images') || ($type == 'radio-image') ) { // note plural images, singular image type is for an image upload // TEST: use the Hybrid radio-images Control here? // $wp_customize->add_control(new Hybrid_Customize_Control_Radio_Image($wp_customize, $settingid, $controlargs)); // } } else { // --- fallback to adding a standard control type --- $wp_customize->add_control($settingid, $controlargs); } } $priority++; } } } bioship_debug("Customizer Control Types", $controltypes); bioship_debug("Control Types Used", $types); bioship_debug("WP CUSTOMIZE OBJECT", $wp_customize); if (isset($missingsanitize)) {bioship_debug("Missing Sanitization", $missingsanitize);} // IDEA: maybe add Theme Pro Upgrade Link // (if/when there is a Premium Theme version) // $settingid = 'customizer_link'; // $wp_customize->add_setting($settingid, array( // 'type' => 'option', // 'capability' => 'edit_theme_options', // 'default' => '' // 'sanitize_callback' => 'bioship_fallback_sanitize_unfiltered' // ) ); // $label = ''; $description = __('Upgrade Theme','bioship'); // $args = array('type' => 'info', 'priority' => '210', 'label' => $label, 'description' => $description, 'setting' => $settingid); // $wp_customize->add_control(new Info_Custom_Control($wp_customize, $settingid, $args)); // well, that is just about enough of that nonsense! // ------------------------------------------------- } } // --------------------------------- // Update the Customizer Description // --------------------------------- // there really should be a core filter for this text... TRAC? if (!function_exists('bioship_customizer_text_script')) { function bioship_customizer_text_script() { if (THEMETRACE) {bioship_trace('F',__FUNCTION__,__FILE__);} // --- add Kirki styling for non-Kirki --- // 2.0.9: consistency display fix for no Kirki loading (via Kirki branding.js) if (!THEMEKIRKI) { $config = bioship_customizer_kirki_styling(array()); echo ""; } // --- just some rogue panel separators and styling --- $styles = "#accordion-panel-skinoptions, #accordion-section-title_tagline {border-top: 20px solid #F0F0F0 !important;} #accordion-panel-skeletonoptions {border-bottom: 20px solid #F0F0F0 !important;} #customize-theme-controls .accordion-section-content {background-color: #E0E0EE !important;} #customize-info .customize-panel-description {background-color: #FDFDFF !important;} #customize-controls .customize-info {margin-bottom:0px !important;} #customize-info .customize-help-toggle {margin-top: 70px;}"; // 1.9.9: enforce panel views for advanced options page (prevent auto-hiding glitch) if ( (isset($_REQUEST['options'])) && ($_REQUEST['options'] == 'advanced') ) { $styles .= PHP_EOL."#accordion-panel-nav_menus {display: none !important;} #accordion-panel-skinoptions, #accordion-panel-skinoptions ul li, #accordion-panel-muscleoptions, #accordion-panel-muscleoptions ul li, #accordion-panel-skeletonoptions, #accordion-panel-skeletonoptions ul li {display:block !important;}"; } // --- filter and output styles --- // 1.8.5: added a style rule filter here $styles = bioship_apply_filters('options_customizer_extra_styles', $styles); echo "".PHP_EOL; // --- change Customizer title message --- // default: 'The Customizer allows you to preview changes to your site before publishing them. You can also navigate to different pages on your site to preview them.