Multiple Custom_Background, è possibile?

27 ago 2010, 20:39:09
Visualizzazioni: 1.07K
Voti: 3

È possibile creare più pagine di amministrazione "sfondo personalizzato"? Un sito su cui sto lavorando necessita di 2 diversi sfondi in 2 aree diverse, mi piacerebbe molto dare al mio cliente la stessa esperienza per entrambi gli sfondi in termini di colore/immagine/selezione-ripetizione ecc. Qualche idea?

0
Tutte le risposte alla domanda 2
14

Ciao @Amit:

La risposta è "Sì, è possibile." La domanda successiva è "Lo vuoi veramente?"

Ho pensato che sarebbe stato divertente vedere se potevo creare un plugin per fare quello che chiedi, quindi ho deciso di verificare se fosse possibile. Naturalmente sono riuscito a farlo funzionare, ma temo che il codice del plugin che ho scritto debba essere così strettamente accoppiato con il codice esistente in WordPress che potrebbe facilmente rompersi con un aggiornamento del core.

Questo codice gestisce tutto il lato amministrativo creando una nuova voce di menu nella sezione Aspetto chiamata "Sfondo Speciale." Quello che non fa è fornire un modo per effettivamente utilizzare lo sfondo; quella è la seconda fase del plugin e richiederà l'hook di molte funzioni in /wp-includes/themes.php e francamente non so se avrò il tempo di scrivere quel codice.

Il motivo per cui mi sono fermato senza farlo è che non conoscevo i requisiti su dove lo sfondo speciale dovrebbe apparire e dove apparirebbe quello regolare. Immagino che potrebbe essere per pagine selezionate e/o percorsi URL?

Ad ogni modo, ecco il codice per il plugin (che puoi anche scaricare da gist):

<?php
/*
Plugin Name: Sfondo Speciale
Plugin URI: http://wordpress.stackexchange.com/questions/972/
Description: Esempio per mostrare come aggiungere uno sfondo speciale utilizzando la pagina di amministrazione dello sfondo esistente nel 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(__('Sfondo Speciale'), __('Sfondo Speciale'),'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 = 'Sfondo Speciale';
    require_once(ABSPATH . 'wp-admin/admin-header.php');
    ob_start();
    $custom_background->admin_page();
    $html = ob_get_clean();
    $html = preg_replace('#<h2>([^<]+)</h2>#','<h2>Sfondo Speciale</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');
}

Francamente è troppo codice da spiegare proattivamente, ma sarò felice di rispondere a domande specifiche.

28 ago 2010 08:10:05
Commenti

Suggerimento: list($var1, $var2) = array($var2, $var1); // scambia i valori di $var1 e $var2

hakre hakre
28 ago 2010 09:18:20

È un plugin che certamente racchiuderei in una classe.

hakre hakre
28 ago 2010 09:20:06

@MikeSchinkel: Puoi aggiungere una breve descrizione sul tuo concetto di swap/save? Normalmente quei valori di modifica del tema theme_mod_background_image sono utilizzati dal core di wp per offrire l'header standard? Cosa fai se non c'è un header nel tema? Sto pensando di creare un oggetto facade hook/option nel mio fork... aggiornato: http://codex.wordpress.org/Theme_Modification_API .

hakre hakre
28 ago 2010 12:06:22

Ti ho fatto un fork. http://gist.github.com/554944

hakre hakre
28 ago 2010 16:11:34

@hakre; grazie per il suggerimento sullo swap. Comunque lo conosco già. Devi capire che quando ho scritto la funzione per la prima volta era molto più complicata e l'ho rifattorizzata fino a quello che è ora, quindi inizialmente non pensavo che sarebbe stata così semplice. Inoltre, di solito non incapsulo le cose in una classe qui su StackExchange perché rende più difficile la comprensione quando tutta la struttura della classe è presente (tuttavia, non è ottimale; se uso una classe più persone ne saranno spaventate; se non uso una classe insegno loro una pratica meno buona).

MikeSchinkel MikeSchinkel
28 ago 2010 17:27:49

@hakre - WordPress memorizza l'intestazione in un'opzione chiamata mods_{$theme}; il mio tema si chiamava wp30 quindi è mods_wp30. Contiene un'immagine di sfondo, una miniatura e un colore. Io intercetto l'aggiornamento e aggiungo i miei elementi con nomi diversi per lo sfondo speciale, da qui lo swap, e poi faccio il contrario quando ottengo l'opzione. WordPress non fornisce contesto in set_theme_mod() il che ha reso tutto molto più difficile di quanto avrebbe dovuto essere (ho richiesto un filtro, forse potresti supportarlo? http://core.trac.wordpress.org/ticket/14721)

MikeSchinkel MikeSchinkel
28 ago 2010 17:58:57

@hakre - Ho dovuto utilizzare l'ordine di salvataggio per capire cosa veniva salvato, il che è molto preoccupante a causa della sua fragilità; aggiungono una cosa a /wp-includes/custom-background.php e tutto si rompe! Per quanto riguarda git, non lo conosco e non sono pronto a impararlo. Capisco che il forking sia una buona cosa in git, ma io lo vedo sempre come una cosa negativa. Vuoi collaborare su questo per il repository su WordPress.org? Se è così, deve gestire più sfondi, non solo uno.

MikeSchinkel MikeSchinkel
28 ago 2010 18:01:19

@hakre - Ho appena guardato il tuo fork. È codice "pulito" ma è così astratto che è difficile da seguire. Io stesso programmavo in quel modo e predicavo (letteralmente) quello stile di codifica nei miei corsi di formazione per programmatori aziendali, governativi e militari. Ma da quando lavoro con WordPress ho imparato ad apprezzare che un codice meno astratto può essere a volte un vantaggio perché è molto più facile da capire. Per quel che vale.

MikeSchinkel MikeSchinkel
28 ago 2010 18:25:26

oh non così astratto. Mi piace solo che gli hook si aggancino agli stessi nomi. e impostare le varianti all'inizio della classe. Mi sono imbattuto in qualche casino durante il refactoring della tua base, quindi sono apparse queste tre classi che potrebbero sembrare un po' esagerate. l'ultima è accoppiata alla prima, la routine può essere unita nella classe del plugin ma non l'ho ancora fatto. L'altra classe era qualcosa con cui mi piaceva giocare per superare il tuo add_filter / insieme di funzioni globali -> una singola funzione globale. quindi quello sì che era astratto :D. :P Grazie per il feedback!

hakre hakre
28 ago 2010 19:01:20

@MikeSchinkel: Anch'io sto iniziando con git. Non ho problemi con il forking, penso sia come avere un nuovo repository. Da quello che ho sentito funziona bene con git, quindi facciamo un po' di fork. Questo gist è un'ottima lavagna. Puoi vedere da dove hai preso le cose ecc. È fantastico. --- Non so se abbia senso aggiungere più di un'immagine di sfondo in WP. Forse? Ma penso che il problema sia che non è progettato così nel core, ci deve essere stato aggiunto un numero o una chiave per distinguere tra i vari sfondi. Probabilmente è più semplice ricodificare quel form e offrire pagine di amministrazione.

hakre hakre
28 ago 2010 19:05:03

@MikeSchinkel: Prova prima di comprare :D : http://progit.org/book/

hakre hakre
28 ago 2010 19:25:49

@hakre: L'astratto è relativo. Vuoi vedere astratto? Leggi il mio libro sulla programmazione! http://mikeschinkel.com/books/ Mi piace Gist ma non ho intenzione di lavorare con Git, almeno non a meno che/fino a quando WordPress non lo adotterà (cosa che ritengo improbabile). Sì, avrebbe molto senso avere più sfondi; immagina una rivista online con 5 sezioni; uno sfondo per ognuna più la home page. E quando possibile cerco di lavorare con quello che WordPress offre, chiedendo hook dove mi servono, piuttosto che buttare via e ricominciare da zero. Questa è semplicemente la mia filosofia per estendere WordPress.

MikeSchinkel MikeSchinkel
28 ago 2010 20:07:15

wow! funziona alla grande! Sono senza parole.

Amit Amit
29 ago 2010 23:18:34

@Amit: Senza parole, ma riesci ancora a scrivere eh? :-) Felice di esserti stato utile. Sono esausto su questo, ho passato molto più tempo del previsto quando ho iniziato a rispondere, ma se il tuo cliente ha bisogno che quei background vengano visualizzati creati, offro consulenza a ore... :)

MikeSchinkel MikeSchinkel
30 ago 2010 00:13:52
Mostra i restanti 9 commenti
5

Tecnicamente è possibile (quindi estendere il sorgente di WordPress), ma non di default. Quindi risponderei di no. La funzione integrata dello sfondo del tema è pensata per una singola grafica per impostazione predefinita.

Ma se descrivi un po' di più le "2 aree differenti" di cui parli, potrei suggerire qualcosa di interessante oltre a questo.

Modifica: Evidenzio per MikeSchinkel. I plugin estendono il sorgente di WordPress.

27 ago 2010 21:11:10
Commenti

Beh.. C'è il sito principale (20 sezioni o giù di lì) e poi c'è una sorta di sotto-sito sotto una di queste sezioni che cambia per questo evento speciale e ha bisogno dei suoi colori di stile e immagine di sfondo personalizzati.

Teoricamente potrei dire al cliente di caricare un'immagine nella "pagina master" di ogni sezione e chiamarla "in qualche modo" ma mi piace la funzionalità di sfondo personalizzato e la posizione semantica nel CMS.

Amit Amit
27 ago 2010 21:17:01

stai usando un template per sezione? potrebbe essere qualcosa su cui agganciarsi. Oppure da sovrascrivere con un sottotema per una certa area (che poi scalerebbe a due immagini di sfondo in totale perché avresti due temi, tema genitore e tema figlio).

hakre hakre
27 ago 2010 21:32:28

O voi di poca fede! Dovresti sapere che non si dice che qualcosa non è possibile con WordPress! ;-)

MikeSchinkel MikeSchinkel
28 ago 2010 08:10:49

Non l'ho fatto. Voglio dire, è un ammasso di PHP che devi solo riorganizzare un po' per ottenere ciò che vuoi :)

hakre hakre
28 ago 2010 09:14:49

Vero. Ma non dovresti scoraggiare le persone; dove c'è volontà c'è un modo!

MikeSchinkel MikeSchinkel
30 ago 2010 00:30:16