Implementing a simple carousel with cakephp and prototype

No jQuery? No problem.

It’s a great chanche to explore stand-alone scripts or other ajax libraries.

As an example, let me introduce Prototype Carousel.  Light and easy, but probably powerful enough to suit your needs. It is done to manage every type of content(not only images: html, flash..).

Thus, it was a perfect fit for my need – a quick way to add some animation and crunch the vertical size of content -rich homepages, without adding new features and options (namely:  cover images fer every post) – something most of my users don’t like.

Really fast and easy: here is the element I used – it implements some configuration options (duration of auto-scrolling, type of transition and animation, sizes of the carousel) and manual command (previous – next – go to slide #..)

Please note the inline styles – so they are dinamically customizable: the container div has to be N * $width pixel wide (where N = number of slides -in this case a simple count($contents)- and $width = size in pixel of a single slide): this way, we may have the carousel working with an undefined number of slides

  1. <div>
  2. <?php
  3.  
  4. [..]
  5. //some conditions based on variables set for the action - not relevant for our example
  6. ?>
  7. <?php
  8. //using old 1.2 helpers
  9. echo $javascript->link('prototype.js',false);
  10. echo $javascript->link('scriptaculous', false);
  11. echo $javascript->link('carousel-min.js',false);
  12. ?>
  13. <?php
  14.  
  15. //set some value if needed
  16. $slides_number = count($contents);
  17. if(!isset($width)) $width = 600;
  18. if(!isset($height)) $height= 450;
  19. $totalsize = $slides_number * $width;
  20. ?>
  21. <style type="text/css" media="screen">
  22. /*here are the carousel styles - leave them here, ifyou don't want to lose the configuration options */
  23. #carousel-wrapper {
  24. position: relative;
  25. width: <?php echo $width; ?>px;
  26. height: <?php echo $height; ?>px;
  27. overflow: hidden;
  28. border: 2px dotted #E9EBE5;
  29. }
  30. #carousel-content {
  31. position: relative;
  32. _height : 1%; /* trick for display IE 7 bug - it shows owerflown content that should be hidden */
  33. width: <?php echo $totalsize; ?>px;
  34. }
  35. #carousel-content .slide {
  36. position: relative;
  37. float: left;
  38. width: <?php echo $width-20; ?>px;
  39. height: <?php echo $height; ?>px;
  40. padding: 8px;
  41. overflow: hidden;
  42. }
  43. .carousel-selected {
  44. border: 1px dashed #DEDEDE;
  45. background-color: #FFF5B3
  46. }
  47.  
  48. .controls {
  49.  
  50. width: <?php echo $width; ?>px;
  51. padding: 6px;
  52. overflow: hidden;
  53. border: 1px solid #E9EBE5;
  54. }
  55. /* #carousel-content h2 {
  56.  
  57. } */
  58. </style>
  59.  
  60. <!-- needed div ids -->
  61. <div id="carousel-wrapper">
  62. <div id="carousel-content">
  63. <?php
  64.  
  65. // other variables/ default settings for the carousel
  66. if(!isset($transition)) $transition = 'sinoidal'; //sinoidal or spring
  67. if(!isset($effect)) $effect = 'scroll'; //scroll or fade
  68. if(!isset($frequency)) $frequency = "8";
  69. if( $effect == 'scroll') $circular= 'true'; else $circular = 'false'
  70. ?>
  71. <?php
  72. // content loop
  73.  
  74. if($effect == 'scroll') {
  75. $contents[] = $contents[0];
  76. //repeating the first slide after the last one is a trick to provide smooth circular scrolling
  77. //
  78. }
  79.  
  80. foreach ($contents as $content):
  81. ?>
  82. <?php
  83. //other things you don't care about in this example..
  84. [..]
  85.  
  86. // set a list of titles for the go to slide # commands
  87. $titles[$id] = $content['Content']['title'];
  88. ?>
  89. <div id="slide-<?php echo $id;?>">
  90. <h2>
  91. <?php echo $html->link($content['Content']['title'],"/content/view/$id"); ?>
  92. </h2>
  93. <div>
  94. <?php
  95. echo $content['Content']['summary'];
  96. ?>
  97. </div>
  98.  
  99. </div>
  100. <?php endforeach; ?>
  101. </div>
  102. </div>
  103. <!-- Menu for manual control: previous slide, next slide, and index (-> go to slide N) -->
  104. <div>
  105. <a href="javascript:" rel="next" style="float: right;">
  106. <?php echo $icons->next('small'); ?>
  107. </a>
  108.  
  109. <a href="javascript:" rel="prev" style="float: left;">
  110. <?php echo $icons->back('small'); ?>
  111. </a>
  112. <ul style="margin-left:10px; margin-right: 30px;">
  113.  
  114. <?php foreach ($titles as $id => $title): ?>
  115. <li>
  116. <a href="javascript:" rel="slide-<?php echo $id; ?>">
  117. <?php echo $text->truncate($title,76,array('ending' => '[..]', 'exact' => false)); ?>
  118. </a>
  119. </li>
  120. <?php endforeach; ?>
  121. </ul>
  122.  
  123. </div>
  124. <!-- finally, here it is. Our carousel call with settings -->
  125. <script type="text/javascript">
  126. 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; ?>});
  127. </script>
  128. </div>

So, just grab the element, and change the data you want displayed – my $contents array, coming from a Model->find, contanins the title, intro and metadata of main homepage posts – if you need something more elegant, just use fixed size “cover” images – of the size of a slide – and an overlay div (with semi-trasparent background), you css wizard (and share your styles back, please!)

Then, set your settings (probably in the relevant controller action), edit your paths, put craousel-min.js in webroot/js (alongside prototype and scriptacuous) and call it from your view.

It’s reausable –  for example, I use it with different settings in many subsites of a portal (each one with his template) and -conditionally, based on a value of  records of the Home model-  enabled or disabled depending of the user (admin) choiche.

  1. <?php
  2. // view/home/display.ctp
  3. $carousel = 0;
  4.  
  5. if(isset($home['Home']['carousel']))
  6. $carousel = $home['Home']['carousel'];
  7. }
  8.  
  9. //[..]
  10. if( $carousel){ //if carousel was selected for the
  11. //top stories of this home, load the settings and then the element
  12. $settings_path = WWW_ROOT.'/themed/'.$this->params['site'].'/elements/yadda_yadda/carousel_settings.ctp';
  13. include($settings_path);
  14.  
  15. echo $this->element('yadda_yadda/carousel',
  16. array('contents' => $selected['content'],
  17. //other not relevant stuff
  18. // [..]
  19. 'width' => $carousel_width,
  20. 'height' => $carousel_height,
  21. 'effect' => $carousel_effect,
  22. 'transition' => $carousel_transition,
  23. 'frequency' => $frequency
  24.  
  25. )
  26. );
  27.  
  28. } else {
  29. // else load the default element showing the top stories like a blog
  30. echo $this->element('articles',
  31. array('contents' => $selected['content'],
  32. //other stuff
  33.  
  34. )
  35. );
  36. }
  37. }
  38. ?>

carousel_settings.ctp simpy is:

  1. <?php
  2. $carousel_width = 600;
  3. $carousel_height = 450;
  4. $carousel_effect = 'scroll'; //scroll or fade
  5. $carousel_transition= 'sinoidal'; //sinoidal or spring
  6. //$frequency = 5;
  7. ?>

just to have settings for specific layouts or views (you may store the values in the database and set them from the controller, of course)

That’s all, comments / questions / suggestions are welcome