Blättkatalog mit jQuery WowBook in pimcore integriert.

Lukas [Tricks und Tools, Pimcore, Technologien]

Um PDFs in Form von Blätterkatalogen anschaulicher darzustellen gibt es schon seit langem diverse Flash basierte Tools. Die haben einen gravierenden Nachteil: Sie laufen nicht auf einem iPad. Zudem ist Flash nicht auf jedem System von Haus aus installiert. Abhilfe schaft ein jQuery Plugin namens WowBook. Nachfolgend ein paar Codezeilen, mit denen man automatisch aus PDFs WowBooks erzeugt.

Link: WowBook auf Github

pimcore Controller

Wir bauen das WowBook so auf, dass es in einem neuen Fenster aufgeht, damit das PDF möglichst viel Platz in Anspruch nehmen kann und optimal gelesen werden kann. Die Idee ist deshalb anstatt das Asset direkt eine Action nach folgendem Schema zu verlinken:

?controller=brochure&action=wowbook&id=assetid

public function wowbookAction() {
   $this->enableLayout();
   $pdf = Asset::getById($this->getParam("id"));
   $this->view->pdf = $pdf;
}

PDF in Bilder umwandeln

Zuerst müssen wir das PDF in Bilder umwandeln, die wir dann als Seiten im WowBook einsetzen können. Die Bilder speichern wir im tmp Verzeichnis von pimcore, damit wir diese nicht jedes mal neu generieren müssen, sie aber durch ein Löschen des Cache bereinigt werden, so dass auch der Seitenbetreiber eine Neugenerierung der Blätterkataloge anstossen kann.

Fürs Umwandeln muss imagemagick auf dem Server über die Kommandozeile verfügbar sein.

$pdf = $this->pdf;

if ($pdf instanceof Asset_Document) {
  $tmpfolder = PIMCORE_TEMPORARY_DIRECTORY."/flipbooks";
  if (!is_dir($tmpfolder)) mkdir($tmpfolder);

  $imagefolder = $tmpfolder."/".$pdf->getId();
  if (!is_dir($imagefolder)) mkdir($imagefolder);

  $globdir = glob($imagefolder."/*.jpg");
  if (count($globdir) == 0) {
    // generate files for pdf
    $source = $pdf->getFileSystemPath();
    $cmd = 'convert -density 288 -colorspace RGB '.$source.' -alpha Off -background white'.
           '-resize 50% '.$imagefolder.'/`basename '.$pdf->getFilename().' .pdf`.jpg';
    $cmdreturn = Pimcore_Tool_Console::exec($cmd);
  }
}

HTML Code generieren

Wenn man mit Bildern arbeitet ist der WowBook Code sehr simpel. In der Dokumentation finden sich zahlreiche Funktionen, die man ebenfalls verwenden könnte. Die Automatisierung macht den Einbau derselben natürlich nicht einfach. Denkbar wäre, dass man die einzelnen Seiten auch aus Documents zusammensetzen könnte. Hier geben wir uns mit der einfachen ein Bild pro Seite Variante zufrieden.

 

Zuerst holen wir uns alle Bilder aus dem Verzeichnis in die wir diese zuvor generieren lassen haben. Imagemagick nummeriert diese automatisch mit einer aufsteigenden Nummer. Im Anschluss gehen wir alle Files durch und ändern den Filenamen auf die URL, unter welcher die Datei im Web aufrufbar ist. Zuvor folgt noch die WowBook Navigation, welche uns neben Wischbewegungen auf Tablets und Mausklicks auf den Rand der Seiten eine zusätzliche Navigation durch den Katalog ermöglichen.

$globdir = glob($imagefolder."/*.jpg");

function replaceFilename($file) {
    return str_replace(PIMCORE_DOCUMENT_ROOT, "", $file);
}

if (count($globdir) > 0) {
    natsort($globdir);
    $i = 0;
    $files = array();
    foreach ($globdir as $key => $value) {
        $files[$i] = $value;
        $i++;
    }
    ?>
    <div id="wowbookcontainer">
        <nav>
            <ul>
                <li><a id='first' href="#" title='goto first page'>First page</a></li>
                <li><a id='back' href="#" title='go back one page'>Back</a></li>
                <li><a id='next' href="#" title='go foward one page'>Next</a></li>
                <li><a id='last' href="#" title='goto last page'>last page</a></li>
                <li><a id='slideshow' href="#" title='start slideshow'>Slide Show</a></li>
                <li><a id='fullscreen' href="#" title='fullscreen on/off'>Fullscreen</a></li>
            </ul>
        </nav>
        <div id="main">
            <div id='brochure'>
                <?
                for ($i = 0; $i < count($files); $i++) {
                    $class = "softpage";
                    ?>
                    <div id="page-<?= $i ?>" class='<?= $class ?>' data-image="<?= replaceFilename($files[$i]); ?>">
                    </div>
                <?
                }
                ?>
            </div>

        </div>
    </div>
<?
}

Javascript

Nun kommt etwas Javascript. Neben dem Aufruf wie man Ihn auch in der WowBook Dokumentation finden kann, gibt es noch ein paar Erweiterungen damit der Blätterkatalog auch anständig aussieht und möglichst gross ist. Als erstes ermitteln wird Anhand der Bildgrösse und der grösse des Viewports die maximal verfügbare Fläche:

<?php
$size = getimagesize($files[0]);
$imageheight = intval($size[1]);
$imagewidth = intval($size[0] * 2);
?>
var height_spacing = 100;
var viewport_height = jQuery(window).height();
var viewport_width = jQuery(window).width();
var original_height = parseInt(<?= $imageheight ?>);
var original_width = parseInt(<?= $imagewidth ?>);

var height = original_height;
var width = original_width;

if (viewport_height - height_spacing < original_height) {
    height = viewport_height - height_spacing;
    width = (original_width / original_height) * height;
}

if (viewport_width < width) {
    width = viewport_width - height_spacing;
    height = (original_height / original_width) * width;
}

jQuery("#wowbookcontainer").css("max-width", width + "px");

Nun initialisieren wir den Blätterkatalog mit dem WowBook Plugin und den zuvor ermittelten Abmasse sowie einiger anderer Optionen.

 var wowbook = jQuery('#brochure').wowBook({
    height: height,
    width: width,
    centeredWhenClosed: true,
    hardcovers: false,
    turnPageDuration: 1000,
    flipSound: false,
    controls: {
        pdf: '#pdf',
        next: '#next',
        back: '#back',
        first: '#first',
        last: '#last',
        slideShow: '#slideshow',
        fullscreen: '#fullscreen'
    },
    touchEnabled: true,
    pageNumbers: false,
    responsive: true,
    scaleToFit: "#wowbookcontainer",
    thumbnailsPosition: 'bottom',
    onFullscreenError: function() {
        var msg = "Fullscreen failed.";
        if (self != top) msg = "The frame is blocking full screen mode. Click on 'remove frame' button above and try to go full screen again."
        alert(msg);
    }
}).fadeIn(1000);

Zu guter letzt soll der Blätterkatalog sich auch responsive verhalten. Wenn ein iPad User den Katalog hochkant öffnet und das Tablet dreht, soll er den Katalog nun auch grösser geniessen können. Und ja das ist wieder der Code von zuvor. Den kann man auch einfach noch zusammenfassen.

var resizeFunction = function() {
    var viewport_height = jQuery(window).height();
    var viewport_width = jQuery(window).width();
    var original_height = parseInt(<?= $imageheight ?>);
    var original_width = parseInt(<?= $imagewidth ?>);

    var height = original_height;
    var width = original_width;

    if (viewport_height - height_spacing < original_height) {
        height = viewport_height - height_spacing;
        width = (original_width / original_height) * height;
    }

    if (viewport_width < width) {
        width = viewport_width - height_spacing;
        height = (original_height / original_width) * width;
    }

    jQuery("#wowbookcontainer").css("max-width", width + "px");
    jQuery.wowBook("#brochure").resize(width, height);
    jQuery("#brochure .wowbook-zoomcontent").css("transform", "scale(1)");
}

jQuery(window).resize(resizeFunction);

Fertig: Präsentation als Blätterkatalog

Nun kann man jedes beliebige PDF anstatt direkt mit einem gezielten Link als Blätterkatalog darstellen lassen. Und so sieht das ganze dann in der Praxis aus:

Präsentation ansehen

 

zurück