MODx snippet to show a photo album with the integration of HighslideJS for beautiful navigation.
<?php
// example use: [!HighSlide4? &lang=`fr` &CBposition=`bottom center` &outline=`rounded-white` &timePerPix=`5` &fadeDuration=`0.8` &repeat=`false`!]
/******************************************************************************
Highslide for MODx
Version 4.0.10 (November 25 2008)
Adapted for MODx CMF by Just1 ( 28 / 09 / 2010 )
Author: Torstein Hønsi
Support: http://vikjavev.no/highslide/forum
Email: See http://highslide.com/
Licence:
Highslide JS is licensed under a Creative Commons Attribution-NonCommercial 2.5
License (http://creativecommons.org/licenses/by-nc/2.5/).
You are free:
* to copy, distribute, display, and perform the work
* to make derivative works
Under the following conditions:
* Attribution. You must attribute the work in the manner specified by the
author or licensor.
* Noncommercial. You may not use this work for commercial purposes.
* For any reuse or distribution, you must make clear to others the license
terms of this work.
* Any of these conditions can be waived if you get permission from the
copyright holder.
Your fair use and other rights are in no way affected by the above.
******************************************************************************/
// ######################################## //
// Snippet hard config
$siteName = $modx->config['site_name'];
//This is using the gallery .js file
$modx->regClientStartupScript("assets_/snippets/highslide4/highslide-with-gallery.js");
//This is using the standard .css file
$modx->regClientCSS("assets_/snippets/highslide4/highslide.css");
//This will set the folder for the outline images
$graphicsDir = "assets_/snippets/highslide4/graphics/";
// subfolders : tumbnails and fullsize images
$thumbsDir = "thumbs";
$filesDir = "fullsize";
// end of snippet hard config
// ######################################## //
// ######################################## //
// Snippet call options.
// ******************** //
// Folders configuration
// ********** //
// gallery images folder (to select a subfolder)
// base galleries directory
$baseDir = (isset($baseDir))? $baseDir : "assets_/galleries/";
if (substr($baseDir, strlen($baseDir)-1, strlen($baseDir)) != '/') $baseDir .= '/';
// subfolder to explore
if (!empty($_GET["folder"]) and !ereg("\.", $_GET["folder"])) $subfolder = $_GET["folder"].'/';
else if (!empty($subfolder)) $subfolder = $subfolder.'/';
// ******************** //
// ******************** //
// Highslide configuration
// ********** //
// left margin for the fullsize image.
$Lmargin = isset($Lmargin)? $Lmargin : 15;
// right margin for the fullsize image.
$Rmargin = isset($Rmargin)? $Rmargin : 15;
// top margin for the fullsize image.
$Tmargin = isset($Tmargin)? $Tmargin : 15;
// bottom margin for the fullsize image.
$Bmargin = isset($Bmargin)? $Bmargin : 15;
// popup position in the user window
$popupPosition = isset($popupPosition)? $popupPosition : "center";
// position for the control bar on the fullsize image. Options are top/bottom & left/right.
$CBposition = isset($CBposition)? $CBposition : "bottom center";
// outline effect for the fullsize image. Options are beveled, drop-shadow (default), outer-glow & rounded-white.
$outline = isset($outline)? $outline : "rounded-white";
// wrapperClassName ; options are "highslide-wrapper" (default), "controls-in-heading", ??
$wrapperClass = isset($wrapperClass)? $wrapperClass : "highslide-wrapper";
// automatically hide controls on mouse out
$automaticControlsHide = isset($automaticControlsHide)? $automaticControlsHide : "true";
// defines if transitions must be fade in / fade out
$withFade = isset($withFade)? $withFade : "true";
// time per picture
$timePerPix = isset($timePerPix)? $timePerPix : "5";
// transition duration
$fadeDuration = isset($fadeDuration)? $fadeDuration : "0.5";
// reading in loop
$repeat = isset($repeat)? $repeat : "false";
// specific album alignement
$albumStyle = isset($align)? " style=\"text-align: ".$align.";\"" : "";
// ******************** //
// ******************** //
// Language configurations
// ********** //
if ($lang == "fr") {
// "or" word
$lang_or = "ou";
// error message : the folder does not exist
$lang_doesnotExist = "n'existe pas";
// error message : impossible to open
$lang_impossibleToOpen = "est impossible à ouvrir";
// link to go to parent folder
$lang_parentFolder = "dossier parent";
// root folder
$lang_rootFolder = "racine des images";
// back to root
$lang_backToRootFolder = "Retour à la racine des images";
// message in order to view some images
$lang_chooseGallery = "Naviguez dans les dossiers pour afficher le contenu d'un album.";
$lang_chooseGalleryRootFolder = "Vous êtes à la racine des images.<br />Déplacez vous dans un dossier pour en voir le contenu.";
// title in help popup on image mousehover
$lang_imageTitle = "cliquer pour agrandir";
// global copyright to inform pictures are property of their owner(s)
$lang_globalCopyright = "Les images affichées restent la propriété de leur auteur respectif et ne sont aucunement libres de droits.<br />Merci de ne pas réutiliser ces images sans accord préalable.";
// Highslide specific text
$lang_HS_cssDirection = "ltr";
$lang_HS_loadingText = "Chargement...";
$lang_HS_loadingTitle = "Cliquer pour annuler";
$lang_HS_focusTitle = "Cliquer pour afficher";
$lang_HS_fullExpandText = "Taille réelle";
$lang_HS_fullExpandTitle = "Taille réelle (f)";
$lang_HS_nextText = "Suivante";
$lang_HS_previousTitle = "Précédente (flèche gauche)";
$lang_HS_nextTitle = "Suivante (flèche droite)";
$lang_HS_moveText = "Déplacer";
$lang_HS_moveTitle = "Déplacer";
$lang_HS_closeText = "Fermer";
$lang_HS_closeTitle = "Fermer (Echap)";
$lang_HS_resizeTitle = "Redimensionner";
$lang_HS_playText = "Lecture";
$lang_HS_playTitle = "Lire le diaporama (espace)";
$lang_HS_pauseText = "Pause";
$lang_HS_pauseTitle = "Mettre en pause (espace)";
$lang_HS_number = "Image %1 sur %2";
$lang_HS_restoreTitle = "Cliquer pour fermer, cliquer-déplacer pour déplacer. Utiliser les flèches pour aller à la suivante/précédente.";
$lang_HS_creditsText = "Highslide JS";
$lang_HS_creditsTitle = "Site web d\'Highslide JS";
}
else {
// "or" word
$lang_or = "or";
// error message : the folder does not exist
$lang_doesnotExist = "does not exist";
// error message : impossible to open
$lang_impossibleToOpen = "cannot be open";
// link to go to parent folder
$lang_parentFolder = "parent folder";
// root folder
$lang_rootFolder = "gallery root";
// back to root
$lang_backToRootFolder = "Back to images root folder";
// message in order to view some images
$lang_chooseGallery = "Please choose one of available folders to view its content.";
$lang_chooseGalleryRootFolder = "You are in root folder.<br />Move to an other directory to see its content.";
// title in help popup on image mousehover
$lang_imageTitle = "click to enlarge";
// global copyright to inform pictures are property of their owner(s)
$lang_globalCopyright = "These pictures stay property of their respective author and owner, and are not free to copy.";
// Highslide specific text
$lang_HS_cssDirection = "ltr";
$lang_HS_loadingText = "Loading...";
$lang_HS_loadingTitle = "Click to cancel";
$lang_HS_focusTitle = "Click to bring to front";
$lang_HS_fullExpandTitle = "Expand to actual size (f)";
$lang_HS_creditsText = "Powered by Highslide JS";
$lang_HS_creditsTitle = "Go to the Highslide JS homepage";
$lang_HS_nextText = "Next";
$lang_HS_moveText = "Move";
$lang_HS_closeText = "Close";
$lang_HS_closeTitle = "Close (esc)";
$lang_HS_resizeTitle = "Resize";
$lang_HS_playText = "Play";
$lang_HS_playTitle = "Play slideshow (spacebar)";
$lang_HS_pauseText = "Pause";
$lang_HS_pauseTitle = "Pause slideshow (spacebar)";
$lang_HS_previousTitle = "Previous (arrow left)";
$lang_HS_nextTitle = "Next (arrow right)";
$lang_HS_moveTitle = "Move";
$lang_HS_fullExpandText = "Full size";
$lang_HS_number = "Image %1 of %2";
$lang_HS_restoreTitle = "Click to close image, click and drag to move. Use arrow keys for next and previous.";
}
// ******************** //
// end of snippet call options.
// ######################################## //
/******************************************************************************
** You DON'T need to edit below this line ! **
******************************************************************************/
// ######################################## //
// SNIPPET CORE
// ########## //
$HighSlide_output = ""; // initialization of output string
// script settings that override those are defined in the "*.js" file
$HighSlide_output .= "
<script type=\"text/javascript\">
hs.graphicsDir = '$graphicsDir';
hs.align = '$popupPosition';
hs.transitions = ['expand', 'crossfade'];
hs.outlineType = '$outline';
hs.wrapperClassName = '$wrapperClass';
hs.fadeInOut = $withFade;
hs.dimmingOpacity = 0.75;
hs.transitionDuration = $fadeDuration*1000;
hs.marginLeft = $Lmargin;
hs.marginRight = $Rmargin;
hs.marginTop = $Tmargin;
hs.marginBottom = $Bmargin;
// language variables
hs.lang.cssDirection = '$lang_HS_cssDirection';
hs.lang.loadingText = '$lang_HS_loadingText';
hs.lang.loadingTitle = '$lang_HS_loadingTitle';
hs.lang.focusTitle = '$lang_HS_focusTitle';
hs.lang.fullExpandTitle = '$lang_HS_fullExpandTitle';
hs.lang.creditsText = '$lang_HS_creditsText';
hs.lang.creditsTitle = '$lang_HS_creditsTitle';
hs.lang.restoreTitle = '$lang_HS_restoreTitle';
hs.nextText = '$lang_HS_nextText';
hs.moveText = '$lang_HS_moveText';
hs.closeText = '$lang_HS_closeText';
hs.closeTitle = '$lang_HS_closeTitle';
hs.resizeTitle = '$lang_HS_resizeTitle';
hs.playText = '$lang_HS_playText';
hs.playTitle = '$lang_HS_playTitle';
hs.pauseText = '$lang_HS_pauseText';
hs.pauseTitle = '$lang_HS_pauseTitle';
hs.previousTitle = '$lang_HS_previousTitle';
hs.nextTitle = '$lang_HS_nextTitle';
hs.moveTitle = '$lang_HS_moveTitle';
hs.fullExpandText = '$lang_HS_fullExpandText';
hs.number = '$lang_HS_number';
// Add the controlbar
if (hs.addSlideshow) hs.addSlideshow({
//slideshowGroup: 'group1',
interval: $timePerPix*1000,
repeat: $repeat,
useControls: true,
fixedControls: 'fit',
overlayOptions: {
opacity: .75,
position: '$CBposition',
hideOnMouseOut: $automaticControlsHide
}
});
</script>
";
function exifdate_sort($imgA, $imgB) {
$exifA = @exif_read_data($imgA, 0, true);
$exifB = @exif_read_data($imgB, 0, true);
if ( $exifA !== false and $exifB !== false
and !empty($exifA["EXIF"]["DateTimeOriginal"])
and !empty($exifB["EXIF"]["DateTimeOriginal"]) ) {
return strcasecmp( $exifA["EXIF"]["DateTimeOriginal"] , $exifB["EXIF"]["DateTimeOriginal"] );
}
else
return strcasecmp($imgA,$imgB);
}
// logical gallery construction
$getVars = "?";
if (strpos($_SERVER["REQUEST_URI"], '?')) {
$linkVars = $_GET;
if (array_key_exists("q", $linkVars)) unset($linkVars["q"]);
if (array_key_exists("folder", $linkVars)) unset($linkVars["folder"]);
if (array_key_exists("action", $linkVars)) unset($linkVars["action"]);
if (array_key_exists("focus", $linkVars)) unset($linkVars["focus"]);
if (count($linkVars) > 1) {
$firstVar = each($linkVars);
$getVars .= $firstVar["key"]."=".$firstVar["value"];
foreach ($linkVars as $key => $value) {
$getVars .= "&".$key."=".$value;
}
} else if (count($linkVars) == 1) {
$firstVar = each($linkVars);
$getVars .= $firstVar["key"]."=".$firstVar["value"];
}
if ($getVars != "?") $getVars .= "&";
}
if ($handle = @opendir($baseDir.$subfolder)) {
$HighSlide_output .= "\n<div class=\"highslide-album-content\">\n";
$folderContent = array(
"dirs" => array(),
"imgs" => array(),
);
chdir($baseDir.$subfolder);
// ******************** //
// folders tree building
// ********** //
// first loop on the folder content
while (false !== ($content = readdir($handle))) {
if (is_dir($content) and $content != "." and $content != ".." and $content != ".htaccess") {
if ($content == $filesDir) { // gallery found !
if ($handleGallery = @opendir($content)) {
chdir($content);
// second loop on each gallery content
while (false !== ($galleryContent = readdir($handleGallery))) {
if ($galleryContent != "." and $galleryContent != ".." and $galleryContent != ".htaccess") {
if (is_file($galleryContent)) {
$folderContent["imgs"][] = $galleryContent;
}
}
} // end while
chdir(".."); // go to $content's parent
}
else { $HighSlide_output .= "\"".$content."\" : ".$lang_impossibleToOpen."<br />\n"; }
}
else if ($content != $thumbsDir) { // gallery does not exist in this folder
$folderContent["dirs"][$content] = $content; // get the folder name
}
}
else if ($content == ".." and is_dir($content) and !empty($subfolder)) { // link to parent, if we are in a subfolder
$folderContent["dirs"][$content] = $lang_parentFolder;
}
// if !is_dir() => it's a file, so cannot be a gallery
} // end while
// tri de l'arborescence des dossiers
if (array_key_exists("..", $folderContent["dirs"]))
asort($folderContent["dirs"]); // tri classique
else
arsort($folderContent["dirs"]); // trie en ordre inverse (pour les années)
// tri des images
if ( is_dir($filesDir) ) {
chdir($filesDir);
usort($folderContent["imgs"], "exifdate_sort");
chdir("..");
}
// echo "arborescence: "; print_r($folderContent);
// ******************** //
// ******************** //
// navigation links
// ********** //
if (count($folderContent["dirs"]) != 0 or array_key_exists("..", $folderContent["dirs"])) {
$HighSlide_output .= "\n<div class=\"highslide-folder-navigation\">\n<ul>\n";
if (array_key_exists("..", $folderContent["dirs"])) {
$folder = substr( $subfolder, 0, strrpos(substr($subfolder, 0, strlen($subfolder)-1), '/') );
$folder = $getVars."folder=".urlencode($folder)."&action=".urlencode($_GET["action"]);
// <ul class="highslide-parent-folder-link">
$HighSlide_output .= '<li class="highslide-parent-folder-link"><a href="[~'.$modx->documentObject["id"].'~]'.$folder.'">'.$folderContent["dirs"][".."].'</a></li>'."\n";
unset($folderContent["dirs"][".."]);
}
if (count($folderContent["dirs"]) != 0) {
foreach ($folderContent["dirs"] as $dir => $name) {
$HighSlide_output .= '<li><a href="[~'.$modx->documentObject["id"].'~]'.$getVars.'folder='.urlencode($subfolder.$dir).'&action='.urlencode($_GET["action"]).'">'.$name.'</a></li>'."\n";
}
}
$HighSlide_output .= "</ul>\n</div>\n\n";
$HighSlide_output .= (!empty($subfolder))? '<h3 class="highslide-album-title">'.substr($subfolder, 0, strlen($subfolder)-1)."</h3>\n" : "";
}
// ******************** //
// ******************** //
// printing of gallery
// ********** //
if (count($folderContent["imgs"]) != 0) {
$HighSlide_output .= '
<div class="highslide-gallery"' . $albumStyle . '>
';
foreach ($folderContent["imgs"] as $curFile) {
$exif = @exif_read_data($filesDir.'/'.$curFile, 0, true);
if ($exif !== false) {
if ( isset($exif["IFD0"]) ) $ifd = $exif["IFD0"]; // EXIF file description
if ( isset($exif["WINXP"]) ) $ixp = $exif["WINXP"]; // Windows XP file data
$hexZero = chr(0);
//
$imageCaption = "";
$imageCaption .= isset($exif["FILE"]["FileName"])? utf8_decode($exif["FILE"]["FileName"]) : utf8_decode($curFile); // image file name
// Picture date
if ( isset($exif["EXIF"]["DateTimeOriginal"]) ) {
$aDatetime = explode(' ', $exif["EXIF"]["DateTimeOriginal"]);
$aDate = explode(':', $aDatetime[0]);
$aDatetime[0] = $aDate[2].'/'.$aDate[1].'/'.$aDate[0];
$imageCaption .= " - ".implode(' ', $aDatetime);
}
$imageCaption .= isset($ifd["Model"])? " (".$ifd["Model"].")" : ""; // camera model
// Image description
if ( isset($ixp) ) {
// Title
if ( !empty($ixp["Title"]) and $ixp["Title"] != ' ' )
$imageCaption .= "<br />\n<strong>" . $ixp["Title"] . "</strong>";
// Comments
if ( !empty($ixp["Comments"]) and $ixp["Comments"] != ' ' )
$imageCaption .= "<br />\n<span style=\"font-style: italic\">" . $ixp["Comments"] . "</span>";
}
else if ( isset($ifd) ) {
// ImageDescription, or Title
if ( !empty($ifd["ImageDescription"]) and $ifd["ImageDescription"] != ' ' )
$imageCaption .= "<br />\n<strong>" . $ifd["ImageDescription"] . "</strong>";
else if ( !empty($ifd["Title"]) and $ifd["Title"] != ' ' )
$imageCaption .= "<br />\n<strong>" . str_replace($hexZero, '', $ifd["Title"]) . "</strong>";
// Comments
if ( !empty($ifd["Comments"]) and $ifd["Comments"] != ' ' )
$imageCaption .= "<br />\n<span style=\"font-style: italic\">" . str_replace($hexZero, '', $ifd["Comments"]) . "</span>";
}
$imageCaption .= "<div>\n";
// Author
if ( isset($ixp) ) {
// Author
/* affichage de l'auteur désactivé pour éviter l'association entre la photo et le nom de son auteur dans les moteurs de recherche
if ( !empty($ixp["Author"]) and $ixp["Author"] != ' ' )
$imageCaption .= "<span style=\"color: gray;\">Photographe : " . $ixp["Author"] . "</span>";
*/
}
else if ( isset($ifd) ) {
// Artist, or Author
if ( !empty($ifd["Artist"]) and $ifd["Artist"] != ' ' )
$imageCaption .= "<span style=\"color: gray;\">Photographie : " . $ifd["Artist"] . "</span>";
else if ( !empty($ifd["Author"]) and $ifd["Author"] != ' ' )
$imageCaption .= "<span style=\"color: gray;\">Photographie : " . str_replace($hexZero, '', $ifd["Author"]) . "</span>";
}
// Copyright
if ( isset($exif["COMPUTED"]["Copyright"]) )
$imageCaption .= "<span style=\"color: gray;\"> ©".$exif["COMPUTED"]["Copyright"]."</span>";
//
$imageCaption .= "\n</div>\n";
//
$imageCaption = utf8_encode($imageCaption); // to support ISO encoded files on server
}
else { $imageCaption = $curFile; }
$HighSlide_output .= '
<a href="'.$baseDir.$subfolder.$filesDir.'/'.$curFile.'" class="highslide" onclick="return hs.expand(this);">
<img src="'.$baseDir.$subfolder.$thumbsDir.'/'.$curFile.'" alt="Highslide JS - '.$curFile.'"
title="'.$lang_imageTitle.' - '.$curFile.'" id="'.$curFile.'" />
</a>
<div class="highslide-caption">
'.$imageCaption.'
</div>
';
}
$HighSlide_output .= '
</div>
';
}
else {
if (empty($_GET["folder"])) {
$HighSlide_output .= "<h3 class=\"highslide-album-title\">".$lang_rootFolder."</h3>\n";
$HighSlide_output .= '<p style="text-align: center;">';
$HighSlide_output .= '<br />'.$lang_chooseGalleryRootFolder.'</p>';
}
else {
$HighSlide_output .= '<p style="text-align: center;">';
$HighSlide_output .= '<br />'.$lang_chooseGallery.'</p>';
}
}
// ******************** //
$HighSlide_output .= "<div class=\"globalCopyright\">".$lang_globalCopyright."</div>\n";
chdir(".."); // go to $baseDir.$subfolder's parent
$HighSlide_output .= "\n</div>\n<!-- end Highslide album content -->\n";
// ouverture automatique de l'image par clic sur un lien externe
$HighSlide_output .= '
<script type="text/javascript">
<!--
hs.expand( document.getElementById( "' . $_GET["focus"] . '" ).parentNode );
//-->
</script>';
}
else if ($baseDir != '/') { $HighSlide_output .= "\"".$baseDir.$subfolder."\" : ".$lang_doesnotExist." ".$lang_or." ".$lang_impossibleToOpen."<br /><a href=\"[~".$modx->documentObject["id"]."~]".$getVars."action=".$_GET["action"]."\">".$lang_backToRootFolder."</a>\n"; }
// else : l'utilisateur cherche simplement a inclure les elements necessaires au fonctionnement de HighslideJS
// ******************** //
// end of snippet core
// ######################################## //
return $HighSlide_output;
?>