├── footer.php ├── functions.php ├── header.php ├── images ├── 1col.png ├── 2cl.png └── 2cr.png ├── inc ├── css │ └── optionsframework.css ├── images │ └── ico-delete.png ├── includes │ ├── class-options-framework-admin.php │ ├── class-options-framework.php │ ├── class-options-interface.php │ ├── class-options-media-uploader.php │ └── class-options-sanitization.php ├── js │ ├── media-uploader.js │ └── options-custom.js └── options-framework.php ├── index.php ├── license.txt ├── options.php ├── readme.md ├── screenshot.png └── style.css /footer.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 17 | * tag of your theme, or you will break many plugins, which 18 | * generally use this hook to reference JavaScript files. 19 | */ 20 | 21 | wp_footer(); 22 | ?> 23 | 24 | 25 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | 26 | 27 | 40 | 41 | 7 | > 8 | 9 | 10 | Options Framework Theme 11 | 12 | 13 | 14 | 15 | > 16 | 17 |
-------------------------------------------------------------------------------- /images/1col.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devinsays/options-framework-theme/10eef1860dd9b9f4dd88932798e1926aaf1d305a/images/1col.png -------------------------------------------------------------------------------- /images/2cl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devinsays/options-framework-theme/10eef1860dd9b9f4dd88932798e1926aaf1d305a/images/2cl.png -------------------------------------------------------------------------------- /images/2cr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devinsays/options-framework-theme/10eef1860dd9b9f4dd88932798e1926aaf1d305a/images/2cr.png -------------------------------------------------------------------------------- /inc/css/optionsframework.css: -------------------------------------------------------------------------------- 1 | /* Options Framework Admin Styles */ 2 | 3 | #optionsframework { 4 | max-width:840px; 5 | background:#fff; 6 | } 7 | #optionsframework h3 { 8 | cursor: default; 9 | background-color: #f1f1f1; 10 | border-bottom: 1px solid #ddd; 11 | padding: 12px 10px; 12 | margin: 0; 13 | } 14 | #optionsframework p { 15 | margin-bottom:0; 16 | padding-bottom:10px; 17 | } 18 | #optionsframework .section { 19 | padding:10px 10px 0; 20 | } 21 | #optionsframework .group { 22 | padding-bottom:40px; 23 | } 24 | #optionsframework .section .controls { 25 | float: left; 26 | min-width:350px; 27 | width: 54%; 28 | padding-right:2%; 29 | } 30 | #optionsframework .section .explain { 31 | max-width:38%; 32 | float: left; 33 | font-size: 12px; 34 | line-height:16px; 35 | color: #777; 36 | } 37 | #optionsframework .section-checkbox .controls { 38 | width: 98%; 39 | } 40 | #optionsframework .section-checkbox .explain { 41 | max-width:94%; 42 | } 43 | #optionsframework .controls input[type=text] { 44 | width:100%; 45 | } 46 | #optionsframework .controls input[type=text].wp-color-picker { 47 | width: 65px; 48 | } 49 | #optionsframework .controls select, #optionsframework .controls textarea { 50 | margin-bottom:10px; 51 | width:100%; 52 | } 53 | #optionsframework .section-radio label, #optionsframework .section-multicheck label { 54 | float:left; 55 | max-width:90%; 56 | line-height: 16px; 57 | margin-bottom: 5px; 58 | } 59 | #optionsframework input.checkbox, #optionsframework input.of-radio { 60 | margin: 0 10px 5px 0; 61 | float:left; 62 | clear:both; 63 | } 64 | #optionsframework .section-typography .controls { 65 | float:none; 66 | width:auto; 67 | } 68 | #optionsframework .section-typography .explain { 69 | float:none; 70 | width:auto; 71 | } 72 | #optionsframework .controls .of-typography-size { 73 | width:80px; 74 | float:left 75 | } 76 | #optionsframework .controls .of-typography-unit { 77 | width:50px; 78 | margin-left:5px; 79 | float:left 80 | } 81 | #optionsframework .controls .of-typography-face { 82 | width:100px; 83 | margin-left:5px; 84 | float:left 85 | } 86 | #optionsframework .controls .of-typography-style { 87 | width:80px; 88 | margin-left:5px; 89 | margin-right:5px; 90 | float:left 91 | } 92 | #optionsframework .section-typography .wp-picker-container { 93 | margin-top:2px; 94 | } 95 | #optionsframework .of-background-properties { 96 | clear:both; 97 | margin-top: 18px; 98 | } 99 | #optionsframework .controls .of-background-repeat { 100 | width:125px; 101 | margin-right:5px; 102 | float:left 103 | } 104 | #optionsframework .controls .of-background-position { 105 | width:125px; 106 | margin-right:5px; 107 | float:left 108 | } 109 | #optionsframework .controls .of-background-attachment { 110 | width:125px; 111 | margin-right:5px; 112 | float:left 113 | } 114 | #optionsframework .section-background .wp-picker-container { 115 | margin-bottom:10px; 116 | } 117 | #optionsframework .controls .of-radio-img-img { 118 | border:3px solid #f9f9f9; 119 | margin:0 5px 10px 0; 120 | display:none; 121 | cursor:pointer; 122 | float:left; 123 | } 124 | #optionsframework .controls .of-radio-img-selected { 125 | border:3px solid #ccc 126 | } 127 | #optionsframework .controls .of-radio-img-img:hover { 128 | opacity:.8; 129 | } 130 | #optionsframework .controls .of-border-width { 131 | width:80px; 132 | float:left 133 | } 134 | #optionsframework .controls .of-border-style { 135 | width:120px; 136 | float:left 137 | } 138 | #optionsframework .hide { 139 | display:none; 140 | } 141 | #optionsframework .of-option-image { 142 | max-width:340px; 143 | margin:3px 0 18px 0; 144 | } 145 | #optionsframework .mini .controls select, #optionsframework .section .mini .controls { 146 | width: 140px; 147 | } 148 | #optionsframework .mini .controls input, #optionsframework .mini .controls { 149 | min-width:140px; 150 | width: 140px; 151 | } 152 | #optionsframework .mini .explain { 153 | max-width:74%; 154 | } 155 | 156 | /* Editor */ 157 | 158 | #optionsframework .section-editor .explain { 159 | max-width: 98%; 160 | float:none; 161 | margin-bottom:5px; 162 | } 163 | 164 | /* Image Uploader */ 165 | 166 | #optionsframework .controls input.upload { 167 | width:80%; 168 | } 169 | #optionsframework .screenshot { 170 | float:left; 171 | margin-left:1px; 172 | position:relative; 173 | width:344px; 174 | margin-top:3px; 175 | } 176 | #optionsframework .screenshot img { 177 | background:#fafafa; 178 | border-color:#ccc #eee #eee #ccc; 179 | border-style:solid; 180 | border-width:1px; 181 | float:left; 182 | max-width:334px; 183 | padding:4px; 184 | margin-bottom:10px; 185 | } 186 | #optionsframework .screenshot .remove-image { 187 | background:url("../images/ico-delete.png") no-repeat; 188 | border:medium none; 189 | bottom:4px; 190 | display:block; 191 | float:left; 192 | height:16px; 193 | padding:0; 194 | position:absolute; 195 | left:-4px; 196 | text-indent:-9999px; 197 | width:16px; 198 | } 199 | #optionsframework .screenshot .no_image .file_link { 200 | margin-left: 20px; 201 | } 202 | #optionsframework .screenshot .no_image .remove-button { 203 | bottom: 0px; 204 | } 205 | #optionsframework .reset-button { 206 | float:left; 207 | cursor:pointer; 208 | } 209 | 210 | /* Bottom Section */ 211 | 212 | #optionsframework-submit { 213 | padding: 7px 10px; 214 | border-top: 1px solid #ddd; 215 | background-color: #f1f1f1; 216 | } 217 | #optionsframework .button-primary { 218 | float:right; 219 | } 220 | #optionsframework .section:after { 221 | content: ""; 222 | display: table; 223 | } 224 | #optionsframework .section:after { 225 | clear: both; 226 | } -------------------------------------------------------------------------------- /inc/images/ico-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devinsays/options-framework-theme/10eef1860dd9b9f4dd88932798e1926aaf1d305a/inc/images/ico-delete.png -------------------------------------------------------------------------------- /inc/includes/class-options-framework-admin.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GPL-2.0+ 6 | * @link http://wptheming.com 7 | * @copyright 2010-2014 WP Theming 8 | */ 9 | 10 | class Options_Framework_Admin { 11 | 12 | /** 13 | * Page hook for the options screen 14 | * 15 | * @since 1.7.0 16 | * @type string 17 | */ 18 | protected $options_screen = null; 19 | 20 | /** 21 | * Hook in the scripts and styles 22 | * 23 | * @since 1.7.0 24 | */ 25 | public function init() { 26 | 27 | // Gets options to load 28 | $options = & Options_Framework::_optionsframework_options(); 29 | 30 | // Checks if options are available 31 | if ( $options ) { 32 | 33 | // Add the options page and menu item. 34 | add_action( 'admin_menu', array( $this, 'add_custom_options_page' ) ); 35 | 36 | // Add the required scripts and styles 37 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) ); 38 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); 39 | 40 | // Settings need to be registered after admin_init 41 | add_action( 'admin_init', array( $this, 'settings_init' ) ); 42 | 43 | // Adds options menu to the admin bar 44 | add_action( 'wp_before_admin_bar_render', array( $this, 'optionsframework_admin_bar' ) ); 45 | 46 | } 47 | 48 | } 49 | 50 | /** 51 | * Registers the settings 52 | * 53 | * @since 1.7.0 54 | */ 55 | function settings_init() { 56 | 57 | // Get the option name 58 | $options_framework = new Options_Framework; 59 | $name = $options_framework->get_option_name(); 60 | 61 | // Registers the settings fields and callback 62 | register_setting( 'optionsframework', $name, array ( $this, 'validate_options' ) ); 63 | 64 | // Displays notice after options save 65 | add_action( 'optionsframework_after_validate', array( $this, 'save_options_notice' ) ); 66 | 67 | } 68 | 69 | /* 70 | * Define menu options 71 | * 72 | * Examples usage: 73 | * 74 | * add_filter( 'optionsframework_menu', function( $menu ) { 75 | * $menu['page_title'] = 'The Options'; 76 | * $menu['menu_title'] = 'The Options'; 77 | * return $menu; 78 | * }); 79 | * 80 | * @since 1.7.0 81 | * 82 | */ 83 | static function menu_settings() { 84 | 85 | $menu = array( 86 | 87 | // Modes: submenu, menu 88 | 'mode' => 'submenu', 89 | 90 | // Submenu default settings 91 | 'page_title' => __( 'Theme Options', 'theme-textdomain' ), 92 | 'menu_title' => __( 'Theme Options', 'theme-textdomain' ), 93 | 'capability' => 'edit_theme_options', 94 | 'menu_slug' => 'options-framework', 95 | 'parent_slug' => 'themes.php', 96 | 97 | // Menu default settings 98 | 'icon_url' => 'dashicons-admin-generic', 99 | 'position' => '61' 100 | 101 | ); 102 | 103 | return apply_filters( 'optionsframework_menu', $menu ); 104 | } 105 | 106 | /** 107 | * Add a subpage called "Theme Options" to the appearance menu. 108 | * 109 | * @since 1.7.0 110 | */ 111 | function add_custom_options_page() { 112 | 113 | $menu = $this->menu_settings(); 114 | 115 | // If you want a top level menu, see this Gist: 116 | // https://gist.github.com/devinsays/884d6abe92857a329d99 117 | 118 | // Code removed because it conflicts with .org theme check. 119 | 120 | $this->options_screen = add_theme_page( 121 | $menu['page_title'], 122 | $menu['menu_title'], 123 | $menu['capability'], 124 | $menu['menu_slug'], 125 | array( $this, 'options_page' ) 126 | ); 127 | 128 | } 129 | 130 | /** 131 | * Loads the required stylesheets 132 | * 133 | * @since 1.7.0 134 | */ 135 | 136 | function enqueue_admin_styles( $hook ) { 137 | 138 | if ( $this->options_screen != $hook ) 139 | return; 140 | 141 | wp_enqueue_style( 'optionsframework', OPTIONS_FRAMEWORK_DIRECTORY . 'css/optionsframework.css', array(), Options_Framework::VERSION ); 142 | wp_enqueue_style( 'wp-color-picker' ); 143 | } 144 | 145 | /** 146 | * Loads the required javascript 147 | * 148 | * @since 1.7.0 149 | */ 150 | function enqueue_admin_scripts( $hook ) { 151 | 152 | if ( $this->options_screen != $hook ) 153 | return; 154 | 155 | // Enqueue custom option panel JS 156 | wp_enqueue_script( 157 | 'options-custom', 158 | OPTIONS_FRAMEWORK_DIRECTORY . 'js/options-custom.js', 159 | array( 'jquery','wp-color-picker' ), 160 | Options_Framework::VERSION 161 | ); 162 | 163 | // Inline scripts from options-interface.php 164 | add_action( 'admin_head', array( $this, 'of_admin_head' ) ); 165 | } 166 | 167 | function of_admin_head() { 168 | // Hook to add custom scripts 169 | do_action( 'optionsframework_custom_scripts' ); 170 | } 171 | 172 | /** 173 | * Builds out the options panel. 174 | * 175 | * If we were using the Settings API as it was intended we would use 176 | * do_settings_sections here. But as we don't want the settings wrapped in a table, 177 | * we'll call our own custom optionsframework_fields. See options-interface.php 178 | * for specifics on how each individual field is generated. 179 | * 180 | * Nonces are provided using the settings_fields() 181 | * 182 | * @since 1.7.0 183 | */ 184 | function options_page() { ?> 185 | 186 |
187 | 188 | menu_settings(); ?> 189 |

190 | 191 | 194 | 195 | 196 | 197 |
198 |
199 |
200 | 201 | 202 |
203 | 204 | 205 |
206 |
207 |
208 |
209 |
210 | 211 |
212 | 213 | get_default_values(); 237 | } 238 | 239 | /* 240 | * Update Settings 241 | * 242 | * This used to check for $_POST['update'], but has been updated 243 | * to be compatible with the theme customizer introduced in WordPress 3.4 244 | */ 245 | 246 | $clean = array(); 247 | $options = & Options_Framework::_optionsframework_options(); 248 | foreach ( $options as $option ) { 249 | 250 | if ( ! isset( $option['id'] ) ) { 251 | continue; 252 | } 253 | 254 | if ( ! isset( $option['type'] ) ) { 255 | continue; 256 | } 257 | 258 | $id = preg_replace( '/[^a-zA-Z0-9._\-]/', '', strtolower( $option['id'] ) ); 259 | 260 | // Set checkbox to false if it wasn't sent in the $_POST 261 | if ( 'checkbox' == $option['type'] && ! isset( $input[$id] ) ) { 262 | $input[$id] = false; 263 | } 264 | 265 | // Set each item in the multicheck to false if it wasn't sent in the $_POST 266 | if ( 'multicheck' == $option['type'] && ! isset( $input[$id] ) ) { 267 | foreach ( $option['options'] as $key => $value ) { 268 | $input[$id][$key] = false; 269 | } 270 | } 271 | 272 | // For a value to be submitted to database it must pass through a sanitization filter 273 | if ( has_filter( 'of_sanitize_' . $option['type'] ) ) { 274 | $clean[$id] = apply_filters( 'of_sanitize_' . $option['type'], $input[$id], $option ); 275 | } 276 | } 277 | 278 | // Hook to run after validation 279 | do_action( 'optionsframework_after_validate', $clean ); 280 | 281 | return $clean; 282 | } 283 | 284 | /** 285 | * Display message when options have been saved 286 | */ 287 | 288 | function save_options_notice() { 289 | add_settings_error( 'options-framework', 'save_options', __( 'Options saved.', 'theme-textdomain' ), 'updated fade' ); 290 | } 291 | 292 | /** 293 | * Get the default values for all the theme options 294 | * 295 | * Get an array of all default values as set in 296 | * options.php. The 'id','std' and 'type' keys need 297 | * to be defined in the configuration array. In the 298 | * event that these keys are not present the option 299 | * will not be included in this function's output. 300 | * 301 | * @return array Re-keyed options configuration array. 302 | * 303 | */ 304 | function get_default_values() { 305 | $output = array(); 306 | $config = & Options_Framework::_optionsframework_options(); 307 | foreach ( (array) $config as $option ) { 308 | if ( ! isset( $option['id'] ) ) { 309 | continue; 310 | } 311 | if ( ! isset( $option['std'] ) ) { 312 | continue; 313 | } 314 | if ( ! isset( $option['type'] ) ) { 315 | continue; 316 | } 317 | if ( has_filter( 'of_sanitize_' . $option['type'] ) ) { 318 | $output[$option['id']] = apply_filters( 'of_sanitize_' . $option['type'], $option['std'], $option ); 319 | } 320 | } 321 | return $output; 322 | } 323 | 324 | /** 325 | * Add options menu item to admin bar 326 | */ 327 | 328 | function optionsframework_admin_bar() { 329 | 330 | $menu = $this->menu_settings(); 331 | 332 | global $wp_admin_bar; 333 | 334 | if ( 'menu' == $menu['mode'] ) { 335 | $href = admin_url( 'admin.php?page=' . $menu['menu_slug'] ); 336 | } else { 337 | $href = admin_url( 'themes.php?page=' . $menu['menu_slug'] ); 338 | } 339 | 340 | $args = array( 341 | 'parent' => 'appearance', 342 | 'id' => 'of_theme_options', 343 | 'title' => $menu['menu_title'], 344 | 'href' => $href 345 | ); 346 | 347 | $wp_admin_bar->add_menu( apply_filters( 'optionsframework_admin_bar', $args ) ); 348 | } 349 | 350 | } -------------------------------------------------------------------------------- /inc/includes/class-options-framework.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GPL-2.0+ 6 | * @link http://wptheming.com 7 | * @copyright 2010-2014 WP Theming 8 | */ 9 | 10 | class Options_Framework { 11 | 12 | /** 13 | * Plugin version, used for cache-busting of style and script file references. 14 | * 15 | * @since 1.7.0 16 | * @type string 17 | */ 18 | const VERSION = '1.9.1'; 19 | 20 | /** 21 | * Gets option name 22 | * 23 | * @since 1.9.0 24 | */ 25 | function get_option_name() { 26 | 27 | $name = ''; 28 | 29 | // Gets option name as defined in the theme 30 | if ( function_exists( 'optionsframework_option_name' ) ) { 31 | $name = optionsframework_option_name(); 32 | } 33 | 34 | // Fallback 35 | if ( '' == $name ) { 36 | $name = get_option( 'stylesheet' ); 37 | $name = preg_replace( "/\W/", "_", strtolower( $name ) ); 38 | } 39 | 40 | return apply_filters( 'options_framework_option_name', $name ); 41 | 42 | } 43 | 44 | /** 45 | * Wrapper for optionsframework_options() 46 | * 47 | * Allows for manipulating or setting options via 'of_options' filter 48 | * For example: 49 | * 50 | * 51 | * add_filter( 'of_options', function( $options ) { 52 | * $options[] = array( 53 | * 'name' => 'Input Text Mini', 54 | * 'desc' => 'A mini text input field.', 55 | * 'id' => 'example_text_mini', 56 | * 'std' => 'Default', 57 | * 'class' => 'mini', 58 | * 'type' => 'text' 59 | * ); 60 | * 61 | * return $options; 62 | * }); 63 | * 64 | * 65 | * Also allows for setting options via a return statement in the 66 | * options.php file. For example (in options.php): 67 | * 68 | * 69 | * return array(...); 70 | * 71 | * 72 | * @return array (by reference) 73 | */ 74 | static function &_optionsframework_options() { 75 | static $options = null; 76 | 77 | if ( !$options ) { 78 | // Load options from options.php file (if it exists) 79 | $location = apply_filters( 'options_framework_location', array( 'options.php' ) ); 80 | if ( $optionsfile = locate_template( $location ) ) { 81 | $maybe_options = load_template( $optionsfile ); 82 | if ( is_array( $maybe_options ) ) { 83 | $options = $maybe_options; 84 | } else if ( function_exists( 'optionsframework_options' ) ) { 85 | $options = optionsframework_options(); 86 | } 87 | } 88 | 89 | // Allow setting/manipulating options via filters 90 | $options = apply_filters( 'of_options', $options ); 91 | } 92 | 93 | return $options; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /inc/includes/class-options-interface.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GPL-2.0+ 6 | * @link http://wptheming.com 7 | * @copyright 2010-2014 WP Theming 8 | */ 9 | 10 | class Options_Framework_Interface { 11 | 12 | /** 13 | * Generates the tabs that are used in the options menu 14 | */ 15 | static function optionsframework_tabs() { 16 | $counter = 0; 17 | $options = & Options_Framework::_optionsframework_options(); 18 | $menu = ''; 19 | 20 | foreach ( $options as $value ) { 21 | // Heading for Navigation 22 | if ( $value['type'] == "heading" ) { 23 | $counter++; 24 | $class = ''; 25 | $class = ! empty( $value['id'] ) ? $value['id'] : $value['name']; 26 | $class = preg_replace( '/[^a-zA-Z0-9._\-]/', '', strtolower($class) ) . '-tab'; 27 | $menu .= '' . esc_html( $value['name'] ) . ''; 28 | } 29 | } 30 | 31 | return $menu; 32 | } 33 | 34 | /** 35 | * Generates the options fields that are used in the form. 36 | */ 37 | static function optionsframework_fields() { 38 | 39 | global $allowedtags; 40 | 41 | $options_framework = new Options_Framework; 42 | $option_name = $options_framework->get_option_name(); 43 | $settings = get_option( $option_name ); 44 | $options = & Options_Framework::_optionsframework_options(); 45 | 46 | $counter = 0; 47 | $menu = ''; 48 | 49 | foreach ( $options as $value ) { 50 | 51 | $val = ''; 52 | $select_value = ''; 53 | $output = ''; 54 | 55 | // Wrap all options 56 | if ( ( $value['type'] != "heading" ) && ( $value['type'] != "info" ) ) { 57 | 58 | // Keep all ids lowercase with no spaces 59 | $value['id'] = preg_replace('/[^a-zA-Z0-9._\-]/', '', strtolower($value['id']) ); 60 | 61 | $id = 'section-' . $value['id']; 62 | 63 | $class = 'section'; 64 | if ( isset( $value['type'] ) ) { 65 | $class .= ' section-' . $value['type']; 66 | } 67 | if ( isset( $value['class'] ) ) { 68 | $class .= ' ' . $value['class']; 69 | } 70 | 71 | $output .= '
'."\n"; 72 | if ( isset( $value['name'] ) ) { 73 | $output .= '

' . esc_html( $value['name'] ) . '

' . "\n"; 74 | } 75 | if ( $value['type'] != 'editor' ) { 76 | $output .= '
' . "\n" . '
' . "\n"; 77 | } 78 | else { 79 | $output .= '
' . "\n" . '
' . "\n"; 80 | } 81 | } 82 | 83 | // Set default value to $val 84 | if ( isset( $value['std'] ) ) { 85 | $val = $value['std']; 86 | } 87 | 88 | // If the option is already saved, override $val 89 | if ( ( $value['type'] != 'heading' ) && ( $value['type'] != 'info') ) { 90 | if ( isset( $settings[($value['id'])]) ) { 91 | $val = $settings[($value['id'])]; 92 | // Striping slashes of non-array options 93 | if ( !is_array($val) ) { 94 | $val = stripslashes( $val ); 95 | } 96 | } 97 | } 98 | 99 | // If there is a description save it for labels 100 | $explain_value = ''; 101 | if ( isset( $value['desc'] ) ) { 102 | $explain_value = $value['desc']; 103 | } 104 | 105 | // Set the placeholder if one exists 106 | $placeholder = ''; 107 | if ( isset( $value['placeholder'] ) ) { 108 | $placeholder = ' placeholder="' . esc_attr( $value['placeholder'] ) . '"'; 109 | } 110 | 111 | if ( has_filter( 'optionsframework_' . $value['type'] ) ) { 112 | $output .= apply_filters( 'optionsframework_' . $value['type'], $option_name, $value, $val ); 113 | } 114 | 115 | 116 | switch ( $value['type'] ) { 117 | 118 | // Basic text input 119 | case 'text': 120 | $output .= ''; 121 | break; 122 | 123 | // Password input 124 | case 'password': 125 | $output .= ''; 126 | break; 127 | 128 | // Textarea 129 | case 'textarea': 130 | $rows = '8'; 131 | 132 | if ( isset( $value['settings']['rows'] ) ) { 133 | $custom_rows = $value['settings']['rows']; 134 | if ( is_numeric( $custom_rows ) ) { 135 | $rows = $custom_rows; 136 | } 137 | } 138 | 139 | $val = stripslashes( $val ); 140 | $output .= ''; 141 | break; 142 | 143 | // Select Box 144 | case 'select': 145 | $output .= ''; 151 | break; 152 | 153 | 154 | // Radio Box 155 | case "radio": 156 | $name = $option_name .'['. $value['id'] .']'; 157 | foreach ($value['options'] as $key => $option) { 158 | $id = $option_name . '-' . $value['id'] .'-'. $key; 159 | $output .= ''; 160 | } 161 | break; 162 | 163 | // Image Selectors 164 | case "images": 165 | $name = $option_name .'['. $value['id'] .']'; 166 | foreach ( $value['options'] as $key => $option ) { 167 | $selected = ''; 168 | if ( $val != '' && ($val == $key) ) { 169 | $selected = ' of-radio-img-selected'; 170 | } 171 | $output .= ''; 172 | $output .= '
' . esc_html( $key ) . '
'; 173 | $output .= '' . $option .''; 174 | } 175 | break; 176 | 177 | // Checkbox 178 | case "checkbox": 179 | $output .= ''; 180 | $output .= ''; 181 | break; 182 | 183 | // Multicheck 184 | case "multicheck": 185 | foreach ($value['options'] as $key => $option) { 186 | $checked = ''; 187 | $label = $option; 188 | $option = preg_replace('/[^a-zA-Z0-9._\-]/', '', strtolower($key)); 189 | 190 | $id = $option_name . '-' . $value['id'] . '-'. $option; 191 | $name = $option_name . '[' . $value['id'] . '][' . $option .']'; 192 | 193 | if ( isset($val[$option]) ) { 194 | $checked = checked($val[$option], 1, false); 195 | } 196 | 197 | $output .= ''; 198 | } 199 | break; 200 | 201 | // Color picker 202 | case "color": 203 | $default_color = ''; 204 | if ( isset($value['std']) ) { 205 | if ( $val != $value['std'] ) 206 | $default_color = ' data-default-color="' .$value['std'] . '" '; 207 | } 208 | $output .= ''; 209 | 210 | break; 211 | 212 | // Uploader 213 | case "upload": 214 | $output .= Options_Framework_Media_Uploader::optionsframework_uploader( $value['id'], $val, null ); 215 | 216 | break; 217 | 218 | // Typography 219 | case 'typography': 220 | 221 | unset( $font_size, $font_style, $font_face, $font_color ); 222 | 223 | $typography_defaults = array( 224 | 'size' => '', 225 | 'face' => '', 226 | 'style' => '', 227 | 'color' => '' 228 | ); 229 | 230 | $typography_stored = wp_parse_args( $val, $typography_defaults ); 231 | 232 | $typography_options = array( 233 | 'sizes' => of_recognized_font_sizes(), 234 | 'faces' => of_recognized_font_faces(), 235 | 'styles' => of_recognized_font_styles(), 236 | 'color' => true 237 | ); 238 | 239 | if ( isset( $value['options'] ) ) { 240 | $typography_options = wp_parse_args( $value['options'], $typography_options ); 241 | } 242 | 243 | // Font Size 244 | if ( $typography_options['sizes'] ) { 245 | $font_size = ''; 252 | } 253 | 254 | // Font Face 255 | if ( $typography_options['faces'] ) { 256 | $font_face = ''; 262 | } 263 | 264 | // Font Styles 265 | if ( $typography_options['styles'] ) { 266 | $font_style = ''; 272 | } 273 | 274 | // Font Color 275 | if ( $typography_options['color'] ) { 276 | $default_color = ''; 277 | if ( isset($value['std']['color']) ) { 278 | if ( $val != $value['std']['color'] ) 279 | $default_color = ' data-default-color="' .$value['std']['color'] . '" '; 280 | } 281 | $font_color = ''; 282 | } 283 | 284 | // Allow modification/injection of typography fields 285 | $typography_fields = compact( 'font_size', 'font_face', 'font_style', 'font_color' ); 286 | $typography_fields = apply_filters( 'of_typography_fields', $typography_fields, $typography_stored, $option_name, $value ); 287 | $output .= implode( '', $typography_fields ); 288 | 289 | break; 290 | 291 | // Background 292 | case 'background': 293 | 294 | $background = $val; 295 | 296 | // Background Color 297 | $default_color = ''; 298 | if ( isset( $value['std']['color'] ) ) { 299 | if ( $val != $value['std']['color'] ) 300 | $default_color = ' data-default-color="' .$value['std']['color'] . '" '; 301 | } 302 | $output .= ''; 303 | 304 | // Background Image 305 | if ( !isset($background['image']) ) { 306 | $background['image'] = ''; 307 | } 308 | 309 | $output .= Options_Framework_Media_Uploader::optionsframework_uploader( $value['id'], $background['image'], null, esc_attr( $option_name . '[' . $value['id'] . '][image]' ) ); 310 | 311 | $class = 'of-background-properties'; 312 | if ( '' == $background['image'] ) { 313 | $class .= ' hide'; 314 | } 315 | $output .= '
'; 316 | 317 | // Background Repeat 318 | $output .= ''; 325 | 326 | // Background Position 327 | $output .= ''; 334 | 335 | // Background Attachment 336 | $output .= ''; 343 | $output .= '
'; 344 | 345 | break; 346 | 347 | // Editor 348 | case 'editor': 349 | $output .= '
' . wp_kses( $explain_value, $allowedtags ) . '
'."\n"; 350 | echo $output; 351 | $textarea_name = esc_attr( $option_name . '[' . $value['id'] . ']' ); 352 | $default_editor_settings = array( 353 | 'textarea_name' => $textarea_name, 354 | 'media_buttons' => false, 355 | 'tinymce' => array( 'plugins' => 'wordpress,wplink' ) 356 | ); 357 | $editor_settings = array(); 358 | if ( isset( $value['settings'] ) ) { 359 | $editor_settings = $value['settings']; 360 | } 361 | $editor_settings = array_merge( $default_editor_settings, $editor_settings ); 362 | wp_editor( $val, $value['id'], $editor_settings ); 363 | $output = ''; 364 | break; 365 | 366 | // Info 367 | case "info": 368 | $id = ''; 369 | $class = 'section'; 370 | if ( isset( $value['id'] ) ) { 371 | $id = 'id="' . esc_attr( $value['id'] ) . '" '; 372 | } 373 | if ( isset( $value['type'] ) ) { 374 | $class .= ' section-' . $value['type']; 375 | } 376 | if ( isset( $value['class'] ) ) { 377 | $class .= ' ' . $value['class']; 378 | } 379 | 380 | $output .= '
' . "\n"; 381 | if ( isset($value['name']) ) { 382 | $output .= '

' . esc_html( $value['name'] ) . '

' . "\n"; 383 | } 384 | if ( isset( $value['desc'] ) ) { 385 | $output .= $value['desc'] . "\n"; 386 | } 387 | $output .= '
' . "\n"; 388 | break; 389 | 390 | // Heading for Navigation 391 | case "heading": 392 | $counter++; 393 | if ( $counter >= 2 ) { 394 | $output .= '
'."\n"; 395 | } 396 | $class = ''; 397 | $class = ! empty( $value['id'] ) ? $value['id'] : $value['name']; 398 | $class = preg_replace('/[^a-zA-Z0-9._\-]/', '', strtolower($class) ); 399 | $output .= '
'; 400 | $output .= '

' . esc_html( $value['name'] ) . '

' . "\n"; 401 | break; 402 | } 403 | 404 | if ( ( $value['type'] != "heading" ) && ( $value['type'] != "info" ) ) { 405 | $output .= '
'; 406 | if ( ( $value['type'] != "checkbox" ) && ( $value['type'] != "editor" ) ) { 407 | $output .= '
' . wp_kses( $explain_value, $allowedtags) . '
'."\n"; 408 | } 409 | $output .= '
'."\n"; 410 | } 411 | 412 | echo $output; 413 | } 414 | 415 | // Outputs closing div if there tabs 416 | if ( Options_Framework_Interface::optionsframework_tabs() != '' ) { 417 | echo '
'; 418 | } 419 | } 420 | 421 | } -------------------------------------------------------------------------------- /inc/includes/class-options-media-uploader.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GPL-2.0+ 6 | * @link http://wptheming.com 7 | * @copyright 2010-2014 WP Theming 8 | */ 9 | 10 | class Options_Framework_Media_Uploader { 11 | 12 | /** 13 | * Initialize the media uploader class 14 | * 15 | * @since 1.7.0 16 | */ 17 | public function init() { 18 | add_action( 'admin_enqueue_scripts', array( $this, 'optionsframework_media_scripts' ) ); 19 | } 20 | 21 | /** 22 | * Media Uploader Using the WordPress Media Library. 23 | * 24 | * Parameters: 25 | * 26 | * string $_id - A token to identify this field (the name). 27 | * string $_value - The value of the field, if present. 28 | * string $_desc - An optional description of the field. 29 | * 30 | */ 31 | 32 | static function optionsframework_uploader( $_id, $_value, $_desc = '', $_name = '' ) { 33 | 34 | // Gets the unique option id 35 | $options_framework = new Options_Framework; 36 | $option_name = $options_framework->get_option_name(); 37 | 38 | $output = ''; 39 | $id = ''; 40 | $class = ''; 41 | $int = ''; 42 | $value = ''; 43 | $name = ''; 44 | 45 | $id = strip_tags( strtolower( $_id ) ); 46 | 47 | // If a value is passed and we don't have a stored value, use the value that's passed through. 48 | if ( $_value != '' && $value == '' ) { 49 | $value = $_value; 50 | } 51 | 52 | if ($_name != '') { 53 | $name = $_name; 54 | } 55 | else { 56 | $name = $option_name.'['.$id.']'; 57 | } 58 | 59 | if ( $value ) { 60 | $class = ' has-file'; 61 | } 62 | $output .= '' . "\n"; 63 | if ( function_exists( 'wp_enqueue_media' ) ) { 64 | if ( ( $value == '' ) ) { 65 | $output .= '' . "\n"; 66 | } else { 67 | $output .= '' . "\n"; 68 | } 69 | } else { 70 | $output .= '

' . __( 'Upgrade your version of WordPress for full media support.', 'theme-textdomain' ) . '

'; 71 | } 72 | 73 | if ( $_desc != '' ) { 74 | $output .= '' . $_desc . '' . "\n"; 75 | } 76 | 77 | $output .= '
' . "\n"; 78 | 79 | if ( $value != '' ) { 80 | $remove = 'Remove'; 81 | $image = preg_match( '/(^.*\.jpg|jpeg|png|gif|ico*)/i', $value ); 82 | if ( $image ) { 83 | $output .= '' . $remove; 84 | } else { 85 | $parts = explode( "/", $value ); 86 | for( $i = 0; $i < sizeof( $parts ); ++$i ) { 87 | $title = $parts[$i]; 88 | } 89 | 90 | // No output preview if it's not an image. 91 | $output .= ''; 92 | 93 | // Standard generic output if it's not an image. 94 | $title = __( 'View File', 'theme-textdomain' ); 95 | $output .= ''; 96 | } 97 | } 98 | $output .= '
' . "\n"; 99 | return $output; 100 | } 101 | 102 | /** 103 | * Enqueue scripts for file uploader 104 | */ 105 | function optionsframework_media_scripts( $hook ) { 106 | 107 | $menu = Options_Framework_Admin::menu_settings(); 108 | 109 | if ( substr( $hook, -strlen( $menu['menu_slug'] ) ) !== $menu['menu_slug'] ) 110 | return; 111 | 112 | if ( function_exists( 'wp_enqueue_media' ) ) 113 | wp_enqueue_media(); 114 | 115 | wp_register_script( 'of-media-uploader', OPTIONS_FRAMEWORK_DIRECTORY .'js/media-uploader.js', array( 'jquery' ), Options_Framework::VERSION ); 116 | wp_enqueue_script( 'of-media-uploader' ); 117 | wp_localize_script( 'of-media-uploader', 'optionsframework_l10n', array( 118 | 'upload' => __( 'Upload', 'theme-textdomain' ), 119 | 'remove' => __( 'Remove', 'theme-textdomain' ) 120 | ) ); 121 | } 122 | } -------------------------------------------------------------------------------- /inc/includes/class-options-sanitization.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GPL-2.0+ 6 | * @link http://wptheming.com 7 | * @copyright 2010-2014 WP Theming 8 | */ 9 | 10 | /** 11 | * Sanitization for text input 12 | * 13 | * @link http://developer.wordpress.org/reference/functions/sanitize_text_field/ 14 | */ 15 | add_filter( 'of_sanitize_text', 'sanitize_text_field' ); 16 | 17 | /** 18 | * Sanitization for password input 19 | * 20 | * @link http://developer.wordpress.org/reference/functions/sanitize_text_field/ 21 | */ 22 | add_filter( 'of_sanitize_password', 'sanitize_text_field' ); 23 | 24 | /** 25 | * Sanitization for select input 26 | * 27 | * Validates that the selected option is a valid option. 28 | */ 29 | add_filter( 'of_sanitize_select', 'of_sanitize_enum', 10, 2 ); 30 | 31 | /** 32 | * Sanitization for radio input 33 | * 34 | * Validates that the selected option is a valid option. 35 | */ 36 | add_filter( 'of_sanitize_radio', 'of_sanitize_enum', 10, 2 ); 37 | 38 | /** 39 | * Sanitization for image selector 40 | * 41 | * Validates that the selected option is a valid option. 42 | */ 43 | add_filter( 'of_sanitize_images', 'of_sanitize_enum', 10, 2 ); 44 | 45 | /** 46 | * Sanitization for textarea field 47 | * 48 | * @param $input string 49 | * @return $output sanitized string 50 | */ 51 | function of_sanitize_textarea( $input ) { 52 | global $allowedposttags; 53 | $output = wp_kses( $input, $allowedposttags ); 54 | return $output; 55 | } 56 | add_filter( 'of_sanitize_textarea', 'of_sanitize_textarea' ); 57 | 58 | /** 59 | * Sanitization for checkbox input 60 | * 61 | * @param $input string (1 or empty) checkbox state 62 | * @return $output '1' or false 63 | */ 64 | function of_sanitize_checkbox( $input ) { 65 | if ( $input ) { 66 | $output = '1'; 67 | } else { 68 | $output = false; 69 | } 70 | return $output; 71 | } 72 | add_filter( 'of_sanitize_checkbox', 'of_sanitize_checkbox' ); 73 | 74 | /** 75 | * Sanitization for multicheck 76 | * 77 | * @param array of checkbox values 78 | * @return array of sanitized values ('1' or false) 79 | */ 80 | function of_sanitize_multicheck( $input, $option ) { 81 | $output = ''; 82 | if ( is_array( $input ) ) { 83 | foreach( $option['options'] as $key => $value ) { 84 | $output[$key] = false; 85 | } 86 | foreach( $input as $key => $value ) { 87 | if ( array_key_exists( $key, $option['options'] ) && $value ) { 88 | $output[$key] = '1'; 89 | } 90 | } 91 | } 92 | return $output; 93 | } 94 | add_filter( 'of_sanitize_multicheck', 'of_sanitize_multicheck', 10, 2 ); 95 | 96 | /** 97 | * File upload sanitization. 98 | * 99 | * Returns a sanitized filepath if it has a valid extension. 100 | * 101 | * @param string $input filepath 102 | * @returns string $output filepath 103 | */ 104 | function of_sanitize_upload( $input ) { 105 | $output = ''; 106 | $filetype = wp_check_filetype( $input ); 107 | if ( $filetype["ext"] ) { 108 | $output = esc_url( $input ); 109 | } 110 | return $output; 111 | } 112 | add_filter( 'of_sanitize_upload', 'of_sanitize_upload' ); 113 | 114 | /** 115 | * Sanitization for editor input. 116 | * 117 | * Returns unfiltered HTML if user has permissions. 118 | * 119 | * @param string $input 120 | * @returns string $output 121 | */ 122 | function of_sanitize_editor( $input ) { 123 | if ( current_user_can( 'unfiltered_html' ) ) { 124 | $output = $input; 125 | } 126 | else { 127 | global $allowedposttags; 128 | $output = wpautop( wp_kses( $input, $allowedposttags ) ); 129 | } 130 | return $output; 131 | } 132 | add_filter( 'of_sanitize_editor', 'of_sanitize_editor' ); 133 | 134 | /** 135 | * Sanitization of input with allowed tags and wpautotop. 136 | * 137 | * Allows allowed tags in html input and ensures tags close properly. 138 | * 139 | * @param string $input 140 | * @returns string $output 141 | */ 142 | function of_sanitize_allowedtags( $input ) { 143 | global $allowedtags; 144 | $output = wpautop( wp_kses( $input, $allowedtags ) ); 145 | return $output; 146 | } 147 | 148 | /** 149 | * Sanitization of input with allowed post tags and wpautotop. 150 | * 151 | * Allows allowed post tags in html input and ensures tags close properly. 152 | * 153 | * @param string $input 154 | * @returns string $output 155 | */ 156 | function of_sanitize_allowedposttags( $input ) { 157 | global $allowedposttags; 158 | $output = wpautop( wp_kses( $input, $allowedposttags) ); 159 | return $output; 160 | } 161 | 162 | /** 163 | * Validates that the $input is one of the avilable choices 164 | * for that specific option. 165 | * 166 | * @param string $input 167 | * @returns string $output 168 | */ 169 | function of_sanitize_enum( $input, $option ) { 170 | $output = ''; 171 | if ( array_key_exists( $input, $option['options'] ) ) { 172 | $output = $input; 173 | } 174 | return $output; 175 | } 176 | 177 | /** 178 | * Sanitization for background option. 179 | * 180 | * @returns array $output 181 | */ 182 | function of_sanitize_background( $input ) { 183 | 184 | $output = wp_parse_args( $input, array( 185 | 'color' => '', 186 | 'image' => '', 187 | 'repeat' => 'repeat', 188 | 'position' => 'top center', 189 | 'attachment' => 'scroll' 190 | ) ); 191 | 192 | $output['color'] = apply_filters( 'of_sanitize_hex', $input['color'] ); 193 | $output['image'] = apply_filters( 'of_sanitize_upload', $input['image'] ); 194 | $output['repeat'] = apply_filters( 'of_background_repeat', $input['repeat'] ); 195 | $output['position'] = apply_filters( 'of_background_position', $input['position'] ); 196 | $output['attachment'] = apply_filters( 'of_background_attachment', $input['attachment'] ); 197 | 198 | return $output; 199 | } 200 | add_filter( 'of_sanitize_background', 'of_sanitize_background' ); 201 | 202 | /** 203 | * Sanitization for background repeat 204 | * 205 | * @returns string $value if it is valid 206 | */ 207 | function of_sanitize_background_repeat( $value ) { 208 | $recognized = of_recognized_background_repeat(); 209 | if ( array_key_exists( $value, $recognized ) ) { 210 | return $value; 211 | } 212 | return apply_filters( 'of_default_background_repeat', current( $recognized ) ); 213 | } 214 | add_filter( 'of_background_repeat', 'of_sanitize_background_repeat' ); 215 | 216 | /** 217 | * Sanitization for background position 218 | * 219 | * @returns string $value if it is valid 220 | */ 221 | function of_sanitize_background_position( $value ) { 222 | $recognized = of_recognized_background_position(); 223 | if ( array_key_exists( $value, $recognized ) ) { 224 | return $value; 225 | } 226 | return apply_filters( 'of_default_background_position', current( $recognized ) ); 227 | } 228 | add_filter( 'of_background_position', 'of_sanitize_background_position' ); 229 | 230 | /** 231 | * Sanitization for background attachment 232 | * 233 | * @returns string $value if it is valid 234 | */ 235 | function of_sanitize_background_attachment( $value ) { 236 | $recognized = of_recognized_background_attachment(); 237 | if ( array_key_exists( $value, $recognized ) ) { 238 | return $value; 239 | } 240 | return apply_filters( 'of_default_background_attachment', current( $recognized ) ); 241 | } 242 | add_filter( 'of_background_attachment', 'of_sanitize_background_attachment' ); 243 | 244 | /** 245 | * Sanitization for typography option. 246 | */ 247 | function of_sanitize_typography( $input, $option ) { 248 | 249 | $output = wp_parse_args( $input, array( 250 | 'size' => '', 251 | 'face' => '', 252 | 'style' => '', 253 | 'color' => '' 254 | ) ); 255 | 256 | if ( isset( $option['options']['faces'] ) && isset( $input['face'] ) ) { 257 | if ( !( array_key_exists( $input['face'], $option['options']['faces'] ) ) ) { 258 | $output['face'] = ''; 259 | } 260 | } 261 | else { 262 | $output['face'] = apply_filters( 'of_font_face', $output['face'] ); 263 | } 264 | 265 | $output['size'] = apply_filters( 'of_font_size', $output['size'] ); 266 | $output['style'] = apply_filters( 'of_font_style', $output['style'] ); 267 | $output['color'] = apply_filters( 'of_sanitize_color', $output['color'] ); 268 | return $output; 269 | } 270 | add_filter( 'of_sanitize_typography', 'of_sanitize_typography', 10, 2 ); 271 | 272 | /** 273 | * Sanitization for font size 274 | */ 275 | function of_sanitize_font_size( $value ) { 276 | $recognized = of_recognized_font_sizes(); 277 | $value_check = preg_replace('/px/','', $value); 278 | if ( in_array( (int) $value_check, $recognized ) ) { 279 | return $value; 280 | } 281 | return apply_filters( 'of_default_font_size', $recognized ); 282 | } 283 | add_filter( 'of_font_size', 'of_sanitize_font_size' ); 284 | 285 | /** 286 | * Sanitization for font style 287 | */ 288 | function of_sanitize_font_style( $value ) { 289 | $recognized = of_recognized_font_styles(); 290 | if ( array_key_exists( $value, $recognized ) ) { 291 | return $value; 292 | } 293 | return apply_filters( 'of_default_font_style', current( $recognized ) ); 294 | } 295 | add_filter( 'of_font_style', 'of_sanitize_font_style' ); 296 | 297 | /** 298 | * Sanitization for font face 299 | */ 300 | function of_sanitize_font_face( $value ) { 301 | $recognized = of_recognized_font_faces(); 302 | if ( array_key_exists( $value, $recognized ) ) { 303 | return $value; 304 | } 305 | return apply_filters( 'of_default_font_face', current( $recognized ) ); 306 | } 307 | add_filter( 'of_font_face', 'of_sanitize_font_face' ); 308 | 309 | /** 310 | * Get recognized background repeat settings 311 | * 312 | * @return array 313 | */ 314 | function of_recognized_background_repeat() { 315 | $default = array( 316 | 'no-repeat' => __( 'No Repeat', 'theme-textdomain' ), 317 | 'repeat-x' => __( 'Repeat Horizontally', 'theme-textdomain' ), 318 | 'repeat-y' => __( 'Repeat Vertically', 'theme-textdomain' ), 319 | 'repeat' => __( 'Repeat All', 'theme-textdomain' ), 320 | ); 321 | return apply_filters( 'of_recognized_background_repeat', $default ); 322 | } 323 | 324 | /** 325 | * Get recognized background positions 326 | * 327 | * @return array 328 | */ 329 | function of_recognized_background_position() { 330 | $default = array( 331 | 'top left' => __( 'Top Left', 'theme-textdomain' ), 332 | 'top center' => __( 'Top Center', 'theme-textdomain' ), 333 | 'top right' => __( 'Top Right', 'theme-textdomain' ), 334 | 'center left' => __( 'Middle Left', 'theme-textdomain' ), 335 | 'center center' => __( 'Middle Center', 'theme-textdomain' ), 336 | 'center right' => __( 'Middle Right', 'theme-textdomain' ), 337 | 'bottom left' => __( 'Bottom Left', 'theme-textdomain' ), 338 | 'bottom center' => __( 'Bottom Center', 'theme-textdomain' ), 339 | 'bottom right' => __( 'Bottom Right', 'theme-textdomain') 340 | ); 341 | return apply_filters( 'of_recognized_background_position', $default ); 342 | } 343 | 344 | /** 345 | * Get recognized background attachment 346 | * 347 | * @return array 348 | */ 349 | function of_recognized_background_attachment() { 350 | $default = array( 351 | 'scroll' => __( 'Scroll Normally', 'theme-textdomain' ), 352 | 'fixed' => __( 'Fixed in Place', 'theme-textdomain') 353 | ); 354 | return apply_filters( 'of_recognized_background_attachment', $default ); 355 | } 356 | 357 | /** 358 | * Sanitize a color represented in hexidecimal notation. 359 | * 360 | * @param string Color in hexidecimal notation. "#" may or may not be prepended to the string. 361 | * @param string The value that this function should return if it cannot be recognized as a color. 362 | * @return string 363 | */ 364 | 365 | function of_sanitize_hex( $hex, $default = '' ) { 366 | if ( of_validate_hex( $hex ) ) { 367 | return $hex; 368 | } 369 | return $default; 370 | } 371 | add_filter( 'of_sanitize_color', 'of_sanitize_hex' ); 372 | 373 | /** 374 | * Get recognized font sizes. 375 | * 376 | * Returns an indexed array of all recognized font sizes. 377 | * Values are integers and represent a range of sizes from 378 | * smallest to largest. 379 | * 380 | * @return array 381 | */ 382 | 383 | function of_recognized_font_sizes() { 384 | $sizes = range( 9, 71 ); 385 | $sizes = apply_filters( 'of_recognized_font_sizes', $sizes ); 386 | $sizes = array_map( 'absint', $sizes ); 387 | return $sizes; 388 | } 389 | 390 | /** 391 | * Get recognized font faces. 392 | * 393 | * Returns an array of all recognized font faces. 394 | * Keys are intended to be stored in the database 395 | * while values are ready for display in in html. 396 | * 397 | * @return array 398 | */ 399 | function of_recognized_font_faces() { 400 | $default = array( 401 | 'arial' => 'Arial', 402 | 'verdana' => 'Verdana, Geneva', 403 | 'trebuchet' => 'Trebuchet', 404 | 'georgia' => 'Georgia', 405 | 'times' => 'Times New Roman', 406 | 'tahoma' => 'Tahoma, Geneva', 407 | 'palatino' => 'Palatino', 408 | 'helvetica' => 'Helvetica*' 409 | ); 410 | return apply_filters( 'of_recognized_font_faces', $default ); 411 | } 412 | 413 | /** 414 | * Get recognized font styles. 415 | * 416 | * Returns an array of all recognized font styles. 417 | * Keys are intended to be stored in the database 418 | * while values are ready for display in in html. 419 | * 420 | * @return array 421 | */ 422 | function of_recognized_font_styles() { 423 | $default = array( 424 | 'normal' => __( 'Normal', 'theme-textdomain' ), 425 | 'italic' => __( 'Italic', 'theme-textdomain' ), 426 | 'bold' => __( 'Bold', 'theme-textdomain' ), 427 | 'bold italic' => __( 'Bold Italic', 'theme-textdomain' ) 428 | ); 429 | return apply_filters( 'of_recognized_font_styles', $default ); 430 | } 431 | 432 | /** 433 | * Is a given string a color formatted in hexidecimal notation? 434 | * 435 | * @param string Color in hexidecimal notation. "#" may or may not be prepended to the string. 436 | * @return bool 437 | */ 438 | function of_validate_hex( $hex ) { 439 | $hex = trim( $hex ); 440 | /* Strip recognized prefixes. */ 441 | if ( 0 === strpos( $hex, '#' ) ) { 442 | $hex = substr( $hex, 1 ); 443 | } 444 | elseif ( 0 === strpos( $hex, '%23' ) ) { 445 | $hex = substr( $hex, 3 ); 446 | } 447 | /* Regex match. */ 448 | if ( 0 === preg_match( '/^[0-9a-fA-F]{6}$/', $hex ) ) { 449 | return false; 450 | } 451 | else { 452 | return true; 453 | } 454 | } -------------------------------------------------------------------------------- /inc/js/media-uploader.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function($){ 2 | 3 | var optionsframework_upload; 4 | var optionsframework_selector; 5 | 6 | function optionsframework_add_file(event, selector) { 7 | 8 | var upload = $(".uploaded-file"), frame; 9 | var $el = $(this); 10 | optionsframework_selector = selector; 11 | 12 | event.preventDefault(); 13 | 14 | // If the media frame already exists, reopen it. 15 | if ( optionsframework_upload ) { 16 | optionsframework_upload.open(); 17 | } else { 18 | // Create the media frame. 19 | optionsframework_upload = wp.media.frames.optionsframework_upload = wp.media({ 20 | // Set the title of the modal. 21 | title: $el.data('choose'), 22 | 23 | // Customize the submit button. 24 | button: { 25 | // Set the text of the button. 26 | text: $el.data('update'), 27 | // Tell the button not to close the modal, since we're 28 | // going to refresh the page when the image is selected. 29 | close: false 30 | } 31 | }); 32 | 33 | // When an image is selected, run a callback. 34 | optionsframework_upload.on( 'select', function() { 35 | // Grab the selected attachment. 36 | var attachment = optionsframework_upload.state().get('selection').first(); 37 | optionsframework_upload.close(); 38 | optionsframework_selector.find('.upload').val(attachment.attributes.url); 39 | if ( attachment.attributes.type == 'image' ) { 40 | optionsframework_selector.find('.screenshot').empty().hide().append('Remove').slideDown('fast'); 41 | } 42 | optionsframework_selector.find('.upload-button').unbind().addClass('remove-file').removeClass('upload-button').val(optionsframework_l10n.remove); 43 | optionsframework_selector.find('.of-background-properties').slideDown(); 44 | optionsframework_selector.find('.remove-image, .remove-file').on('click', function() { 45 | optionsframework_remove_file( $(this).parents('.section') ); 46 | }); 47 | }); 48 | 49 | } 50 | 51 | // Finally, open the modal. 52 | optionsframework_upload.open(); 53 | } 54 | 55 | function optionsframework_remove_file(selector) { 56 | selector.find('.remove-image').hide(); 57 | selector.find('.upload').val(''); 58 | selector.find('.of-background-properties').hide(); 59 | selector.find('.screenshot').slideUp(); 60 | selector.find('.remove-file').unbind().addClass('upload-button').removeClass('remove-file').val(optionsframework_l10n.upload); 61 | // We don't display the upload button if .upload-notice is present 62 | // This means the user doesn't have the WordPress 3.5 Media Library Support 63 | if ( $('.section-upload .upload-notice').length > 0 ) { 64 | $('.upload-button').remove(); 65 | } 66 | selector.find('.upload-button').on('click', function(event) { 67 | optionsframework_add_file(event, $(this).parents('.section')); 68 | }); 69 | } 70 | 71 | $('.remove-image, .remove-file').on('click', function() { 72 | optionsframework_remove_file( $(this).parents('.section') ); 73 | }); 74 | 75 | $('.upload-button').click( function( event ) { 76 | optionsframework_add_file(event, $(this).parents('.section')); 77 | }); 78 | 79 | }); -------------------------------------------------------------------------------- /inc/js/options-custom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom scripts needed for the colorpicker, image button selectors, 3 | * and navigation tabs. 4 | */ 5 | 6 | jQuery(document).ready(function($) { 7 | 8 | // Loads the color pickers 9 | $('.of-color').wpColorPicker(); 10 | 11 | // Image Options 12 | $('.of-radio-img-img').click(function(){ 13 | $(this).parent().parent().find('.of-radio-img-img').removeClass('of-radio-img-selected'); 14 | $(this).addClass('of-radio-img-selected'); 15 | }); 16 | 17 | $('.of-radio-img-label').hide(); 18 | $('.of-radio-img-img').show(); 19 | $('.of-radio-img-radio').hide(); 20 | 21 | // Loads tabbed sections if they exist 22 | if ( $('.nav-tab-wrapper').length > 0 ) { 23 | options_framework_tabs(); 24 | } 25 | 26 | function options_framework_tabs() { 27 | 28 | var $group = $('.group'), 29 | $navtabs = $('.nav-tab-wrapper a'), 30 | active_tab = ''; 31 | 32 | // Hides all the .group sections to start 33 | $group.hide(); 34 | 35 | // Find if a selected tab is saved in localStorage 36 | if ( typeof(localStorage) != 'undefined' ) { 37 | active_tab = localStorage.getItem('active_tab'); 38 | } 39 | 40 | // If active tab is saved and exists, load it's .group 41 | if ( active_tab != '' && $(active_tab).length ) { 42 | $(active_tab).fadeIn(); 43 | $(active_tab + '-tab').addClass('nav-tab-active'); 44 | } else { 45 | $('.group:first').fadeIn(); 46 | $('.nav-tab-wrapper a:first').addClass('nav-tab-active'); 47 | } 48 | 49 | // Bind tabs clicks 50 | $navtabs.click(function(e) { 51 | 52 | e.preventDefault(); 53 | 54 | // Remove active class from all tabs 55 | $navtabs.removeClass('nav-tab-active'); 56 | 57 | $(this).addClass('nav-tab-active').blur(); 58 | 59 | if (typeof(localStorage) != 'undefined' ) { 60 | localStorage.setItem('active_tab', $(this).attr('href') ); 61 | } 62 | 63 | var selected = $(this).attr('href'); 64 | 65 | $group.hide(); 66 | $(selected).fadeIn(); 67 | 68 | }); 69 | } 70 | 71 | }); -------------------------------------------------------------------------------- /inc/options-framework.php: -------------------------------------------------------------------------------- 1 | 7 | * @license GPL-2.0+ 8 | * @link http://wptheming.com 9 | * @copyright 2010-2014 WP Theming 10 | * 11 | * @wordpress-plugin 12 | * Plugin Name: Options Framework 13 | * Plugin URI: http://wptheming.com 14 | * Description: A framework for building theme options. 15 | * Version: 1.9.1 16 | * Author: Devin Price 17 | * Author URI: http://wptheming.com 18 | * License: GPL-2.0+ 19 | * License URI: http://www.gnu.org/licenses/gpl-2.0.txt 20 | * Text Domain: optionsframework 21 | * Domain Path: /languages 22 | */ 23 | 24 | // If this file is called directly, abort. 25 | if ( ! defined( 'WPINC' ) ) { 26 | die; 27 | } 28 | 29 | // Don't load if optionsframework_init is already defined 30 | if (is_admin() && ! function_exists( 'optionsframework_init' ) ) : 31 | 32 | function optionsframework_init() { 33 | 34 | // If user can't edit theme options, exit 35 | if ( ! current_user_can( 'edit_theme_options' ) ) { 36 | return; 37 | } 38 | 39 | // Loads the required Options Framework classes. 40 | require plugin_dir_path( __FILE__ ) . 'includes/class-options-framework.php'; 41 | require plugin_dir_path( __FILE__ ) . 'includes/class-options-framework-admin.php'; 42 | require plugin_dir_path( __FILE__ ) . 'includes/class-options-interface.php'; 43 | require plugin_dir_path( __FILE__ ) . 'includes/class-options-media-uploader.php'; 44 | require plugin_dir_path( __FILE__ ) . 'includes/class-options-sanitization.php'; 45 | 46 | // Instantiate the options page. 47 | $options_framework_admin = new Options_Framework_Admin; 48 | $options_framework_admin->init(); 49 | 50 | // Instantiate the media uploader class 51 | $options_framework_media_uploader = new Options_Framework_Media_Uploader; 52 | $options_framework_media_uploader->init(); 53 | 54 | } 55 | 56 | add_action( 'init', 'optionsframework_init', 20 ); 57 | 58 | endif; 59 | 60 | 61 | /** 62 | * Helper function to return the theme option value. 63 | * If no value has been saved, it returns $default. 64 | * Needed because options are saved as serialized strings. 65 | * 66 | * Not in a class to support backwards compatibility in themes. 67 | */ 68 | if ( ! function_exists( 'of_get_option' ) ) : 69 | function of_get_option( $name, $default = false ) { 70 | 71 | $option_name = ''; 72 | 73 | // Gets option name as defined in the theme 74 | if ( function_exists( 'optionsframework_option_name' ) ) { 75 | $option_name = optionsframework_option_name(); 76 | } 77 | 78 | // Fallback option name 79 | if ( '' == $option_name ) { 80 | $option_name = get_option( 'stylesheet' ); 81 | $option_name = preg_replace( "/\W/", "_", strtolower( $option_name ) ); 82 | } 83 | 84 | // Get option settings from database 85 | $options = get_option( $option_name ); 86 | 87 | // Return specific option 88 | if ( isset( $options[$name] ) ) { 89 | return $options[$name]; 90 | } 91 | 92 | return $default; 93 | } 94 | endif; -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 |
16 |

Options Framework Theme

17 |

Use of_get_option($id,$default) to return option values.

18 |
19 | 20 |
21 | 22 |

About

23 | 24 |

This is the adapted theme version of the Options Framework plugin, which makes it easy to include an options panel for any theme.

25 | 26 |

How to Include in Your Own Project

27 | 28 |

Just drag the admin folder of this theme, options.php and functions.php into the theme of your choice.

29 | 30 |
31 | 32 |

Basic Options

33 | 34 |
35 |
type: text (mini)
36 |
of_get_option('example_text_mini'):
37 |
38 | 39 |
40 |
type: text
41 |
of_get_option('example_text'):
42 |
43 | 44 |
45 |
type: textarea
46 |
of_get_option('example_textarea'):
47 |
48 | 49 |
50 |
type: select (mini)
51 |
of_get_option('example_select'):
52 |
53 | 54 |
55 |
type: select2 (wide)
56 |
of_get_option('example_select_wide'):
57 |
58 | 59 |
60 |
type: select
61 |
of_get_option('example_select_categories'): category id =
62 |
63 | 64 |
65 |
type: select
66 |
of_get_option('example_select_tags'): term id =
67 |
68 | 69 |
70 |
type: select
71 |
of_get_option('example_select_pages'): page id =
72 |
73 | 74 |
75 |
type: radio
76 |
of_get_option('example_radio'):
77 |
78 | 79 |
80 |
type: checkbox
81 |
of_get_option('example_checkbox'):
82 |
83 | 84 |
85 | 86 |

Advanced Options

87 | 88 |
89 |
type: uploader
90 |
of_get_option('example_uploader'):
91 | 92 | 93 | 94 |
95 | 96 |
97 |
type: image
98 |
of_get_option('images'):
99 |
100 | 101 |
102 |
type: multicheck
103 |
of_get_option('multicheck'): 104 | 105 | 106 |
107 |
108 | 109 |

The array sent in the options panel was defined as:
110 | "French Toast", "two" => "Pancake", "three" => "Omelette", "four" => "Crepe", "five" => "Waffle" ); 112 | print_r( $test_array_jr ); 113 | ?> 114 |

115 | 116 |

You can get the value of all items in the checkbox array:

117 |
    118 | $value ) { 121 | // If you need the option's name rather than the key you can get that 122 | $name = $test_array_jr[$key]; 123 | // Prints out each of the values 124 | echo '
  • ' . $key . ' (' . $name . ') = ' . $value . '
  • '; 125 | } 126 | } 127 | else { 128 | echo '
  • There are no saved values yet.
  • '; 129 | } 130 | ?> 131 |
132 | 133 |

You can also get an individual checkbox value if you know what you are looking for. In this example, I'll check for the key "one", which is an item I sent in the array for checkboxes:

134 | 135 |

The value of the multicheck box "one" of example_multicheck is: 136 | 137 | 144 | 145 |

146 | 147 |
148 |
type: background
149 |
of_get_option('background'): 150 | '; 154 | echo '
    '; 155 | foreach ( $background as $i=> $param ){ 156 | echo '
  • '.$i . ' = ' . $param . '
  • '; 157 | } 158 | echo '
'; 159 | } else { 160 | echo ''; 161 | echo '
    '; 162 | echo '
  • '.$background['color'].'
  • '; 163 | echo '
'; 164 | } 165 | } else { 166 | echo "no entry"; 167 | }; ?> 168 | 169 |
170 |
171 | 172 |
173 |
type: colorpicker
174 |
of_get_option('colorpicker'): 175 | 176 | 177 | 178 |
179 |
180 | 181 |
182 |
type: typography
183 |
of_get_option('typography'): 184 | '; 187 | foreach ( $typography as $i => $param ) { 188 | echo '
  • '.$i . ' = ' . $param . '
  • '; 189 | } 190 | echo ''; 191 | echo 'Some sample text in your style'; 192 | } else { 193 | echo "no entry"; 194 | } ?> 195 |
    196 |
    197 | 198 |
    199 | 200 |

    Editor

    201 | 202 |
    203 |
    type: editor
    204 |
    of_get_option('example_editor'):
    205 | 206 |
    207 |
    208 | 209 |
    210 |
    211 | 212 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 6 | 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | Preamble 11 | 12 | The licenses for most software are designed to take away your 13 | freedom to share and change it. By contrast, the GNU General Public 14 | License is intended to guarantee your freedom to share and change free 15 | software--to make sure the software is free for all its users. This 16 | General Public License applies to most of the Free Software 17 | Foundation's software and to any other program whose authors commit to 18 | using it. (Some other Free Software Foundation software is covered by 19 | the GNU Library General Public License instead.) You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | this service if you wish), that you receive source code or can get it 26 | if you want it, that you can change the software or use pieces of it 27 | in new free programs; and that you know you can do these things. 28 | 29 | To protect your rights, we need to make restrictions that forbid 30 | anyone to deny you these rights or to ask you to surrender the rights. 31 | These restrictions translate to certain responsibilities for you if you 32 | distribute copies of the software, or if you modify it. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must give the recipients all the rights that 36 | you have. You must make sure that they, too, receive or can get the 37 | source code. And you must show them these terms so they know their 38 | rights. 39 | 40 | We protect your rights with two steps: (1) copyright the software, and 41 | (2) offer you this license which gives you legal permission to copy, 42 | distribute and/or modify the software. 43 | 44 | Also, for each author's protection and ours, we want to make certain 45 | that everyone understands that there is no warranty for this free 46 | software. If the software is modified by someone else and passed on, we 47 | want its recipients to know that what they have is not the original, so 48 | that any problems introduced by others will not reflect on the original 49 | authors' reputations. 50 | 51 | Finally, any free program is threatened constantly by software 52 | patents. We wish to avoid the danger that redistributors of a free 53 | program will individually obtain patent licenses, in effect making the 54 | program proprietary. To prevent this, we have made it clear that any 55 | patent must be licensed for everyone's free use or not licensed at all. 56 | 57 | The precise terms and conditions for copying, distribution and 58 | modification follow. 59 | 60 | GNU GENERAL PUBLIC LICENSE 61 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 62 | 63 | 0. This License applies to any program or other work which contains 64 | a notice placed by the copyright holder saying it may be distributed 65 | under the terms of this General Public License. The "Program", below, 66 | refers to any such program or work, and a "work based on the Program" 67 | means either the Program or any derivative work under copyright law: 68 | that is to say, a work containing the Program or a portion of it, 69 | either verbatim or with modifications and/or translated into another 70 | language. (Hereinafter, translation is included without limitation in 71 | the term "modification".) Each licensee is addressed as "you". 72 | 73 | Activities other than copying, distribution and modification are not 74 | covered by this License; they are outside its scope. The act of 75 | running the Program is not restricted, and the output from the Program 76 | is covered only if its contents constitute a work based on the 77 | Program (independent of having been made by running the Program). 78 | Whether that is true depends on what the Program does. 79 | 80 | 1. You may copy and distribute verbatim copies of the Program's 81 | source code as you receive it, in any medium, provided that you 82 | conspicuously and appropriately publish on each copy an appropriate 83 | copyright notice and disclaimer of warranty; keep intact all the 84 | notices that refer to this License and to the absence of any warranty; 85 | and give any other recipients of the Program a copy of this License 86 | along with the Program. 87 | 88 | You may charge a fee for the physical act of transferring a copy, and 89 | you may at your option offer warranty protection in exchange for a fee. 90 | 91 | 2. You may modify your copy or copies of the Program or any portion 92 | of it, thus forming a work based on the Program, and copy and 93 | distribute such modifications or work under the terms of Section 1 94 | above, provided that you also meet all of these conditions: 95 | 96 | a) You must cause the modified files to carry prominent notices 97 | stating that you changed the files and the date of any change. 98 | 99 | b) You must cause any work that you distribute or publish, that in 100 | whole or in part contains or is derived from the Program or any 101 | part thereof, to be licensed as a whole at no charge to all third 102 | parties under the terms of this License. 103 | 104 | c) If the modified program normally reads commands interactively 105 | when run, you must cause it, when started running for such 106 | interactive use in the most ordinary way, to print or display an 107 | announcement including an appropriate copyright notice and a 108 | notice that there is no warranty (or else, saying that you provide 109 | a warranty) and that users may redistribute the program under 110 | these conditions, and telling the user how to view a copy of this 111 | License. (Exception: if the Program itself is interactive but 112 | does not normally print such an announcement, your work based on 113 | the Program is not required to print an announcement.) 114 | 115 | These requirements apply to the modified work as a whole. If 116 | identifiable sections of that work are not derived from the Program, 117 | and can be reasonably considered independent and separate works in 118 | themselves, then this License, and its terms, do not apply to those 119 | sections when you distribute them as separate works. But when you 120 | distribute the same sections as part of a whole which is a work based 121 | on the Program, the distribution of the whole must be on the terms of 122 | this License, whose permissions for other licensees extend to the 123 | entire whole, and thus to each and every part regardless of who wrote it. 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | -------------------------------------------------------------------------------- /options.php: -------------------------------------------------------------------------------- 1 | __( 'One', 'theme-textdomain' ), 24 | 'two' => __( 'Two', 'theme-textdomain' ), 25 | 'three' => __( 'Three', 'theme-textdomain' ), 26 | 'four' => __( 'Four', 'theme-textdomain' ), 27 | 'five' => __( 'Five', 'theme-textdomain' ) 28 | ); 29 | 30 | // Multicheck Array 31 | $multicheck_array = array( 32 | 'one' => __( 'French Toast', 'theme-textdomain' ), 33 | 'two' => __( 'Pancake', 'theme-textdomain' ), 34 | 'three' => __( 'Omelette', 'theme-textdomain' ), 35 | 'four' => __( 'Crepe', 'theme-textdomain' ), 36 | 'five' => __( 'Waffle', 'theme-textdomain' ) 37 | ); 38 | 39 | // Multicheck Defaults 40 | $multicheck_defaults = array( 41 | 'one' => '1', 42 | 'five' => '1' 43 | ); 44 | 45 | // Background Defaults 46 | $background_defaults = array( 47 | 'color' => '', 48 | 'image' => '', 49 | 'repeat' => 'repeat', 50 | 'position' => 'top center', 51 | 'attachment'=>'scroll' ); 52 | 53 | // Typography Defaults 54 | $typography_defaults = array( 55 | 'size' => '15px', 56 | 'face' => 'georgia', 57 | 'style' => 'bold', 58 | 'color' => '#bada55' ); 59 | 60 | // Typography Options 61 | $typography_options = array( 62 | 'sizes' => array( '6','12','14','16','20' ), 63 | 'faces' => array( 'Helvetica Neue' => 'Helvetica Neue','Arial' => 'Arial' ), 64 | 'styles' => array( 'normal' => 'Normal','bold' => 'Bold' ), 65 | 'color' => false 66 | ); 67 | 68 | // Pull all the categories into an array 69 | $options_categories = array(); 70 | $options_categories_obj = get_categories(); 71 | foreach ($options_categories_obj as $category) { 72 | $options_categories[$category->cat_ID] = $category->cat_name; 73 | } 74 | 75 | // Pull all tags into an array 76 | $options_tags = array(); 77 | $options_tags_obj = get_tags(); 78 | foreach ( $options_tags_obj as $tag ) { 79 | $options_tags[$tag->term_id] = $tag->name; 80 | } 81 | 82 | 83 | // Pull all the pages into an array 84 | $options_pages = array(); 85 | $options_pages_obj = get_pages( 'sort_column=post_parent,menu_order' ); 86 | $options_pages[''] = 'Select a page:'; 87 | foreach ($options_pages_obj as $page) { 88 | $options_pages[$page->ID] = $page->post_title; 89 | } 90 | 91 | // If using image radio buttons, define a directory path 92 | $imagepath = get_template_directory_uri() . '/images/'; 93 | 94 | $options = array(); 95 | 96 | $options[] = array( 97 | 'name' => __( 'Basic Settings', 'theme-textdomain' ), 98 | 'type' => 'heading' 99 | ); 100 | 101 | $options[] = array( 102 | 'name' => __( 'Input Text Mini', 'theme-textdomain' ), 103 | 'desc' => __( 'A mini text input field.', 'theme-textdomain' ), 104 | 'id' => 'example_text_mini', 105 | 'std' => 'Default', 106 | 'class' => 'mini', 107 | 'type' => 'text' 108 | ); 109 | 110 | $options[] = array( 111 | 'name' => __( 'Input Text', 'theme-textdomain' ), 112 | 'desc' => __( 'A text input field.', 'theme-textdomain' ), 113 | 'id' => 'example_text', 114 | 'std' => 'Default Value', 115 | 'type' => 'text' 116 | ); 117 | 118 | $options[] = array( 119 | 'name' => __( 'Input with Placeholder', 'theme-textdomain' ), 120 | 'desc' => __( 'A text input field with an HTML5 placeholder.', 'theme-textdomain' ), 121 | 'id' => 'example_placeholder', 122 | 'placeholder' => 'Placeholder', 123 | 'type' => 'text' 124 | ); 125 | 126 | $options[] = array( 127 | 'name' => __( 'Textarea', 'theme-textdomain' ), 128 | 'desc' => __( 'Textarea description.', 'theme-textdomain' ), 129 | 'id' => 'example_textarea', 130 | 'std' => 'Default Text', 131 | 'type' => 'textarea' 132 | ); 133 | 134 | $options[] = array( 135 | 'name' => __( 'Input Select Small', 'theme-textdomain' ), 136 | 'desc' => __( 'Small Select Box.', 'theme-textdomain' ), 137 | 'id' => 'example_select', 138 | 'std' => 'three', 139 | 'type' => 'select', 140 | 'class' => 'mini', //mini, tiny, small 141 | 'options' => $test_array 142 | ); 143 | 144 | $options[] = array( 145 | 'name' => __( 'Input Select Wide', 'theme-textdomain' ), 146 | 'desc' => __( 'A wider select box.', 'theme-textdomain' ), 147 | 'id' => 'example_select_wide', 148 | 'std' => 'two', 149 | 'type' => 'select', 150 | 'options' => $test_array 151 | ); 152 | 153 | if ( $options_categories ) { 154 | $options[] = array( 155 | 'name' => __( 'Select a Category', 'theme-textdomain' ), 156 | 'desc' => __( 'Passed an array of categories with cat_ID and cat_name', 'theme-textdomain' ), 157 | 'id' => 'example_select_categories', 158 | 'type' => 'select', 159 | 'options' => $options_categories 160 | ); 161 | } 162 | 163 | if ( $options_tags ) { 164 | $options[] = array( 165 | 'name' => __( 'Select a Tag', 'options_check' ), 166 | 'desc' => __( 'Passed an array of tags with term_id and term_name', 'options_check' ), 167 | 'id' => 'example_select_tags', 168 | 'type' => 'select', 169 | 'options' => $options_tags 170 | ); 171 | } 172 | 173 | $options[] = array( 174 | 'name' => __( 'Select a Page', 'theme-textdomain' ), 175 | 'desc' => __( 'Passed an pages with ID and post_title', 'theme-textdomain' ), 176 | 'id' => 'example_select_pages', 177 | 'type' => 'select', 178 | 'options' => $options_pages 179 | ); 180 | 181 | $options[] = array( 182 | 'name' => __( 'Input Radio (one)', 'theme-textdomain' ), 183 | 'desc' => __( 'Radio select with default options "one".', 'theme-textdomain' ), 184 | 'id' => 'example_radio', 185 | 'std' => 'one', 186 | 'type' => 'radio', 187 | 'options' => $test_array 188 | ); 189 | 190 | $options[] = array( 191 | 'name' => __( 'Example Info', 'theme-textdomain' ), 192 | 'desc' => __( 'This is just some example information you can put in the panel.', 'theme-textdomain' ), 193 | 'type' => 'info' 194 | ); 195 | 196 | $options[] = array( 197 | 'name' => __( 'Input Checkbox', 'theme-textdomain' ), 198 | 'desc' => __( 'Example checkbox, defaults to true.', 'theme-textdomain' ), 199 | 'id' => 'example_checkbox', 200 | 'std' => '1', 201 | 'type' => 'checkbox' 202 | ); 203 | 204 | $options[] = array( 205 | 'name' => __( 'Advanced Settings', 'theme-textdomain' ), 206 | 'type' => 'heading' 207 | ); 208 | 209 | $options[] = array( 210 | 'name' => __( 'Check to Show a Hidden Text Input', 'theme-textdomain' ), 211 | 'desc' => __( 'Click here and see what happens.', 'theme-textdomain' ), 212 | 'id' => 'example_showhidden', 213 | 'type' => 'checkbox' 214 | ); 215 | 216 | $options[] = array( 217 | 'name' => __( 'Hidden Text Input', 'theme-textdomain' ), 218 | 'desc' => __( 'This option is hidden unless activated by a checkbox click.', 'theme-textdomain' ), 219 | 'id' => 'example_text_hidden', 220 | 'std' => 'Hello', 221 | 'class' => 'hidden', 222 | 'type' => 'text' 223 | ); 224 | 225 | $options[] = array( 226 | 'name' => __( 'Uploader Test', 'theme-textdomain' ), 227 | 'desc' => __( 'This creates a full size uploader that previews the image.', 'theme-textdomain' ), 228 | 'id' => 'example_uploader', 229 | 'type' => 'upload' 230 | ); 231 | 232 | $options[] = array( 233 | 'name' => "Example Image Selector", 234 | 'desc' => "Images for layout.", 235 | 'id' => "example_images", 236 | 'std' => "2c-l-fixed", 237 | 'type' => "images", 238 | 'options' => array( 239 | '1col-fixed' => $imagepath . '1col.png', 240 | '2c-l-fixed' => $imagepath . '2cl.png', 241 | '2c-r-fixed' => $imagepath . '2cr.png' 242 | ) 243 | ); 244 | 245 | $options[] = array( 246 | 'name' => __( 'Example Background', 'theme-textdomain' ), 247 | 'desc' => __( 'Change the background CSS.', 'theme-textdomain' ), 248 | 'id' => 'example_background', 249 | 'std' => $background_defaults, 250 | 'type' => 'background' 251 | ); 252 | 253 | $options[] = array( 254 | 'name' => __( 'Multicheck', 'theme-textdomain' ), 255 | 'desc' => __( 'Multicheck description.', 'theme-textdomain' ), 256 | 'id' => 'example_multicheck', 257 | 'std' => $multicheck_defaults, // These items get checked by default 258 | 'type' => 'multicheck', 259 | 'options' => $multicheck_array 260 | ); 261 | 262 | $options[] = array( 263 | 'name' => __( 'Colorpicker', 'theme-textdomain' ), 264 | 'desc' => __( 'No color selected by default.', 'theme-textdomain' ), 265 | 'id' => 'example_colorpicker', 266 | 'std' => '', 267 | 'type' => 'color' 268 | ); 269 | 270 | $options[] = array( 'name' => __( 'Typography', 'theme-textdomain' ), 271 | 'desc' => __( 'Example typography.', 'theme-textdomain' ), 272 | 'id' => "example_typography", 273 | 'std' => $typography_defaults, 274 | 'type' => 'typography' 275 | ); 276 | 277 | $options[] = array( 278 | 'name' => __( 'Custom Typography', 'theme-textdomain' ), 279 | 'desc' => __( 'Custom typography options.', 'theme-textdomain' ), 280 | 'id' => "custom_typography", 281 | 'std' => $typography_defaults, 282 | 'type' => 'typography', 283 | 'options' => $typography_options 284 | ); 285 | 286 | $options[] = array( 287 | 'name' => __( 'Text Editor', 'theme-textdomain' ), 288 | 'type' => 'heading' 289 | ); 290 | 291 | /** 292 | * For $settings options see: 293 | * http://codex.wordpress.org/Function_Reference/wp_editor 294 | * 295 | * 'media_buttons' are not supported as there is no post to attach items to 296 | * 'textarea_name' is set by the 'id' you choose 297 | */ 298 | 299 | $wp_editor_settings = array( 300 | 'wpautop' => true, // Default 301 | 'textarea_rows' => 5, 302 | 'tinymce' => array( 'plugins' => 'wordpress,wplink' ) 303 | ); 304 | 305 | $options[] = array( 306 | 'name' => __( 'Default Text Editor', 'theme-textdomain' ), 307 | 'desc' => sprintf( __( 'You can also pass settings to the editor. Read more about wp_editor in the WordPress codex', 'theme-textdomain' ), 'http://codex.wordpress.org/Function_Reference/wp_editor' ), 308 | 'id' => 'example_editor', 309 | 'type' => 'editor', 310 | 'settings' => $wp_editor_settings 311 | ); 312 | 313 | return $options; 314 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Options Framework Theme 2 | 3 | Contributors: Devin Price 4 | Tags: options, theme options 5 | Donate link: http://bit.ly/options-donate-2 6 | Requires at least: 3.6 7 | Tested up to: 4.0 8 | Stable tag: 1.9.1 9 | License: GPLv2 10 | 11 | ## Description 12 | 13 | This is the adapted theme version of the Options Framework plugin. 14 | 15 | The Options Framework makes it easy to include an options panel in any WordPress theme. It was built so developers can concentrate on making the actual theme rather than spending time creating an options panel from scratch. 16 | 17 | ## Frequently Asked Questions 18 | 19 | ### How do I build options for my own theme? 20 | 21 | Just drag the "inc" folder of this theme, options.php and functions.php into the theme of your choice. 22 | 23 | options.php is a blueprint for how to work with options. It includes an example of every option available in the panel and sample output in the theme. 24 | 25 | You can also watch the video screencast I have at [http://wptheming.com/options-framework-theme](http://wptheming.com/options-framework-theme). 26 | 27 | ### What options are available to use? 28 | 29 | * text 30 | * textarea 31 | * checkbox 32 | * select 33 | * radio 34 | * upload (an image uploader) 35 | * images (use images instead of radio buttons) 36 | * background (a set of options to define a background) 37 | * multicheck 38 | * color (a jquery color picker) 39 | * typography (a set of options to define typography) 40 | * editor 41 | 42 | ## Changelog 43 | 44 | #### Development 45 | 46 | * Update: Change sanitization of editor to use $allowedposttags 47 | * Update: Include link button in tinyMCE (props @rosswintle) 48 | * Update: Style headers to look nice in WordPress 4.4 49 | 50 | #### 1.9.1 51 | 52 | * Update: Use "theme-textdomain" consistently 53 | * Update: Load options.php so child themes can easily override 54 | * Enhancement: New filter "options_framework_option_name" 55 | 56 | #### 1.9.0 57 | 58 | * Breaking Change: Change how option name is defined 59 | 60 | #### 1.8.1 61 | 62 | * Remove sanitization of info option and description field 63 | 64 | #### 1.8.0 65 | 66 | * Fix for colorpicker spacing 67 | * Better sanitization of upload option 68 | * Use filtered values for optionsframework_admin_bar 69 | * More filters for menu location 70 | * Placeholders can be used with text and textarea options (@Furex) 71 | 72 | #### 1.7.2 73 | 74 | * Increase text input width 75 | * Rename add_options_page function to resolve automatic theme check conflicts 76 | * Check isset for $value['desc'] in info option 77 | * Only load styles on options page (props @AndorChen) 78 | 79 | #### 1.7.1 80 | 81 | * Fix to use option name if set in options.php 82 | 83 | #### 1.7.0 84 | 85 | * Update to class based plugin (large code refactor) 86 | * Drop color picker support for older versions of WordPress 87 | * Allow option pages without tabs 88 | 89 | #### 1.6.1 90 | 91 | * Fix for update notice location 92 | * Use checked() function more consistently (props @vinodvdalvi) 93 | * Reuse media modal for uploads 94 | * Avoid error if $options array not set (props @albyrock87) 95 | 96 | #### 1.6 97 | 98 | * JS/CSS should only load on options page 99 | * Make options filterable like plugin version 100 | * Allow media buttons in the editor option 101 | * Menu settings filter 102 | * Fix js bindings for upload modal (props @themeblvd) 103 | 104 | #### 1.5.2 105 | 106 | * Removed updater script, it was causing issues with attachments 107 | 108 | #### 1.5 109 | 110 | * Updated width of text input 111 | * New media uploader 112 | * Dropped custom post types for file attachments 113 | * Updater script to remove the unused 'optionsframework' post types 114 | * Updated IDs for .tabs and .groups 115 | 116 | #### 1.4 117 | 118 | * Add missing sanitization to typography color (@weplantmedia) 119 | * New colorpicker (props @mattweibe for getting this in WordPress core) 120 | * Farsi translations (@vahidd.com) 121 | * Added password option type (props @neojp) 122 | * Allow ids to passed to tabs (props @themeblvd) 123 | * Added optionsframework_after_validate hook (h/t @vanpop and @pryley) 124 | 125 | #### 1.3 126 | 127 | * Allow options to save when set by theme customizer 128 | * Save checkbox options to boolean false rather than "0" 129 | * Added optionsframework_after hook 130 | * Normalized text domains to options_framework_theme 131 | 132 | #### 1.2 133 | 134 | * ID can now be passed on info option for styling purposes 135 | 136 | #### 1.1 137 | 138 | * Move js example from functions.php to options.php 139 | * Simplify functions.php, no check for child theme now 140 | * Display admin menu link only if user has permissions (props @mindctrl) 141 | * Added support for wp_editor 142 | * Updated textarea settings to allow rows parameter 143 | * Updated cursor:default for h3 metabox, props @yurifedorov 144 | * Filtering of typography options (@mattwiebe) 145 | * Updated methods for typography options 146 | * Make uploader post type non-public (@samargulies) 147 | * Change name of admin folder to inc 148 | 149 | #### 1.0 150 | 151 | * Option header (h4) will not display in panel if name !isset (props @alepee) 152 | * Fix for user roles when saving options 153 | * Updated theme to no longer be a child of Twenty Eleven 154 | * Updated textarea settings to allow rows parameter 155 | * Updated cursor:default for h3 metabox, props @yurifedorov 156 | 157 | #### 0.9 158 | 159 | * Load thickbox using site_url() to allow for https (props @samargulies) 160 | * Change santization to use $allowedposttags for textarea and info 161 | * Single checkboxes now use labels 162 | * CSS updates for formatting long labels 163 | * Allows dashes in the options id (props @mantone) 164 | * Uses add_theme_page over add_submenu_page (props @enile8) 165 | 166 | #### 0.8 167 | 168 | * Saves tab states using local storage 169 | * Minor style updates for WordPress 3.2 release 170 | 171 | #### 0.7 172 | 173 | * Added filtering for recognized arrays (like Font Face) 174 | * Using isset rather than !empty to return of_get_option 175 | * Significant updates for setting and restoring defaults 176 | * Background option outputs no-repeat rather than none 177 | 178 | #### 0.6 179 | 180 | * Introduces validation filters 181 | * Better data sanitization and escaping 182 | * Updates labels in options-interface.php 183 | * Changes how checkboxes saved in database ("0" or "1") 184 | * Stores typography, backgrounds and multichecks directly as arrays 185 | * For full description, see: http://wptheming.com/2011/05/options-framework-0-6/ 186 | 187 | #### 0.5 188 | 189 | * Fixed errors when more than one multicheck options is used 190 | * Updated optionsframework_setdefaults so defaults actually save on first run 191 | * Require that all options have lowercase alphanumeric ids 192 | * Added link to options from the WordPress admin bar 193 | 194 | #### 0.4 195 | 196 | * Updated multicheck option to save keys rather than values 197 | * Unset default array options after each output in optionsframework_setdefaults 198 | 199 | #### 0.3 200 | 201 | * White listed options for increased security 202 | * Fixed errors with checkbox and select boxes 203 | * Improved the multicheck option and changed format 204 | 205 | #### 0.2 206 | 207 | * Uploaded to the WordPress repository 208 | 209 | #### 0.1 210 | 211 | * Initial release -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devinsays/options-framework-theme/10eef1860dd9b9f4dd88932798e1926aaf1d305a/screenshot.png -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: Options Framework Theme 3 | Theme URI: http://wptheming.com 4 | Description: An example/test theme with a complete theme options panel. 5 | Author: Devin Price 6 | Author URI: http://wptheming.com 7 | Version: 1.9.1 8 | */ 9 | 10 | body { 11 | background:#eee; 12 | } 13 | 14 | body, input, textarea { 15 | color: #373737; 16 | font: 15px "Helvetica Neue", Helvetica, Arial, sans-serif; 17 | font-weight: 300; 18 | line-height: 1.625; 19 | } 20 | 21 | p { 22 | margin:0 0 10px 0; 23 | } 24 | 25 | h1, h2, h3 { 26 | margin:0 0 10px 0; 27 | } 28 | 29 | #page { 30 | background:#fff; 31 | min-width:440px; 32 | max-width:740px; 33 | width:60%; 34 | margin:20px auto; 35 | } 36 | 37 | header { 38 | background:#dedede; 39 | padding:30px 40px; 40 | } 41 | 42 | .entry-content { 43 | padding:20px 40px; 44 | } 45 | 46 | .entry-content img { 47 | max-width: 100%; 48 | } --------------------------------------------------------------------------------