Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

WordPress ed OOP: creare una classe per gestire gli script

Impariamo a creare una classe per la gestione degli script in WordPress utilizzando il paradigma della programmazione per oggetti.
Impariamo a creare una classe per la gestione degli script in WordPress utilizzando il paradigma della programmazione per oggetti.
Link copiato negli appunti

Nel corso degli articoli precedenti abbiamo analizzato le basi della programmazione OOP in WordPress. In questo articolo ed in quelli successivi vedremo alcune applicazioni pratiche dell'OOP nel noto Blog engine Open Source.

Gli script in WordPress

Gli script JavaScript devono essere prima registrati e solo dopo possono essere inclusi. Per registrare uno script si utilizza la funzione wp_register_script() e per includerlo la funzione wp_enqueue_script(); entrambe queste funzioni lavorano unitamente all'action di WordPress wp_enqueue_scripts. Supponiamo quindidi aver creato uno script chiamato myscript.js e di volerlo includere nel footer, ossia prima della chiusura dell'elemento body:

function my_theme_add_scripts() {
wp_register_script( 'myscript', get_template_directory_uri() . '/js/myscript.js', '1.0', true );
wp_enqueue_script( 'myscript' );
}
add_action( 'wp_enqueue_scripts', 'my_theme_add_scripts' );

Se aggiungiamo questo codice al file 'functions.php' del nostro tema otterremo il risultato voluto. Il problema dell'approccio procedurale, come abbiamo già detto, è la difficoltà nella gestione e nella manutenzione del codice. Infatti:

  • Dovremo stabilire quale libreria JavaScript usare e all'occorrenza cambiarla con semplicità.
  • Se includiamo script remoti, dovremo trovare un modo di evitare che il browser vada in timeout qualora la risorsa non sia disponibile.
  • Dovremo verificare sempre che una data libreria, un plugin o uno script non sia già stato caricato in precedenza.
  • Dovremo automatizzare il processo di registrazione ed inclusione degli script per evitare di scrivere codice ridondante.

Definizione della classe

Definiamo la nostra classe come segue:

if( !class_exists( 'My_Theme_Scripts' ) ) {
  class My_Theme_Scripts {
  // proprietà
  public function __construct() { }
  }
}

Verificare sempre che una classe non sia stata definita in precedenza è sempre una buona pratica da seguire per evitare conflitti ed errori fatali in PHP.

Definire la libreria JavaScript in uso

La prima cosa che definiremo nella nostra classe è la libreria JavaScript che dovremo utilizzare; WordPress dispone già di diverse librerie incluse nel suo core, quindi un ulteriore passaggio da effettuare sarà quello di specificare se vogliamo usare la versione built-in o una versione esterna (presente nel tema, plugin o su un CDN remoto). L' informazione sulla libreria scelta sarà pubblica perché vogliamo che anche altre parti del nostro codice dispongano di questo dato:

// proprietà
public $jsLibrary;
private $_isBuiltInLibrary;
public function __construct( $library, $builtIn ) {
  $this->jsLibrary = $library;
  $this->_isBuiltInLibrary = $builtIn;
  //...
}

Un esempio d'uso potrebbe quindi essere il seguente:

$myThemeScripts = new My_Theme_Scripts( 'jquery', true );
echo $myThemeScripts->jsLibrary; // 'jquery'

Agli altri componenti del nostro codice serve sapere che stiamo usando jQuery, mentre l'informazione circa l'origine della libreria è ininfluente. Un'altra informazione utile è sicuramente la versione scelta della libreria:

// proprietà
public $jsLibrary;
public $jsLibraryVer;
private $_isBuiltInLibrary;
public function __construct( $library, $version, $builtIn ) {
  $this->jsLibrary = $library;
  $this->jsLibraryVer = $version;
  $this->_isBuiltInLibrary = $builtIn;
  //...
}

Un semplice test potrebbe quindi essere formulato in questo modo:

$myThemeScripts = new My_Theme_Scripts( 'jquery', '1.9', true );
echo $myThemeScripts->jsLibrary; // 'jquery'
echo $myThemeScripts->jsLibraryVer; // '1.9'

A questo punto possiamo definire un metodo privato per includere la libreria principale. La nostra libreria è un componente speciale, quindi merita un trattamento a parte:

private function _addLibrary( $url = '' ) {
  if( $this->_isBuiltinLibrary ) {
      wp_enqueue_script( $this->jsLibrary );
  } else {
    wp_deregister_script( $this->jsLibrary );
    wp_register_script( $this->jsLibrary, $url, $this->jsLibraryVer, true );
    wp_enqueue_script( $this->jsLibrary );
  }
}

Il nostro metodo verrà chiamato all'interno del metodo pubblico che andremo a legare al costruttore e all'action wp_enqueue_scripts:

public function __construct( $library, $version, $builtIn ) {
  // proprietà
  add_action( 'wp_enqueue_scripts', array( &$this, 'addScripts' ) );
}

public function addScripts() {
  $this->_addLibrary();
  // altri script
}

Evitare i timeout per gli script remoti

Se includiamo degli script remoti c'è la possibilità che tali script non siano disponibili, in questo caso, e specialmente nel caso delle librerie, l'intero codice JavaScript del nostro sito cessa di funzionare; la soluzione in questi casi è quella di verificare che lo script remoto sia disponibile ed impostare uno script di ripiego locale nel caso in cui il tempo di attesa sia troppo lungo.

private function _isRemoteScriptAlive ( $url ) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url );
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, false );
  curl_setopt( $ch, CURLOPT_TIMEOUT, 3 );
	curl_exec( $ch );
$errorNumber = curl_errno( $ch );
  curl_close( $ch );
  if( $errorNumber > 0 ) {
    return false;
  }
  return true;
}

In pratica abbiamo impostato un timeout di tre secondi per verificare se lo script remoto è accessibile. Possiamo usare questo metodo nel seguente modo:

$remoteScript = 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js';
if( $this->_isRemoteScriptAlive( $remoteScript ) ) {
  // includiamo la copia CDN
} else {
  // includiamo la copia locale
}

Evitare di caricare gli script due volte

WordPress dispone della funzione wp_script_is() che per ignoti motivi viene usata raramente; in realtà questa funzione è utilissima perché ci permette di sapere se uno script è già stato incluso o meno restituendo un valore booleano. Il problema della duplicazione degli script è infatti molto diffuso, ad esempio numerosi plugin registrano due volte la libreria jQuery andando ad aggiungere la loro versione a quella del tema in uso; il risultato potrebbe essere disastroso, in questo modo si ha infatti la sovrascrittura della versione precedentemente registrata ed una miriade di effetti collaterali sul codice. Ma per limitare tali problemi possiamo aggiungere un semplice metodo alla nostra classe:

private function _isScriptAlreadyLoaded( $handle ) {
  if( !wp_script_is( strtolower( $handle ) ) ) {
    return false;
  }
  return true;
}

In questo modo sapremo sempre se c'è effettivamente bisogno di caricare uno script o meno:

if( !$this->_isScriptAlreadyLoaded( 'jquery' ) ) {
  // inserisco jQuery
}

Automatizzare l'inserimento degli script

Sinora abbiamo visto come includere la libreria principale, il problema ora sta nel trovare una soluzione per includere gli altri script senza dovere ogni volta ripetere le funzioni di WordPress per ciascuno script. Sicuramente una soluzione valida è quella di utilizzare un array associativo come proprietà della nostra classe:

// proprietà
public $otherScripts = array();
public function __construct(..., $scripts ) {
  // proprietà
  $this->otherScripts = $scripts;
  // qui usiamo addScripts()
}

Il nostro array dovrà avere il nome dello script, la versione, il percorso o URL, un valore booleano per sapere se va incluso nel footer o meno e l'eventuale dipendenza da altri script:

$myScripts = array(
  0 => array(
    'handle' => 'flexslider'
    'url' => get_template_directory_uri() . '/js/jquery.flexslider.js',
    'ver' => '2.0',
     'dep' => array( 'jquery' );
    'infooter' => true
  ),
  //...
);

Quindi, nel nostro metodo addScripts() scriveremo il seguente codice:

foreach( $this->otherScripts as $script => $value ) {
  $handle = $value['handle'];
  $url = $value['url'];
  $ver = $value['ver'];
  $dep = $value['dep'];
  $inFooter = $value['infooter'];
  if( is_array( $dep ) ) {
    wp_register_script( $handle, $url, $ver, $dep, $inFooter );
  } else {
    wp_register_script( $handle, $url, $ver, $inFooter );
  }
  wp_enqueue_script( $handle );
}

In questo modo è sufficiente aggiungere un'altra voce all'array per ottenere il risultato voluto.

Conclusioni e documentazione ufficiale

In questa breve trattazione è stato affrontato l'argomento relativo alla registrazione, all'inclusione e alla gestione degli scripts in WordPress, con particolare attenzione agli effetti pratici di tali procedure e ai loro possibili effetti collaterali, come per esempio i caricamenti duplicati. Per approfondire l'argomento è possibile consultare i riferimenti contenuti nella documentazione ufficiale:

Ti consigliamo anche