3

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 2

2

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.

14
  • Tip: list($var1, $var2) = array($var2, $var1); // swaps the values of $var1 and $var2
    – hakre
    Commented Aug 28, 2010 at 9:18
  • 1
    That's a plugin I would definitely wrap up in a class.
    – hakre
    Commented Aug 28, 2010 at 9:20
  • @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 .
    – hakre
    Commented Aug 28, 2010 at 12:06
  • 1
    I forked you. gist.github.com/554944
    – hakre
    Commented Aug 28, 2010 at 16:11
  • @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
0

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.

5
  • 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.
    – Amit
    Commented 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).
    – hakre
    Commented 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 :)
    – hakre
    Commented 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.