Is it possible to create multiple "custom background" administration pages? A site I'm doing now needs 2 different background in 2 different areas, I would really love giving my client the same experience for both backgrounds in terms of colour/image/select-repeat etc. Any Ideas?
2 Answers
Hi @Amit:
The answer is "Yes, it is possible." The follow up question is "Do you really want to?"
I thought it would be fun to see if I could build a plugin to do what you are asking for so I decided to see if it was possible. Of course I was able to make it work but I fear that the plugin code I wrote needs to be so tightly coupled with the existing code in WordPress that it might easily break on a core update.
This code handles all the admin console side of things by creating a new menu item in the Appearance section called "Special Background." What it does not do is provide any way to actually use the background; that's phase two of the plugin and will require hooking many of the functions in /wp-includes/themes.php
and frankly I don't know if I'll get a chance to write that code.
The reason I stopped without doing it is I didn't know the requirements for where the special background should show and where the regular one would show. I assume maybe for selected pages and/or URL paths?
Nonetheless, here if the code for the plugin (which you can also download from gist):
<?php
/*
Plugin Name: Special Background
Plugin URI: http://wordpress.stackexchange.com/questions/972/
Description: Example to show how to add a special background using exiting background admin page in core.
Version: 0.1
Author: Mike Schinkel
Author URI: http://mikeschinkel.com/custom-wordpress-plugins/
*/
add_filter('admin_menu','add_special_background_menu_item');
function add_special_background_menu_item() {
add_theme_page(__('Special Background'), __('Special Background'),'edit_theme_options','special-background','special_background_admin_page');
}
add_filter('admin_init','add_js_for_special_background');
function add_js_for_special_background() {
global $custom_background;
if (is_special_background_page()) {
wp_enqueue_script('custom-background');
wp_enqueue_style('farbtastic');
}
$hook = 'load-appearance_page_special-background';
add_action($hook, array(&$custom_background, 'admin_load'));
add_action($hook, array(&$custom_background, 'take_action'), 49);
add_action($hook, array(&$custom_background, 'handle_upload'), 49);
}
add_filter('theme_mod_background_image', 'theme_mod_special_background_image');
add_filter('theme_mod_background_image_thumb','theme_mod_special_background_image_thumb');
add_filter('theme_mod_background_repeat', 'theme_mod_special_background_repeat');
add_filter('theme_mod_background_position_x', 'theme_mod_special_background_position_x');
add_filter('theme_mod_background_attachment', 'theme_mod_special_background_attachment');
add_filter('theme_mod_background_color', 'theme_mod_special_background_color');
function theme_mod_special_background_image($defaults) {
return theme_mod_special_background_image_attrs('image',$defaults);
}
function theme_mod_special_background_image_thumb($defaults) {
return theme_mod_special_background_image_attrs('image_thumb',$defaults);
}
function theme_mod_special_background_repeat($defaults) {
return theme_mod_special_background_image_attrs('repeat',$defaults);
}
function theme_mod_special_background_position_x($defaults) {
return theme_mod_special_background_image_attrs('position_x',$defaults);
}
function theme_mod_special_background_attachment($defaults) {
return theme_mod_special_background_image_attrs('attachment',$defaults);
}
function theme_mod_special_background_color($defaults) {
return theme_mod_special_background_image_attrs('color',$defaults);
}
function theme_mod_special_background_image_attrs($attr,$defaults) {
if (is_special_background_page()) {
$mods = get_option( 'mods_' . get_current_theme() );
$defaults = (!empty($mods["special_background_{$attr}"]) ? $mods["special_background_{$attr}"] : '');
}
return $defaults;
}
add_filter('pre_update_option_mods_' . get_current_theme(),'pre_update_option_special_background_image',10,2);
function pre_update_option_special_background_image($newvalue, $oldvalue) {
static $times_called = 0;
if (!empty($_POST) && is_special_background_page()) {
if ((isset($_POST['action']) && $_POST['action']=='save') || isset($_POST['reset-background']) || isset($_POST['remove-background'])) {
switch ($times_called) {
case 0:
$newvalue = special_background_image_value_swap('image',$newvalue,$oldvalue);
break;
case 1:
$newvalue = special_background_image_value_swap('image_thumb',$newvalue,$oldvalue);
break;
}
} else {
if ($times_called==0 && isset($_POST['background-repeat'])) {
$newvalue = special_background_image_value_swap('repeat',$newvalue,$oldvalue);
}
if ($times_called==1 && isset($_POST['background-position-x'])) {
$newvalue = special_background_image_value_swap('position_x',$newvalue,$oldvalue);
}
if ($times_called==2 && isset($_POST['background-attachment'])) {
$newvalue = special_background_image_value_swap('attachment',$newvalue,$oldvalue);
}
if ($times_called==3 && isset($_POST['background-color'])) {
$newvalue = special_background_image_value_swap('color',$newvalue,$oldvalue);
}
}
$times_called++;
}
return $newvalue;
}
function special_background_image_value_swap($swap_what,$newvalue,$oldvalue) {
$newvalue["special_background_{$swap_what}"] = $newvalue["background_{$swap_what}"];
$newvalue["background_{$swap_what}"] = $oldvalue["background_{$swap_what}"];
return $newvalue;
}
function special_background_admin_page() {
global $custom_background;
if (is_special_background_page()) {
global $parent_file,$submenu_file,$title;
$parent_file = 'themes.php';
$submenu_file = 'themes.php?page=special-background';
$title = 'Special Background';
require_once(ABSPATH . 'wp-admin/admin-header.php');
ob_start();
$custom_background->admin_page();
$html = ob_get_clean();
$html = preg_replace('#<h2>([^<]+)</h2>#','<h2>Special Background</h2>',$html);
echo $html;
include(ABSPATH . 'wp-admin/admin-footer.php');
exit;
}
}
function is_special_background_page() {
global $pagenow;
return ($pagenow=='themes.php' &&
isset($_GET['page']) && $_GET['page']== 'special-background');
}
Frankly it is too much code to explain proactively but I'll be happy to answer specific questions.
-
Tip:
list($var1, $var2) = array($var2, $var1); // swaps the values of $var1 and $var2
– hakreCommented Aug 28, 2010 at 9:18 -
1
-
@MikeSchinkel: Can you add a little description on your swap/save concept? Are normally those theme_mod_background_image theme modification values used by wp core to offer the standard header? What do you do if there is no header in theme? I'm thinking about creating some hook/option facade object in my fork... updated: codex.wordpress.org/Theme_Modification_API .– hakreCommented Aug 28, 2010 at 12:06
-
1
-
@hakre; thanks for the tip on the swap. I am familiar with it though. You must understand that when I first wrote the function it was much more complicated and I refactored it down to what it is so I wasn't originally thinking it would be as simplistic. I also don't tend to wrap things up in a class for here on StackExchange because it make it harder for people to understand when all the class plumbing is in place (yet, it is not optimal; if I use a class more people will be scared off it; if I don't use a class I'm teaching them less good practice.) Commented Aug 28, 2010 at 17:27
Technically it's possible (so to extend the wordpress source), but not by default. So I would give the answer to no. The build-in background theme feature is for a single graphics only be default.
But if you describe a little bit more about the "2 different areas" you're writing about, there might be something nice to suggest next to this.
Edit: Highlight for MikeSchinkel. Plugins are extending the wordpress source.
-
Well.. There's the main site (20 sections or so) and then there's like a sub-site under one those sections which changes for this special event and need its own style colours and background image. Theoretically I could tell the client to upload an image to the "master page" of each section and call it "some-how" but I like the custom background functionality and semantic position in the CMS.– AmitCommented Aug 27, 2010 at 21:17
-
are you using a template per section? that might be something to hook in. Or to override with a subtheme for a certain area (that would scale to two background images then in total because you would have two themes, parent and child theme).– hakreCommented Aug 27, 2010 at 21:32
-
Ye of little faith! You should know not to say something is not possible with WordPress! ;-) Commented Aug 28, 2010 at 8:10
-
I didn't. I mean it's a pile of PHP you only need to re-arrange a little to get things done :)– hakreCommented Aug 28, 2010 at 9:14
-
True. But you shouldn't discourage people; where there is a will there is a way! Commented Aug 30, 2010 at 0:30