-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
4,923 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
<?php | ||
/** | ||
* PicoFotofolder. A Mansory/Lightbox plugin for galleries | ||
* Edited December 2019 by Maloja | ||
* | ||
* @author Maloja | ||
* @license http://opensource.org/licenses/MIT The MIT License | ||
* @link http://github.com/maloja/pico-fotofolder | ||
* | ||
*/ | ||
class PicoFotofolder extends AbstractPicoPlugin { | ||
|
||
const API_VERSION = 2; | ||
protected $enabled = true; | ||
protected $dependsOn = array(); | ||
|
||
/** | ||
* This private variables | ||
*/ | ||
private $p_keyword = 'fotofolder'; | ||
private $p_count = 0; | ||
private $image_src = array(); | ||
|
||
/** | ||
* | ||
* Triggered after Pico has prepared the raw file contents for parsing | ||
*/ | ||
public function onContentParsed(&$content) { | ||
$content = preg_replace_callback( '/<p>\s*\(%\s+' . $this->p_keyword .'\s*\(\s*(.*?)\s*\)\s+%\)\s*<\/p>/', function($match) { | ||
|
||
if ($match[1]) { | ||
list ($this->image_src['path'], | ||
$this->image_src['sort'], | ||
$this->image_src['order']) = explode(',', str_replace('"', '', $match[1])); | ||
|
||
$this->image_src['path'] = trim($this->image_src['path']); | ||
$this->image_src['sort'] = trim($this->image_src['sort']); | ||
$this->image_src['order'] = trim($this->image_src['order']); | ||
if ($this->image_src['sort'] == "") $this->image_src['sort'] = 'name'; | ||
if ($this->image_src['order'] == "") $this->image_src['order'] = 'dsc'; | ||
|
||
$img_metas = $this->readMetaArray(); | ||
|
||
if (count($img_metas) > 0) { | ||
$out = $this->createOutput($img_metas); | ||
$this->p_count++; | ||
} | ||
} | ||
return $out; | ||
}, $content); | ||
} | ||
|
||
|
||
/** | ||
* Triggered after Pico has rendered the page | ||
*/ | ||
public function onPageRendered(&$output ) { | ||
// add required elements in head tag | ||
if ($this->p_count > 0) { | ||
$jsh = ' <!-- Fotofolder Elements -->' . "\n"; | ||
$jsh .= ' <link href="' . $this->getConfig('plugins_url') . 'PicoFotofolder/assets/css/fotofolder.css" rel="stylesheet">' . "\n"; | ||
$jsh .= ' <script src="' . $this->getConfig('plugins_url') . 'PicoFotofolder/vendor/lazyload/dist/lazyload.min.js"></script>' . "\n"; | ||
$jsh .= ' <link href="' . $this->getConfig('plugins_url') . 'PicoFotofolder/vendor/baguettebox/dist/baguetteBox.css" rel="stylesheet">' . "\n"; | ||
$jsh .= ' <script src="' . $this->getConfig('plugins_url') . 'PicoFotofolder/vendor/baguettebox/dist/baguetteBox.min.js"></script>' . "\n"; | ||
$jsh .= '</head>' . "\n" . '<body>' . "\n"; | ||
$output = preg_replace('/\\<\\/head\\>\s*\n\s*\\<body\\>/', $jsh, $output, 1); | ||
|
||
// Add LazyLoad | ||
$jsh = '<script>' . "\n"; | ||
$jsh .= ' var lazyLoadInstance = new LazyLoad({ ' . "\n"; | ||
$jsh .= ' elements_selector: ".lazy", ' . "\n"; | ||
$jsh .= ' load_delay: 500' . "\n"; | ||
$jsh .= ' });' . "\n"; | ||
$jsh .= '</script>' . "\n"; | ||
$jsh .= '</body>' . "\n" . '</html>' . "\n"; | ||
$output = preg_replace('/\\<\\/body\\>\s*\n\s*\\<\/html\\>/', $jsh, $output, 1); | ||
} | ||
} | ||
|
||
|
||
/*************************************************************** | ||
* Private Functions | ||
*/ | ||
|
||
/***************************************************************/ | ||
private function readMetaArray() { | ||
$dir = $_SERVER['DOCUMENT_ROOT'] . $this->image_src['path']; | ||
$img_metas = array(); | ||
$pattern = '{,.}*.{[jJ][pP][gG],[jJ][pP][eE][gG],[pP][nN][gG],[gG][iI][fF],dat}'; | ||
$filelist = glob($dir . '/' . $pattern, GLOB_BRACE); | ||
usort($filelist, create_function('$a,$b', 'return filemtime($b) - filemtime($a);')); | ||
|
||
//check if metafile is still up to date or if we have to create a new one | ||
if (strpos($filelist[0], '.fotofolder.dat') == true) { | ||
$string_data = file_get_contents($filelist[0]); | ||
$img_metas = unserialize($string_data); | ||
} | ||
//ok recreate it | ||
else { | ||
foreach ($filelist as $img) { | ||
if (strpos($img, '.fotofolder.dat') == false) { | ||
list($width, $height, $type, $attr) = getimagesize($img); | ||
$exif = (exif_read_data($img, 0, true)); | ||
$url = str_replace($_SERVER['DOCUMENT_ROOT'], '', $img); | ||
$img_name = pathinfo($img, PATHINFO_BASENAME); | ||
|
||
// handle thumbnails | ||
if (!file_exists( $_SERVER['DOCUMENT_ROOT'] . $this->image_src['path'] . '/thumbnails' )) { | ||
mkdir( $_SERVER['DOCUMENT_ROOT'] . $this->image_src['path'] . '/thumbnails', 0777, true); | ||
} | ||
$thumb_name = $_SERVER['DOCUMENT_ROOT'] . $this->image_src['path'] . '/thumbnails/thumb_' . $img_name; | ||
if ( !file_exists($thumb_name) ) { | ||
$this->scaleImageCopy($img, $thumb_name, 300, 300); | ||
} | ||
elseif ( filemtime($thumb_name) < filemtime($img) ) { | ||
$this->scaleImageCopy($img, $thumb_name, 300, 300); | ||
} | ||
if ($width > $height) $format = 'landscape'; | ||
if ($width < $height) $format = 'portrait'; | ||
if ( abs( 1 - $width / $height) > 0.8 ) $format = 'square'; | ||
|
||
|
||
$thumb_date = filemtime($thumb_name); | ||
$thumb_url = $this->image_src['path'] . '/thumbnails/thumb_' . $img_name; | ||
|
||
array_push( $img_metas, array( 'filename' => $img, | ||
'url' => $url, | ||
'imgname' => $img_name, | ||
'date' => $exif['FILE']['FileDateTime'], | ||
'width' => $width, | ||
'height' => $height, | ||
'type' => $type, | ||
'attr' => $attr, | ||
'format' => $format, | ||
'thumb_url' => $thumb_url, | ||
'thumb_date' => $thumb_date )); | ||
|
||
} | ||
} | ||
$string_data = serialize($img_metas); | ||
file_put_contents($_SERVER['DOCUMENT_ROOT'] . $this->image_src['path'] . '/.fotofolder.dat', $string_data); | ||
} | ||
return($img_metas); | ||
} | ||
|
||
/***************************************************************/ | ||
private function createOutput($img_metas) { | ||
|
||
if ( $image_src['order'] == 'asc') { | ||
usort($img_metas, function($a, $b) { | ||
return $a[$this->image_src['sort']] <=> $b[$this->image_src['sort']]; | ||
}); | ||
} | ||
else { | ||
usort($img_metas, function($a, $b) { | ||
return $b[$this->image_src['sort']] <=> $a[$this->image_src['sort']]; | ||
}); | ||
} | ||
|
||
$out = '<div class="mgrid baguette_' . $this->p_count . '">' . "\n"; | ||
foreach ($img_metas as $pic) { | ||
$out .= " <a href=\"{$pic['url']}\" class=\"mgrid-item {$pic['format']}\"> \n"; | ||
$out .= " <img class=\"lazy\" data-src=\"{$pic['thumb_url']}\" src=\"#\" alt=\" \">\n"; | ||
$out .= " <div class=\"zoomicon\" style=\"background-image: url('{$this->getConfig('plugins_url')}PicoFotofolder/assets/circleplus.png')\"> </div> \n"; | ||
$out .= ' </a>' . "\n"; | ||
} | ||
$out .= "</div>\n"; | ||
|
||
$out .= "<script>\n"; | ||
$out .= " baguetteBox.run('.baguette_{$this->p_count}', { \n"; | ||
$out .= " fullScreen: true, \n"; | ||
$out .= " });\n"; | ||
$out .= "</script>\n"; | ||
return $out; | ||
} | ||
|
||
|
||
|
||
|
||
/** | ||
* Resize image - preserve ratio of width and height. | ||
* @param string $sourceImage path to source JPEG image | ||
* @param string $targetImage path to final JPEG image file | ||
* @param int $maxWidth maximum width of final image (value 0 - width is optional) | ||
* @param int $maxHeight maximum height of final image (value 0 - height is optional) | ||
* @param int $quality quality of final image (0-100) | ||
* @return bool | ||
*/ | ||
private function scaleImageCopy($sourceImage, $targetImage, $maxWidth, $maxHeight, $quality = 80) { | ||
// Obtain image from given source file. | ||
if (!$image = @imagecreatefromjpeg($sourceImage)) { | ||
return false; | ||
} | ||
|
||
// Get dimensions of source image. | ||
list($origWidth, $origHeight) = getimagesize($sourceImage); | ||
|
||
if ($maxWidth == 0) $maxWidth = $origWidth; | ||
if ($maxHeight == 0) $maxHeight = $origHeight; | ||
|
||
// do not grow the image | ||
if ( ($origWidth < $maxWidth) && ($origHeight < $maxHeight) ) { | ||
$maxWidth = $origWidth; | ||
$maxHeight = $origHeight; | ||
} | ||
|
||
// Calculate ratio of desired maximum sizes and original sizes. | ||
$widthRatio = $maxWidth / $origWidth; | ||
$heightRatio = $maxHeight / $origHeight; | ||
|
||
// Ratio used for calculating new image dimensions. | ||
$ratio = min($widthRatio, $heightRatio); | ||
|
||
// Calculate new image dimensions. | ||
$newWidth = (int)$origWidth * $ratio; | ||
$newHeight = (int)$origHeight * $ratio; | ||
|
||
// Create final image with new dimensions. | ||
$newImage = imagecreatetruecolor($newWidth, $newHeight); | ||
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight); | ||
imagejpeg($newImage, $targetImage, $quality); | ||
|
||
// Free up the memory. | ||
imagedestroy($image); | ||
imagedestroy($newImage); | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# PicoFotofolder | ||
|
||
A masonry like gallery for [Pico CMS](http://picocms.org) including a fullscreen and lazyload capabilities. It will display all images within a folder as a gallery. It is based on the two small "vanilla" JavaScripts [baguetteBox](https://github.com/feimosi/baguetteBox.js) and [Lazyload](https://github.com/verlok/lazyload). | ||
|
||
## Screenshot | ||
|
||
![Screenshot](images/pico-fotofolder-screenshot.png "Fotofolder Screenshot") | ||
|
||
## Installation | ||
|
||
Copy the files from Github https://github.com/maloja/pico-fotofolder into your Pico CMS plugins folder `plugins/PicoFotofolder`. | ||
|
||
or clone directly from Github in `plugins/PicoFotofolder` | ||
|
||
cd plugins | ||
git clone https://github.com/maloja/pico-fotofolder | ||
|
||
or, if you installed Pico CMS with composer | ||
|
||
composer require maloja/pico-fotofolder | ||
|
||
## Usage | ||
|
||
Add the following expression in your Markdown file: | ||
|
||
(% fotofolder ( /path/to/your/images [sort] [order] %) | ||
|
||
Optional arguments: | ||
- `[sort]` Can be 'date or 'name'. This will sort the images according date, which means the exif image date not the file date, or according the filename. Default is 'name'. | ||
|
||
- `[order]` Can be 'asc' or 'dsc'. Ascending or descending sort order. Default is 'dsc' | ||
|
||
### Caching | ||
|
||
In order to increase page loading speed for PicoFotofolder, an additional subfolder `/thumbnails` for thumbnails is automatically created in your image folder. Therefore, make sure that write rights are granted for your image folder. A hidden file ".fotofolder.dat" is also created. This file stores meta information of your images. The subfolder `/thumbnails` as well as the file" .fotofolder.dat "are created automatically and can be deleted at any time if incorrect information is displayed in the gallery. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.mgrid { | ||
display: grid; | ||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); /* Make columns adjust according to the available viewport */ | ||
grid-gap: 10px; | ||
grid-auto-rows: 260px; /*Set the height for implicitly-created row track */ | ||
grid-auto-flow: dense; | ||
height: fit-content; | ||
} | ||
|
||
|
||
@media screen and (max-width: 820) { | ||
.mgrid { | ||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); | ||
grid-auto-rows: 160px; | ||
} | ||
} | ||
|
||
.mgrid-item.landscape { | ||
grid-column-end: span 2; | ||
} | ||
.mgrid-item.portrait { | ||
grid-row-end: span 1; | ||
} | ||
|
||
.mgrid-item { | ||
position: relative; | ||
overflow: hidden; | ||
border-radius: 3px; | ||
box-sizing: border-box; | ||
} | ||
|
||
.mgrid-item img { | ||
height: 100%; | ||
width: 100%; | ||
object-fit: cover; | ||
} | ||
|
||
.zoomicon { | ||
position: absolute; | ||
top: 50%; | ||
left: 50%; | ||
margin: -24px auto 0 -24px; | ||
width: 48px; | ||
height:48px; | ||
z-index: 10; | ||
background-repeat: no-repeat; | ||
display: none; | ||
} | ||
|
||
.mgrid-item:hover img { | ||
cursor: pointer; | ||
filter: brightness(50%); | ||
} | ||
|
||
.mgrid-item:hover .zoomicon { | ||
display: block; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"name": "maloja/pico-fotofolder", | ||
"type": "pico-plugin", | ||
"description": "A masonry like gallery for Pico CMS", | ||
"keywords": [ "pico", "picocms", "picocms-plugin", "pico-fotofolder", "gallery" ], | ||
"homepage": "https://github.com/maloja/pico-fotofolder", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Maloja", | ||
"homepage": "https://github.com/maloja/pico-fotofolder", | ||
"role": "Lead Developer" | ||
} | ||
], | ||
"support": { | ||
"docs": "http://picocms.org/docs/pico-http-params/", | ||
"issues": "https://github.com/maloja/pico-fotofolder/issues", | ||
"source": "https://github.com/maloja/pico-fotofolder" | ||
}, | ||
"require": { | ||
"php": ">=5.3.6" | ||
}, | ||
"autoload": { | ||
"classmap": [ "PicoFotofolder.php" ] | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2017 Marek Grzybek | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
Oops, something went wrong.