Galleria fotografica senza refresh con cambio url html5 per WordPress

I vostri visitatori escono dalle vostre gallerie fotografiche stanchi dei continui reload di pagina? Oppure volete solo migliorarne la fruibilità? Ecco come creare una fantastica galleria fotografica senza refresh mantenendo il cambio url dinamico per il SEO usando il pushState di HTML5!

Idea e preparazione files

WordPress permette di creare gallery fotografiche con la possibilità di inserire la paginazione per ogni immagine usando il page-break. Queste gallery sono perfette per fare maggiori pagine viste, tuttavia risultano molto scomode per l’utente finale, che ad ogni click, deve refreshare l’intera pagina per aggiornare – di fatto – solo la foto desiderata.

NOTA: se il pulsante page break non compare nel vostro editor inserite il seguente codice nel vostro functions.php

// Aggiungi Page Break
add_filter( 'mce_buttons', 'my_add_page_break_button', 1, 2 );
function my_add_page_break_button( $buttons, $id ){
    if ( 'content' != $id )
        return $buttons;
    array_splice( $buttons, 13, 0, 'wp_page' );
    return $buttons;
}

risultato finale backend cms della gallery:

cms-gallery-ajax

risultato finale della gallery:

gallery ajax

Al click sulle frecce l’immagine verrà cambiata in modo selettivo senza refreshare tutta la pagina e l’url cambierà con l’indirizzo cliccato (perfetto per il seo), il tutto in modo semplice, veloce e perfettamente integrato con WordPress!

Sviluppiamo il nostro engine gallery ajax per WordPress

Per la nostra gallery non andremo a utilizzare nessun plugin, bensì faremo il tutto “fatto in casa”.

Per prima cosa identificate e aprite il file che viene richiamato nel single per renderizzare il post (nel nostro caso ci interessa il formato gallery). Nel caso in esame useremo il tema default di wordpress, per cui il file è post/content-gallery.php.

A questo punto andiamo a eliminare:

a) la parte di rendering standard del post type che potete identificare con  the_content()

b) eliminiamo anche la funzione – ove presente-  wp_link_pages() …andremo a farne una custom noi secondo le nostre specifiche esigenze.

A questo punto iniziamo a strutturare l’html come segue:

  <div id="gallery-holder">

      <div id="main-content">
      <?php the_content(); //stampa immagine ?>
      </div>

      <div id="gallery-nav-holder">
          <?php
          wp_link_pages(array(
             'before' => '<div class="page-nav page-nav-post gallery-nav-custom">',
             'after' => '</div>',
             'link_before' => '',
             'link_after' => '',
             'next_or_number'   => 'next',
             'pagelink'         => '',
             'echo' => true,
             'nextpagelink'     => '<div class="arrow-fotogallery-next"> >> </div>',
             'previouspagelink' => '<div class="arrow-fotogallery-previous"> << </div>'
         ));
         ?>
       </div>

  </div>
  <!--gallery-holder  -->

Come potete vedere andiamo a mettere il contenuto del post in un contenitore con id “main-content” e andiamo a creare grazie a wp_link_pages la paginazione del post andando a passare all’interno della funzione una struttura html che ci servirà per il nostro engine.

Il nostro obbiettivo è infatti quello di essere poco invasivi e usare quello che ci da wordpress per effettuare il cambio url e la sostituzione selettiva della foto al click.

A questo punto se aggiornate il vostro post dovreste vedere la prima foto della gallery e le frecce next e prev cliccabili. Ad ogni click la pagina viene cambiate normalmente (in quanto dobbiamo ancora entrare nel vivo del nostro engine).

Sviluppo javascript della gallery

Per prima cosa impostiamo le variabili necessarie:

        var iteractor_count = 0;
        $(document).on( 'click', ".page-nav-post a", function( event ) {
      	  //Previene click dell'href 
          event.preventDefault();

          iteractor_count++;

          //Variabili
          var gallery_home = "<?php echo get_permalink(); ?>"; //home dell'articolo
          var url = window.location.href; //url attuale
          var link = $(this).attr('href'); //url cliccato
          var link_page = $(this).find('div').html(); //extra: potete identificare l'html del pulsante cliccato

Per “intercettare” il normale funzionamento del link della nostra paginazione andiamo a usare il seguente codice:

event.preventDefault();

Dopodichè sono state impostate le variabili necessarie al funzionamento, con l’aggiunta di iteractor_count che vedremo dopo.

Una volta cliccato il link andiamo ad aggiornare la foto e la navigazione usando load di jQuery e facendo puntare al giusto div:

          //aggiorno foto
          $("#main-content").empty();
          $("#main-content").load(""+link+" #main-content");

          //aggiorno nav
          $(".page-nav-post").empty();
          $(".page-nav-post").load(""+link+" .page-nav-post");

NOTA: è possibile anche usare ajax al posto di load, magari predisponendo un template di pagina al fine di renderizzare solo quel determinato elemento da cambiare – utile per una maggiore performance.

Se non conosci jQuery LOAD –> Approfondisci qui

A questo punto, come potrete vedere, al click sulle frecce della gallery la vostra immagine cambierà correttamente, ma il vostro url resterà quello della gallery originale. In realtà noi vogliamo farlo cambiare, ad esempio:

  • tuosito.it/gallery
  • tuosito.it/gallery/2/ –> foto 2 della gallery
  • etc

Come fare?

Utilizzo di pushState HTML5 per il cambio url

Hmtl5 introduce la funzionalità pushState che ci permette di cambiare l’url dell’address bar del browser e di tenere anche la cronologia della pagina precedente nel caso l’utente usasse il “torna indietro” del browser. Tra i suoi parametri annoveriamo anche la possibilità di cambiare anche il page title visualizzato dal browser.

Dal punto di vista analitico l’utilizzo di pushState è esattamente come un reload / cambio pagina tradizionale (e anche google analytics/ e similari lo riconoscono come tale).

L’uso è piuttosto semplice:

 history.pushState("url attuale", "titolo nuova pagina", "nuovo url");

Vediamo come usarlo a nostro favore per la gallery.

Per prima cosa dobbiamo identificare quando siamo su una pagina della gallery qualsiasi (es. tuosito.it/gallery/1,2,3,4,5etc) rispetto alla prima (es. tuosito.it/gallery/)

//Recupero segmento url finale
var result = link.match(/([^\/]*)\/*$/)[1];
if (isNaN(result))
{
  //Non numerico - Caso prima foto
  result = "";
}

NOTA: La funzionalità isNaN fa il check se la variabile passata al suo interno è numerica oppure no.

A questo punto, in modo analogo, dobbiamo creare il  nostro url finale aggiornato da poter usare nel pushState

 var final_segment = url.match(/([^\/]*)\/*$/)[1]; // identifico ultimo segmento url

Faccio il check di quanto trovato:

          if (isNaN(final_segment))
            {

              //Non numerico - Caso prima foto
              if(iteractor_count == 1) {
                 var url_no_last_slash = url;
                 var url_finale = url_no_last_slash+result+"/";
               }

            }else{

                  if(gallery_home == link) {

                    iteractor_count = 0;
                    var base_article_url = url.replace(final_segment,"");
                    var url_no_last_slash = base_article_url.replace(/\/$/, "");
                    var url_finale = url_no_last_slash+result+"";

                  } else {

                    var base_article_url = url.replace(final_segment,"");
                    var url_no_last_slash = base_article_url.replace(/\/$/, "");
                    var url_finale = url_no_last_slash+result+"/";

                  }//if gallery_home == link

             }//else

Come avete visto iteractor_count viene incrementato a ogni click e  serve per settare correttamente l’url nel caso ci trovassimo nella pagina home. La prima foto infatti può essere richiamata in due modi:

  • accesso all’articolo normale
  • un utente scorre indietro la fotogallery fino a ritornare alla prima immagine.

Per identificare e settare correttamente l’url in questi due casi, ho usato la variabile iteractor_count unito al check del link cliccato con la gallery_home (che di fatto è il permalink dell’articolo recuperato via php da wordpress).

Per finire, abbiamo tutto ciò che ci serve per il pushState:

//Push State
history.pushState(url, document.title+" | Pagina "+result, url_finale);

Step facoltativo: overlay onHover

overlay-gallery-ajax-wordpress

Questo codice è da inserire solo nel caso vogliate un effetto come quello che vedete qui sopra, ovvero: focus completo sull’immagine “oscurando” tutto il resto del sito.

HTML da aggiungere

 <div class="gallery-overlay"></div>

CSS da aggiungere

.gallery-overlay{ 
background: rgba(0,0,0,0.7); 
width: 100%; height: 100%; 
position: fixed; top:0; left:0; 
z-index: 2; 
display: none; 
}
#gallery-holder{z-index: 3; position: relative;}
#gallery-nav-holder{
z-index: 3;
position: absolute;
top: 0%;
width: 100%;
margin: 20px 0px;
}

Javascript da aggiungere

     //Overlay onHover Engine
        if(attiva_overlay){
          $( "#gallery-holder").hover(
            function() {
              $(".gallery-overlay").stop().fadeIn();
            }, function() {
                $(".gallery-overlay").stop().fadeOut();
            }
          );
        }//attiva overlay

Codice finale completo

In questa versione di codice finale ho messo le variabili utilizzate dentro un wrapper in modo tale da poterle cambiare una sola volta in tutto lo script (utile nel caso doveste cambiare tema per cambiare i puntamenti html). Ho altresì messo il log e l’overlay configurabile come opzione da settare su true o false nel caso vogliate o meno la relativa opzione. Il tutto è testato e  funzionate sul tema default di wordpress twentyseventeen ma è facilmente adattabile e configurabile in qualsiasi tema.

Consiglio di attivare il debug solo al fine di capire meglio il funzionamento generale dello script o per la risoluzione di eventuali bug.

File post/content-gallery.php – tema twentyseventeen

	<!--Gallery Custom -->
	<style>
	.gallery-overlay{ background: rgba(0,0,0,0.7); width: 100%; height: 100%; position: fixed; top:0; left:0; z-index: 2; display: none; }
       #gallery-holder{z-index: 3;  position: relative;  overflow:hidden;  }
			 #gallery-nav-holder{
				  top:0%;
				  z-index: 3;
          position: absolute;
          width: 100%;
          margin: 0px;
        }
			.arrow-fotogallery-next{ background: red; float:right; padding: 25px; }
			.arrow-fotogallery-previous{ background: red; float: left;  padding: 25px; }
			</style>

			<div class="gallery-overlay"></div>
		  <div id="gallery-holder">
				  <div id="main-content">
				  	<?php the_content();?>
				  </div>
					<div id="gallery-nav-holder">
				          <?php
				          wp_link_pages(array(
				             'before' => '<div class="page-nav-post gallery-nav-custom">',
				             'after' => '</div>',
				             'link_before' => '',
				             'link_after' => '',
				             'next_or_number'   => 'next',
				             'pagelink'         => '',
				             'echo' => true,
				             'nextpagelink'     => '<div class="arrow-fotogallery-next"> >> </div>',
				             'previouspagelink' => '<div class="arrow-fotogallery-previous"> << </div>'
				         ));
				         ?>
				  </div>
			 </div>
			 <!--gallery-holder  -->


  		<script>
      //Engine Gallery senza refresh per WordPress - by Riccardo Mel
      //Vietata la riproduzione
      //riccardomel.com - targetweb.it
      //[email protected]
      //Ver. 1.0
      jQuery(document).ready(function($) {

        //Opzioni
        var attiva_overlay = false;
        var gallery_debug = false;

	//Variabili
        var gallery_html_trigger = ".page-nav-post a";
        var gallery_html_constr_holder = "#gallery-holder";
        var gallery_html_constr_overlay = ".gallery-overlay";
        var gallery_html_constr_content = "#main-content";
        var gallery_html_constr_nav = ".page-nav-post";


        //Overlay onHover Engine
        if(attiva_overlay){
            $( gallery_html_constr_holder).hover(
              function() {
                $(gallery_html_constr_overlay).stop().fadeIn();
              }, function() {
                  $(gallery_html_constr_overlay).stop().fadeOut();
              }
            );
         }//attiva overlay

        var iteractor_count = 0;
        $(document).on( 'click', gallery_html_trigger, function( event ) {
      		event.preventDefault();
          iteractor_count++;
          //Variabili

          var gallery_home = "<?php echo get_permalink(); ?>";
          var url = window.location.href;
          var link = $(this).attr('href');
          var link_page = $(this).find('div').html();
          if(gallery_debug){
        		console.log( 'Gallery Debug: Url ' +url);
            console.log( 'Gallery Debug: Link ' +link);
            console.log( 'Gallery Debug: gallery_home ' +gallery_home);
            console.log( 'Gallery Debug: Clicked item' +link_page);
          }//gallery debug

          //aggiorno foto
          $(gallery_html_constr_content).empty();
          $(gallery_html_constr_content).load(""+link+" "+gallery_html_constr_content+"");

          //aggiorno nav
          $(gallery_html_constr_nav).empty();
          $(gallery_html_constr_nav).load(""+link+" "+gallery_html_constr_nav+"");

          //Recupero segmento url finale
          var result = link.match(/([^\/]*)\/*$/)[1];
          if (isNaN(result))
           {
             //Non numerico - Caso prima foto
             if(gallery_debug){
           		   console.log("Gallery Debug: non numerico - Caso prima foto - imposto result senza elementi");
             }//gallery debug
             result = "";
           }

           var final_segment = url.match(/([^\/]*)\/*$/)[1];
           if(gallery_debug){  console.log("Gallery Debug: iteractor"+iteractor_count);  console.log("Gallery Debug: final segment "+final_segment); }//gallery debug

           if (isNaN(final_segment))
            {

              //Non numerico - Caso prima foto
              if(iteractor_count == 1) {
                 if(gallery_debug){ console.log("Gallery Debug: case 1"); }
                 var url_no_last_slash = url;
                 var url_finale = url_no_last_slash+result+"/";
               }

            }else{

                  if(gallery_home == link) {

                    iteractor_count = 0;
                    if(gallery_debug){ console.log("Gallery Debug: case 2"); }
                    var base_article_url = url.replace(final_segment,"");
                    var url_no_last_slash = base_article_url.replace(/\/$/, "");
                    var url_finale = url_no_last_slash+result+"";

                  } else {

                    if(gallery_debug){ console.log("Gallery Debug: case3"); }
                    var base_article_url = url.replace(final_segment,"");
                    var url_no_last_slash = base_article_url.replace(/\/$/, "");
                    var url_finale = url_no_last_slash+result+"/";

                  }//if gallery_home == link

             }//else

           if(gallery_debug){
             console.log("Gallery Debug: url finale "+url_finale);
             console.log("Gallery Debug: result "+result);
            }  //Debug

          //Push State
           history.pushState(url, document.title+" | Pagina "+result, url_finale);

      });//click

    });//DOM
</script>
<!--Gallery Custom -->

Conclusioni & link utili

Spero che l’articolo vi sia utile per crearvi la vostra gallery di immagini wordpress su misura per le vostre reali esigenze, senza plugin o widget di terze parti.  Vuoi imparare meglio html5, javascript e jQuery ma non sai da dove iniziare? Ecco un libro che racchiude una buona infarinatura generale su tutti questi linguaggi:

libro-html5-css3-jquery

HTML5 – CSS3 – Javascript 
Descrizione libro: La Rete sta cambiando. I clienti si aspettano siti web dinamici e d’impatto, gli utenti pretendono interfacce intuitive che si adattino alle specificità di ogni dispositivo di navigazione. Progettare applicazioni web moderne significa trovarsi a proprio agio con tecnologie diverse e sapere come gestire la complessità. Questo libro disegna un percorso di apprendimento che procede in maniera graduale dalla creazione delle fondamenta del sito in HTML5 all’applicazione degli stili con CSS3; dalla dinamicità fornita da JavaScript alla programmazione lato server con PHP; dalla programmazione lato client alle possibilità offerte dall’utilizzo delle API di famose applicazioni web come Twitter e Google; da jQuery ad Ajax. Tutto accompagnato da esempi pratici, soluzioni e consigli per migliorare subito i propri progetti.


Questo articolo ti è stato utile? Condividilo sui tuoi social network preferiti!

Se hai bisogno di aiuto con WordPress o con questa gallery contattami.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Server
Up Next:

Hosting: partiamo con il piede giusto

Hosting: partiamo con il piede giusto