..è un carosello.
Contesto: un’applicazione iniziata con cakephp 1.2 e prototype (sempre quella). Aggiornata a cake 1.3, ma mantenendo i vecchi helper (come AjaxHelper invece del nuovo Js). Quindi, niente jQuery. Una limitazione? un po’, ma anche un’ottima opportunità per provare un po’ di codice lato client o ajax basato su prototype/scriptaculous o indipendente dalle maggiori librerie.
Un ottimo esempio è Prototype Carousel. Semplice, leggero ma abbastanza configurabile. Utilizzabile con qualsiasi tipo di contenuto (non solo immagini).
Pensavo di realizzare qualcosa implementando le “immagini copertina” (come in questo blog) ma alla fine ho optato per una soluzione semplice e veloce ma accettabile: mostrare titolo e intro dei vari contenuti, che ci siano immagini oppure no. (più immediato da implementare, ed una opzione in meno per chi inserisce i contenuti: cosa che conta parecchio..)
Letteralmente semplice e veloce.
Ecco l’element che fa il grosso del lavoro (carousel.ctp), implementando lo slideshow dei contenuti scelti ed i comandi manuali (avanti / indietro / sommario delle slide).
Notare che gli stili sono inclusi inline, essendo così immediatamente configurabili – il contenitore deve essere n volte la larghezza della singola slide, dove n è il numero di contenuti (in questo caso un banale count($contents)); in questo modo il carosello si adegua ad un numero variabile di slide:
- <div class="entry">
- <?php
-
- [..]
- //some conditions based on variables set for the action - not relevant for our example
- ?>
- <?php
- //using old 1.2 helpers
- echo $javascript->link('prototype.js',false);
- echo $javascript->link('scriptaculous', false);
- echo $javascript->link('carousel-min.js',false);
- ?>
- <?php
-
- //set some value if needed
- $totalsize = $slides_number * $width;
- ?>
- <style type="text/css" media="screen">
- /*here are the carousel styles - leave them here, ifyou don't want to lose the configuration options */
- #carousel-wrapper {
- position: relative;
- width: <?php echo $width; ?>px;
- height: <?php echo $height; ?>px;
- overflow: hidden;
- border: 2px dotted #E9EBE5;
- }
- #carousel-content {
- position: relative;
- _height : 1%; /* trick for display IE 7 bug - it shows owerflown content that should be hidden */
- width: <?php echo $totalsize; ?>px;
- }
- #carousel-content .slide {
- position: relative;
- float: left;
- width: <?php echo $width-20; ?>px;
- height: <?php echo $height; ?>px;
- padding: 8px;
- overflow: hidden;
- }
- .carousel-selected {
- border: 1px dashed #DEDEDE;
- background-color: #FFF5B3
- }
-
- .controls {
-
- width: <?php echo $width; ?>px;
- padding: 6px;
- overflow: hidden;
- border: 1px solid #E9EBE5;
- }
- /* #carousel-content h2 {
-
- } */
- </style>
-
- <!-- needed div ids -->
- <div id="carousel-wrapper">
- <div id="carousel-content">
- <?php
-
- // other variables/ default settings for the carousel
- if( $effect == 'scroll') $circular= 'true'; else $circular = 'false'
- ?>
- <?php
- // content loop
-
- if($effect == 'scroll') {
- $contents[] = $contents[0];
- //repeating the first slide after the last one is a trick to provide smooth circular scrolling
- //
- }
-
- foreach ($contents as $content):
- ?>
- <?php
- //other things you don't care about in this example..
- [..]
-
- // set a list of titles for the go to slide # commands
- $titles[$id] = $content[$Type]['title'];
- ?>
- <div class="slide" id="slide-<?php echo $id;?>">
- <h2>
- <?php echo $html->link($content['Content']['title'],"/content/view/$id"); ?>
- </h2>
- <div>
- <?php
- echo $content['Content']['summary'];
- ?>
- </div>
-
- </div>
- <?php endforeach; ?>
- </div>
- </div>
- <!-- Menu for manual control: previous slide, next slide, and index (-> go to slide N) -->
- <div class="controls">
- <a href="javascript:" class="carousel-control ico-next" rel="next" style="float: right;">
- <?php echo $icons->next('small'); ?>
- </a>
-
- <a href="javascript:" class="carousel-control ico-prev" rel="prev" style="float: left;">
- <?php echo $icons->back('small'); ?>
- </a>
- <ul style="margin-left:10px; margin-right: 30px;">
- <?php
- // if($effect == 'scroll') {
- // array_pop($titles);
- // }
- ?>
- <?php foreach ($titles as $id => $title): ?>
- <li>
- <a href="javascript:" rel="slide-<?php echo $id; ?>" class="carousel-jumper">
- </a>
- </li>
- <?php endforeach; ?>
- </ul>
-
- </div>
- <!-- finally, here it is. Our carousel call with settings -->
- <script type="text/javascript">
- new Carousel('carousel-wrapper', $$('#carousel-content .slide'), $$('a.carousel-control', 'a.carousel-jumper'),{duration: 0.8, circular: <?php echo $circular; ?>, effect: '<?php echo $effect; ?>', transition:'<?php echo $transition; ?>', wheel: true, auto: true, frequency: <?php echo $frequency; ?>});
- </script>
- </div>
Una volta a posto (nella directory webroot/js) il file carousel-min.js e le librerie prototype e scriptaculous, è sufficiente passare all’elemento le variabili necessarie: eventuali valori per configurarlo (dimensioni, durata delle singole slide, tipo di animazione nelle transizioni..) e l’array dei contenuti (il classico risultato di un Model->find di cake).
E’ facilmente configurabile a seconda del contesto e quindi riusabile. Ad esempio, nel mio caso, ogni sito di un portale ha le sue configurazioni in un semplice file incluso, mentre l’oggetto Home (per gestire le homepage dei singoli siti) ha una proprietà “caousel” (boolean) che attiva / disattiva il carosello a scelta del redattore.
- <?php
- // view/home/display.ctp
- $carousel = 0;
-
- $carousel = $home['Home']['carousel'];
- }
-
- //[..]
- if( $carousel){ //if carousel was selected for the
- //top stories of this home, load the settings and then the element
- $settings_path = WWW_ROOT.'/themed/'.$this->params['site'].'/elements/blocks/home/carousel_settings.ctp';
- include($settings_path);
-
- echo $this->element('blocks/home/carousel',
- //other not relevant stuff
- // [..]
- 'width' => $carousel_width,
- 'height' => $carousel_height,
- 'effect' => $carousel_effect,
- 'transition' => $carousel_transition,
- 'frequency' => $frequency
-
- )
- );
-
- } else {
- // else load the default element showing the top stories like a blog
- echo $this->element('articles',
- //other stuff
-
- )
- );
- }
- }
- ?>
Il file carousel_settings è semplicemente:
- <?php
- $carousel_width = 600;
- $carousel_height = 450;
- $carousel_effect = 'scroll'; //scroll or fade
- $carousel_transition= 'sinoidal'; //sinoidal or spring
- //$frequency = 5;
- ?>
..per avere impostazioni legate al layout o alla view. Ovviamente a seconda dell’uso può essere meglio impostare i valori nel controller.
Usarlo per un effetto più elegante?
Semplice: forzare i contenuti ad immagini di dimensioni prefissate (quelle delle slide), e giocare un po’ coi css mettendo il div con il titolo in sovrimpressione con un po’ di trasparenza.