mirror of https://github.com/thumbsup/thumbsup
Merge pull request #44 from rprieto/albums
thumbsup v2: rewrite the website around 'albums'pull/45/head
commit
fa5652b380
@ -0,0 +1,146 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>Photo album - captions</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="public/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Photo album</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
|
||||
<section id="sidebar">
|
||||
<nav>
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index.html">
|
||||
|
||||
Home<span class="count">24</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-photos.html">
|
||||
-
|
||||
photos<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-videos.html">
|
||||
-
|
||||
videos<span class="count">2</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-captions.html">
|
||||
-
|
||||
captions<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-rotations.html">
|
||||
-
|
||||
rotations<span class="count">16</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
|
||||
<nav class="breadcrumbs">
|
||||
<a class="breadcrumb-item" href="index.html">Home </a><span class="breadcrumb-item active">captions</span>
|
||||
</nav>
|
||||
|
||||
<ul id="albums">
|
||||
</ul>
|
||||
|
||||
<ul id="gallery">
|
||||
<li data-src="media/large/captions/sunset.jpg"
|
||||
data-sub-html="Beach"
|
||||
data-download-url="media/large/captions/sunset.jpg">
|
||||
<a href="media/large/captions/sunset.jpg">
|
||||
<img src="media/thumbs/captions/sunset.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="sunset.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/captions/tree.jpg"
|
||||
data-sub-html="Autum"
|
||||
data-download-url="media/large/captions/tree.jpg">
|
||||
<a href="media/large/captions/tree.jpg">
|
||||
<img src="media/thumbs/captions/tree.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="tree.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/captions/water.jpg"
|
||||
data-sub-html="Sea"
|
||||
data-download-url="media/large/captions/water.jpg">
|
||||
<a href="media/large/captions/water.jpg">
|
||||
<img src="media/thumbs/captions/water.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="water.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="public/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="public/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,146 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>Photo album - photos</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="public/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Photo album</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
|
||||
<section id="sidebar">
|
||||
<nav>
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index.html">
|
||||
|
||||
Home<span class="count">24</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-photos.html">
|
||||
-
|
||||
photos<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-videos.html">
|
||||
-
|
||||
videos<span class="count">2</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-captions.html">
|
||||
-
|
||||
captions<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-rotations.html">
|
||||
-
|
||||
rotations<span class="count">16</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
|
||||
<nav class="breadcrumbs">
|
||||
<a class="breadcrumb-item" href="index.html">Home </a><span class="breadcrumb-item active">photos</span>
|
||||
</nav>
|
||||
|
||||
<ul id="albums">
|
||||
</ul>
|
||||
|
||||
<ul id="gallery">
|
||||
<li data-src="media/large/photos/port-stephens.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/photos/port-stephens.jpg">
|
||||
<a href="media/large/photos/port-stephens.jpg">
|
||||
<img src="media/thumbs/photos/port-stephens.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="port-stephens.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/photos/port-douglas1.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/photos/port-douglas1.jpg">
|
||||
<a href="media/large/photos/port-douglas1.jpg">
|
||||
<img src="media/thumbs/photos/port-douglas1.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="port-douglas1.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/photos/port-douglas2.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/photos/port-douglas2.jpg">
|
||||
<a href="media/large/photos/port-douglas2.jpg">
|
||||
<img src="media/thumbs/photos/port-douglas2.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="port-douglas2.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="public/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="public/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,276 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>Photo album - rotations</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="public/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Photo album</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
|
||||
<section id="sidebar">
|
||||
<nav>
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index.html">
|
||||
|
||||
Home<span class="count">24</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-photos.html">
|
||||
-
|
||||
photos<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-videos.html">
|
||||
-
|
||||
videos<span class="count">2</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-captions.html">
|
||||
-
|
||||
captions<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-rotations.html">
|
||||
-
|
||||
rotations<span class="count">16</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
|
||||
<nav class="breadcrumbs">
|
||||
<a class="breadcrumb-item" href="index.html">Home </a><span class="breadcrumb-item active">rotations</span>
|
||||
</nav>
|
||||
|
||||
<ul id="albums">
|
||||
</ul>
|
||||
|
||||
<ul id="gallery">
|
||||
<li data-src="media/large/rotations/Landscape_1.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_1.jpg">
|
||||
<a href="media/large/rotations/Landscape_1.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_1.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_1.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_2.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_2.jpg">
|
||||
<a href="media/large/rotations/Landscape_2.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_2.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_2.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_3.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_3.jpg">
|
||||
<a href="media/large/rotations/Landscape_3.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_3.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_3.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_4.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_4.jpg">
|
||||
<a href="media/large/rotations/Landscape_4.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_4.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_4.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_5.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_5.jpg">
|
||||
<a href="media/large/rotations/Landscape_5.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_5.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_5.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_6.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_6.jpg">
|
||||
<a href="media/large/rotations/Landscape_6.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_6.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_6.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_7.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_7.jpg">
|
||||
<a href="media/large/rotations/Landscape_7.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_7.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_7.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Landscape_8.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Landscape_8.jpg">
|
||||
<a href="media/large/rotations/Landscape_8.jpg">
|
||||
<img src="media/thumbs/rotations/Landscape_8.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Landscape_8.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_1.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_1.jpg">
|
||||
<a href="media/large/rotations/Portrait_1.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_1.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_1.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_2.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_2.jpg">
|
||||
<a href="media/large/rotations/Portrait_2.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_2.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_2.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_3.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_3.jpg">
|
||||
<a href="media/large/rotations/Portrait_3.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_3.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_3.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_4.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_4.jpg">
|
||||
<a href="media/large/rotations/Portrait_4.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_4.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_4.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_5.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_5.jpg">
|
||||
<a href="media/large/rotations/Portrait_5.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_5.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_5.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_6.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_6.jpg">
|
||||
<a href="media/large/rotations/Portrait_6.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_6.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_6.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_7.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_7.jpg">
|
||||
<a href="media/large/rotations/Portrait_7.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_7.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_7.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
<li data-src="media/large/rotations/Portrait_8.jpg"
|
||||
data-sub-html=""
|
||||
data-download-url="media/large/rotations/Portrait_8.jpg">
|
||||
<a href="media/large/rotations/Portrait_8.jpg">
|
||||
<img src="media/thumbs/rotations/Portrait_8.jpg"
|
||||
width="120"
|
||||
height="120"
|
||||
alt="Portrait_8.jpg" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="public/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="public/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>Photo album - videos</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="public/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Photo album</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
|
||||
<section id="sidebar">
|
||||
<nav>
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index.html">
|
||||
|
||||
Home<span class="count">24</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-photos.html">
|
||||
-
|
||||
photos<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-videos.html">
|
||||
-
|
||||
videos<span class="count">2</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-captions.html">
|
||||
-
|
||||
captions<span class="count">3</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="index-rotations.html">
|
||||
-
|
||||
rotations<span class="count">16</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
|
||||
<nav class="breadcrumbs">
|
||||
<a class="breadcrumb-item" href="index.html">Home </a><span class="breadcrumb-item active">videos</span>
|
||||
</nav>
|
||||
|
||||
<ul id="albums">
|
||||
</ul>
|
||||
|
||||
<ul id="gallery">
|
||||
<li data-html="#media23"
|
||||
data-poster="media/large/videos/countdown.jpg"
|
||||
data-download-url="">
|
||||
<a href="">
|
||||
<img src="media/thumbs/videos/countdown.jpg"
|
||||
width=""
|
||||
height="120"
|
||||
alt="countdown.mp4" />
|
||||
</a>
|
||||
<img class="video-overlay" src="public/play.png" />
|
||||
</li>
|
||||
<li data-html="#media24"
|
||||
data-poster="media/large/videos/momentum.jpg"
|
||||
data-download-url="">
|
||||
<a href="">
|
||||
<img src="media/thumbs/videos/momentum.jpg"
|
||||
width=""
|
||||
height="120"
|
||||
alt="momentum.m2ts" />
|
||||
</a>
|
||||
<img class="video-overlay" src="public/play.png" />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
<div id="media23" style="display:none;">
|
||||
<video class="lg-video-object lg-html5 video-js vjs-default-skin" preload="none" controls>
|
||||
<source src="media/large/videos/countdown.mp4" type="video/mp4" />
|
||||
Your browser does not support HTML5 video
|
||||
</video>
|
||||
</div>
|
||||
<div id="media24" style="display:none;">
|
||||
<video class="lg-video-object lg-html5 video-js vjs-default-skin" preload="none" controls>
|
||||
<source src="media/large/videos/momentum.mp4" type="video/mp4" />
|
||||
Your browser does not support HTML5 video
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="public/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="public/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 297 KiB |
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
Before Width: | Height: | Size: 75 KiB |
@ -0,0 +1,9 @@
|
||||
var File = require('./file');
|
||||
|
||||
exports.fromMetadata = function(metadata) {
|
||||
return {
|
||||
files: Object.keys(metadata).map(function(filepath) {
|
||||
return new File(filepath, metadata[filepath]);
|
||||
})
|
||||
}
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
var path = require('path');
|
||||
var index = 0;
|
||||
|
||||
function File(filepath, metadata) {
|
||||
this.id = ++index;
|
||||
this.filepath = filepath;
|
||||
this.filename = path.basename(filepath);
|
||||
this.date = new Date(metadata.exif.date || metadata.fileDate);
|
||||
this.caption = metadata.exif.caption;
|
||||
this.isVideo = (metadata.mediaType === 'video');
|
||||
this.urls = urls(filepath, metadata.mediaType);
|
||||
}
|
||||
|
||||
function urls(filepath, mediaType) {
|
||||
return (mediaType === 'video') ? videoUrls(filepath) : photoUrls(filepath);
|
||||
}
|
||||
|
||||
function videoUrls(filepath) {
|
||||
return {
|
||||
thumb: 'media/thumbs/' + ext(filepath, 'jpg'),
|
||||
poster: 'media/large/' + ext(filepath, 'jpg'),
|
||||
video: 'media/large/' + ext(filepath, 'mp4'),
|
||||
original: 'media/original/' + filepath
|
||||
};
|
||||
}
|
||||
|
||||
function photoUrls(filepath) {
|
||||
return {
|
||||
thumb: 'media/thumbs/' + filepath,
|
||||
large: 'media/large/' + filepath,
|
||||
original: 'media/original/' + filepath
|
||||
};
|
||||
}
|
||||
|
||||
function ext(file, ext) {
|
||||
return file.replace(/\.[a-z0-9]+$/i, '.' + ext);
|
||||
}
|
||||
|
||||
module.exports = File;
|
@ -0,0 +1,105 @@
|
||||
var _ = require('lodash');
|
||||
var index = 0;
|
||||
|
||||
// number of images to show in the album preview grid
|
||||
var PREVIEW_COUNT = 2;
|
||||
|
||||
var SORT_ALBUMS_BY = {
|
||||
title: function(album) { return album.title; },
|
||||
date: function(album) { return album.stats.fromDate; }
|
||||
};
|
||||
|
||||
var SORT_MEDIA_BY = {
|
||||
filename: function(file) { return file.filename; },
|
||||
date: function(file) { return file.date; }
|
||||
};
|
||||
|
||||
function Album(opts) {
|
||||
if (typeof opts === 'string') opts = { title: opts };
|
||||
this.title = opts.title || ('Album ' + index++);
|
||||
this.filename = sanitise(this.title);
|
||||
this.files = opts.files || [];
|
||||
this.albums = opts.albums || [];
|
||||
this.depth = 0;
|
||||
this.stats = null;
|
||||
this.previews = null;
|
||||
}
|
||||
|
||||
Album.prototype.finalize = function(options) {
|
||||
options = _.defaults(options, {
|
||||
sortAlbumsBy: 'date',
|
||||
sortMediaBy: 'date'
|
||||
});
|
||||
// lock all nested albums first (recursive)
|
||||
// and set a nested filename
|
||||
for (var i = 0; i < this.albums.length; ++i) {
|
||||
this.albums[i].filename = this.filename + '-' + this.albums[i].filename;
|
||||
this.albums[i].depth = this.depth + 1;
|
||||
this.albums[i].finalize();
|
||||
}
|
||||
this.calculateStats();
|
||||
this.calculateSummary();
|
||||
this.sort(options);
|
||||
this.pickPreviews();
|
||||
};
|
||||
|
||||
Album.prototype.calculateStats = function() {
|
||||
// nested albums
|
||||
var nestedPhotos = _.map(this.albums, 'stats.photos');
|
||||
var nestedVideos = _.map(this.albums, 'stats.videos');
|
||||
var nestedFromDates = _.map(this.albums, 'stats.fromDate');
|
||||
var nestedToDates = _.map(this.albums, 'stats.toDate');
|
||||
// current level
|
||||
var currentPhotos = _.filter(this.files, {isVideo: false}).length;
|
||||
var currentVideos = _.filter(this.files, {isVideo: true}).length;
|
||||
var currentFromDate = _.map(this.files, 'date');
|
||||
var currentToDate = _.map(this.files, 'date');
|
||||
// aggregate all stats
|
||||
this.stats = {
|
||||
albums: this.albums.length,
|
||||
photos: _.sum(_.compact(_.concat(nestedPhotos, currentPhotos))) || 0,
|
||||
videos: _.sum(_.compact(_.concat(nestedVideos, currentVideos))) || 0,
|
||||
fromDate: _.min(_.compact(_.concat(nestedFromDates, currentFromDate))),
|
||||
toDate: _.max(_.compact(_.concat(nestedToDates, currentToDate)))
|
||||
};
|
||||
this.stats.total = this.stats.photos + this.stats.videos;
|
||||
}
|
||||
|
||||
Album.prototype.calculateSummary = function() {
|
||||
var items = [
|
||||
itemCount(this.stats.albums, 'album'),
|
||||
itemCount(this.stats.photos, 'photo'),
|
||||
itemCount(this.stats.videos, 'video')
|
||||
];
|
||||
this.summary = _.compact(items).join(', ');
|
||||
};
|
||||
|
||||
Album.prototype.sort = function(options) {
|
||||
this.files = _.sortBy(this.files, SORT_MEDIA_BY[options.sortMediaBy]);
|
||||
this.albums = _.sortBy(this.albums, SORT_ALBUMS_BY[options.sortAlbumsBy]);
|
||||
this.albums.forEach(function(nested) {
|
||||
nested.sort(options);
|
||||
});
|
||||
};
|
||||
|
||||
Album.prototype.pickPreviews = function() {
|
||||
this.previews = this.files.slice(0, PREVIEW_COUNT);
|
||||
var missing = PREVIEW_COUNT - this.previews.length;
|
||||
for (var i = 0; i < missing; ++i) {
|
||||
this.previews.push({
|
||||
urls: { thumb: 'public/missing.png' }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function sanitise(filename) {
|
||||
return filename.replace(/[^a-z0-9-_]/ig, '');
|
||||
}
|
||||
|
||||
function itemCount(count, type) {
|
||||
if (count === 0) return '';
|
||||
var plural = (count > 1) ? 's' : '';
|
||||
return '' + count + ' ' + type + plural;
|
||||
}
|
||||
|
||||
module.exports = Album;
|
@ -0,0 +1,31 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var Album = require('./album');
|
||||
|
||||
// for now, a single level of albums by month named "{year}-{month}"
|
||||
// eventually could support nested albums e.g. "{year}/{month}"
|
||||
// it could be an option like "format: yyyy/mm"
|
||||
exports.albums = function(collection, opts) {
|
||||
var groups = {};
|
||||
collection.files.forEach(function(file) {
|
||||
var groupName = exports.format(file.date);
|
||||
if (!groups.hasOwnProperty(groupName)) {
|
||||
groups[groupName] = [];
|
||||
}
|
||||
groups[groupName].push(file);
|
||||
});
|
||||
var albums = _.map(groups, function(val, key) {
|
||||
return new Album({
|
||||
title: key,
|
||||
files: groups[key]
|
||||
});
|
||||
})
|
||||
return albums;
|
||||
};
|
||||
|
||||
exports.format = function(date) {
|
||||
var year = date.getFullYear().toString();
|
||||
var month = new String(date.getMonth() + 1);
|
||||
if (month.length === 1) month = '0' + month;
|
||||
return year + '-' + month;
|
||||
};
|
@ -0,0 +1,24 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var Album = require('./album');
|
||||
|
||||
// for now only 1 level of folders,
|
||||
// e.g. an album might be called "holidays/newyork" or "holidays/tokyo"n
|
||||
// eventually we could return nested albums as an option
|
||||
exports.albums = function(collection, opts) {
|
||||
var folders = {};
|
||||
collection.files.forEach(function(file) {
|
||||
var dir = path.dirname(file.filepath);
|
||||
if (!folders.hasOwnProperty(dir)) {
|
||||
folders[dir] = [];
|
||||
}
|
||||
folders[dir].push(file);
|
||||
});
|
||||
var albums = _.map(folders, function(val, key) {
|
||||
return new Album({
|
||||
title: key,
|
||||
files: folders[key]
|
||||
});
|
||||
})
|
||||
return albums;
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
var async = require('async');
|
||||
var pad = require('pad');
|
||||
var files = require('../utils/files');
|
||||
var template = require('./template');
|
||||
var model = require('./model');
|
||||
var pages = require('./pages');
|
||||
|
||||
exports.build = function(metadata, opts, callback) {
|
||||
|
||||
var common = pages.common(opts);
|
||||
|
||||
function render(filename, templateName, data) {
|
||||
var fullPath = path.join(opts.output, filename);
|
||||
var pageData = _.extend(data, common);
|
||||
var contents = template.render(templateName, pageData);
|
||||
return function(next) {
|
||||
fs.writeFile(fullPath, contents, next);
|
||||
};
|
||||
}
|
||||
|
||||
function website(callback) {
|
||||
var structure = model.create(metadata, opts);
|
||||
var homepage = pages.homepage(structure);
|
||||
var index = opts.index || 'index.html';
|
||||
|
||||
var items = [
|
||||
render(index, 'homepage', homepage)
|
||||
];
|
||||
|
||||
structure.forEach(function(folder, index) {
|
||||
var gallery = pages.gallery(structure, index);
|
||||
var page = render(folder.name + '.html', 'gallery', gallery);
|
||||
items.push(page);
|
||||
});
|
||||
|
||||
async.parallel(items, callback);
|
||||
}
|
||||
|
||||
function lightGallery(callback) {
|
||||
// note: this module might be deduped
|
||||
// so we can't assume it's in the local node_modules
|
||||
var lgPackage = require.resolve('lightgallery/package.json');
|
||||
var src = path.join(path.dirname(lgPackage), 'dist');
|
||||
var dest = path.join(opts.output, 'public', 'light-gallery');
|
||||
fs.copy(src, dest, callback);
|
||||
}
|
||||
|
||||
function support(callback) {
|
||||
var src = path.join(__dirname, '..', '..', 'public');
|
||||
var dest = path.join(opts.output, 'public');
|
||||
fs.copy(src, dest, callback);
|
||||
}
|
||||
|
||||
function customStyle(callback) {
|
||||
if (opts.css) {
|
||||
var dest = path.join(opts.output, 'public', path.basename(opts.css));
|
||||
fs.copy(opts.css, dest, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
process.stdout.write(pad('Static website', 20));
|
||||
async.series([
|
||||
website,
|
||||
lightGallery,
|
||||
support,
|
||||
customStyle
|
||||
], function(err) {
|
||||
console.log('[====================] done');
|
||||
callback(err);
|
||||
});
|
||||
|
||||
};
|
@ -1,91 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var glob = require('glob');
|
||||
|
||||
/*
|
||||
In-memory structure of the galleries organised in folders
|
||||
with relative links to the media, thumbnails, etc...
|
||||
*/
|
||||
|
||||
exports.create = function(metadata, opts) {
|
||||
|
||||
var index = 0;
|
||||
|
||||
function fileInfo(data, file) {
|
||||
return {
|
||||
id: ++index,
|
||||
date: data.exif.date || data.fileDate,
|
||||
path: file,
|
||||
name: path.basename(file),
|
||||
video: data.mediaType === 'video',
|
||||
size: opts.thumbSize,
|
||||
urls: urls(file, data),
|
||||
caption: data.exif.caption
|
||||
}
|
||||
}
|
||||
|
||||
function urls(file, data) {
|
||||
if (data.mediaType === 'video') {
|
||||
var urls = videoUrls(file);
|
||||
urls.download = opts.originalVideos ? urls.original : urls.video;
|
||||
return urls;
|
||||
} else {
|
||||
var urls = photoUrls(file);
|
||||
urls.download = opts.originalPhotos ? urls.original : urls.large;
|
||||
return urls;
|
||||
}
|
||||
}
|
||||
|
||||
function videoUrls(file) {
|
||||
return {
|
||||
thumb: 'media/thumbs/' + ext(file, 'jpg'),
|
||||
poster: 'media/large/' + ext(file, 'jpg'),
|
||||
video: 'media/large/' + ext(file, 'mp4'),
|
||||
original: 'media/original/' + file
|
||||
};
|
||||
}
|
||||
|
||||
function photoUrls(file) {
|
||||
return {
|
||||
thumb: 'media/thumbs/' + file,
|
||||
large: 'media/large/' + file,
|
||||
original: 'media/original/' + file
|
||||
};
|
||||
}
|
||||
|
||||
function ext(file, ext) {
|
||||
return file.replace(/\.[a-z0-9]+$/i, '.' + ext);
|
||||
}
|
||||
|
||||
function byFolder(file) {
|
||||
return path.dirname(file.path);
|
||||
}
|
||||
|
||||
function folderInfo(files, name) {
|
||||
return {
|
||||
name: name,
|
||||
media: files,
|
||||
url: name + '.html'
|
||||
};
|
||||
}
|
||||
|
||||
var sortFunctions = {
|
||||
'name': function(folder) {
|
||||
return folder.name;
|
||||
},
|
||||
'date': function(folder) {
|
||||
return _(folder.media).sortBy('date').first().date;
|
||||
}
|
||||
};
|
||||
|
||||
var chosenSort = sortFunctions[opts.sortFolders];
|
||||
|
||||
return _(metadata).map(fileInfo)
|
||||
.sortBy('date')
|
||||
.groupBy(byFolder)
|
||||
.map(folderInfo)
|
||||
.sortBy(chosenSort)
|
||||
.value();
|
||||
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var moment = require('moment');
|
||||
|
||||
/*
|
||||
Common page data shared by all models
|
||||
*/
|
||||
exports.common = function(opts) {
|
||||
var titleParts = opts.title.split(' ');
|
||||
return {
|
||||
css: opts.css ? path.basename(opts.css) : null,
|
||||
title: titleParts[0],
|
||||
subtitle: titleParts.slice(1).join(' '),
|
||||
googleAnalytics: opts.googleAnalytics
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
Homepage data
|
||||
*/
|
||||
exports.homepage = function(structure) {
|
||||
var galleries = structure.map(function(folder) {
|
||||
return {
|
||||
name: folder.name,
|
||||
url: folder.name + '.html',
|
||||
stats: stats(folder.media),
|
||||
fromDate: date(_.minBy(folder.media, 'date').date),
|
||||
toDate: date(_.maxBy(folder.media, 'date').date),
|
||||
grid: grid(folder.media)
|
||||
};
|
||||
});
|
||||
return {
|
||||
galleries: galleries
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Single gallery page
|
||||
*/
|
||||
exports.gallery = function(structure, index) {
|
||||
var links = structure.map(function(folder, i) {
|
||||
return {
|
||||
name: folder.name,
|
||||
url: folder.name + '.html',
|
||||
active: (i === index)
|
||||
};
|
||||
});
|
||||
return {
|
||||
links: links,
|
||||
gallery: structure[index]
|
||||
};
|
||||
};
|
||||
|
||||
function stats(media) {
|
||||
var results = [];
|
||||
var photos = _.filter(media, {video: false}).length;
|
||||
var videos = _.filter(media, {video: true}).length;
|
||||
if (photos > 0) results.push(photos + ' photos');
|
||||
if (videos > 0) results.push(videos + ' videos');
|
||||
return results.join(', ');
|
||||
}
|
||||
|
||||
function date(timestamp) {
|
||||
return moment(timestamp).format('D MMM YY');
|
||||
}
|
||||
|
||||
function grid(media) {
|
||||
return [
|
||||
(media.length > 0) ? media[0].urls.thumb : 'public/missing.png',
|
||||
(media.length > 1) ? media[1].urls.thumb : 'public/missing.png',
|
||||
(media.length > 2) ? media[2].urls.thumb : 'public/missing.png',
|
||||
(media.length > 3) ? media[3].urls.thumb : 'public/missing.png'
|
||||
];
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
var async = require('async');
|
||||
var pad = require('pad');
|
||||
var files = require('../utils/files');
|
||||
var template = require('./template');
|
||||
var Album = require('./album');
|
||||
var byFolder = require('./by-folder');
|
||||
|
||||
exports.build = function(collection, opts, callback) {
|
||||
|
||||
// set the download link to the right place
|
||||
template.setOptions({
|
||||
originalPhotos: opts.originalPhotos,
|
||||
originalVideos: opts.originalVideos
|
||||
});
|
||||
|
||||
function website(callback) {
|
||||
// top-level album for the home page
|
||||
var home = new Album('Home');
|
||||
home.filename = opts.index || 'index';
|
||||
// create folder albums
|
||||
home.albums = byFolder.albums(collection, {});
|
||||
home.finalize();
|
||||
// create top level gallery
|
||||
var gallery = {
|
||||
home: home,
|
||||
css: opts.css ? path.basename(opts.css) : null,
|
||||
title: opts.title,
|
||||
titleWords: opts.title.split(' '),
|
||||
thumbSize: opts.thumbSize,
|
||||
largeSize: opts.largeSize,
|
||||
googleAnalytics: opts.googleAnalytics
|
||||
};
|
||||
// render entire album hierarchy
|
||||
var tasks = renderAlbum(gallery, [], home);
|
||||
async.parallel(tasks, callback);
|
||||
}
|
||||
|
||||
function renderAlbum(gallery, breadcrumbs, album) {
|
||||
// render this album
|
||||
var thisAlbumTask = renderTemplate(album.filename + '.html', 'album', {
|
||||
gallery: gallery,
|
||||
breadcrumbs: breadcrumbs,
|
||||
album: album
|
||||
});
|
||||
var tasks = [thisAlbumTask];
|
||||
// and all nested albums
|
||||
album.albums.forEach(function(nested) {
|
||||
var nestedAlbumsTasks = renderAlbum(gallery, breadcrumbs.concat([album]), nested);
|
||||
Array.prototype.push.apply(tasks, nestedAlbumsTasks);
|
||||
});
|
||||
return tasks;
|
||||
}
|
||||
|
||||
function renderTemplate(filename, templateName, data) {
|
||||
// render a given HBS template
|
||||
var fullPath = path.join(opts.output, filename);
|
||||
var contents = template.render(templateName, data);
|
||||
return function(next) {
|
||||
fs.writeFile(fullPath, contents, next);
|
||||
};
|
||||
}
|
||||
|
||||
function lightGallery(callback) {
|
||||
// note: this module might be deduped
|
||||
// so we can't assume it's in the local node_modules
|
||||
var lgPackage = require.resolve('lightgallery/package.json');
|
||||
var src = path.join(path.dirname(lgPackage), 'dist');
|
||||
var dest = path.join(opts.output, 'public', 'light-gallery');
|
||||
fs.copy(src, dest, callback);
|
||||
}
|
||||
|
||||
function support(callback) {
|
||||
var src = path.join(__dirname, '..', '..', 'public');
|
||||
var dest = path.join(opts.output, 'public');
|
||||
fs.copy(src, dest, callback);
|
||||
}
|
||||
|
||||
function customStyle(callback) {
|
||||
if (opts.css) {
|
||||
var dest = path.join(opts.output, 'public', path.basename(opts.css));
|
||||
fs.copy(opts.css, dest, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
process.stdout.write(pad('Static website', 20));
|
||||
async.series([
|
||||
website,
|
||||
lightGallery,
|
||||
support,
|
||||
customStyle
|
||||
], function(err) {
|
||||
console.log('[====================] done');
|
||||
callback(err);
|
||||
});
|
||||
|
||||
};
|
@ -0,0 +1,131 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>{{gallery.title}} - {{album.title}}</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="public/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
{{#if gallery.css}}
|
||||
<link rel="stylesheet" href="public/{{gallery.css}}" />
|
||||
{{/if}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>{{gallery.title}}</h1>
|
||||
<h2>{{gallery.subtitle}}</h2>
|
||||
</header>
|
||||
|
||||
<section id="sidebar">
|
||||
<nav>
|
||||
{{> sidebar-album gallery.home }}
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
|
||||
<nav class="breadcrumbs">
|
||||
{{#each breadcrumbs~}}
|
||||
<a class="breadcrumb-item" href="{{filename}}.html">{{title}} </a>
|
||||
{{~/each~}}
|
||||
<span class="breadcrumb-item active">{{album.title}}</span>
|
||||
</nav>
|
||||
|
||||
<ul id="albums">
|
||||
{{#each album.albums}}
|
||||
<li>
|
||||
<a href="{{filename}}.html">
|
||||
<ul class="grid clearfix">
|
||||
{{~#each previews ~}}
|
||||
<li><img src="{{this.urls.thumb}}" /></li>
|
||||
{{~/each}}
|
||||
</ul>
|
||||
<h3>{{title}}</h3>
|
||||
<div class="meta">
|
||||
{{summary}}<br />
|
||||
{{{date stats.fromDate}}} - {{{date stats.toDate}}}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
<ul id="gallery">
|
||||
{{#each album.files}}
|
||||
{{#if isVideo}}
|
||||
<li data-html="#media{{id}}"
|
||||
data-poster="{{urls.poster}}"
|
||||
data-download-url="{{{download this}}}">
|
||||
<a href="{{{download this}}}">
|
||||
<img src="{{urls.thumb}}"
|
||||
width="{{../gallery.thumbsSize}}"
|
||||
height="{{../gallery.thumbSize}}"
|
||||
alt="{{filename}}" />
|
||||
</a>
|
||||
<img class="video-overlay" src="public/play.png" />
|
||||
</li>
|
||||
{{else}}
|
||||
<li data-src="{{urls.large}}"
|
||||
data-sub-html="{{caption}}"
|
||||
data-download-url="{{{download this}}}">
|
||||
<a href="{{{download this}}}">
|
||||
<img src="{{urls.thumb}}"
|
||||
width="{{../gallery.thumbSize}}"
|
||||
height="{{../gallery.thumbSize}}"
|
||||
alt="{{filename}}" />
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
{{#each album.files}}
|
||||
{{#if isVideo}}
|
||||
<div id="media{{id}}" style="display:none;">
|
||||
<video class="lg-video-object lg-html5 video-js vjs-default-skin" preload="none" controls>
|
||||
<source src="{{urls.video}}" type="video/mp4" />
|
||||
Your browser does not support HTML5 video
|
||||
</video>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="public/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="public/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{{> analytics}}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,107 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>{{gallery.name}}</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/light-gallery/css/lightgallery.css" />
|
||||
<link rel="stylesheet" href="http://vjs.zencdn.net/4.12/video-js.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
{{#if css}}
|
||||
<link rel="stylesheet" href="public/{{css}}" />
|
||||
{{/if}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<a href="index.html">
|
||||
<h1>{{title}}</h1>
|
||||
<h2>{{subtitle}}</h2>
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
{{#each links}}
|
||||
<li {{#if active}}class="active"{{/if}}>
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<ul id="gallery">
|
||||
{{#each gallery.media}}
|
||||
{{#if video}}
|
||||
<li data-html="#media{{id}}"
|
||||
data-poster="{{urls.poster}}"
|
||||
data-download-url="{{urls.download}}">
|
||||
<a href="{{urls.download}}">
|
||||
<img src="{{urls.thumb}}"
|
||||
width="{{size}}"
|
||||
height="{{size}}"
|
||||
alt="{{name}}" />
|
||||
</a>
|
||||
<img class="video-overlay" src="public/play.png" />
|
||||
</li>
|
||||
{{else}}
|
||||
<li data-src="{{urls.large}}"
|
||||
data-sub-html="{{caption}}"
|
||||
data-download-url="{{urls.download}}">
|
||||
<a href="{{urls.download}}">
|
||||
<img src="{{urls.thumb}}"
|
||||
width="{{size}}"
|
||||
height="{{size}}"
|
||||
alt="{{name}}" />
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
<div id="videos">
|
||||
{{#each gallery.media}}
|
||||
{{#if video}}
|
||||
<div id="media{{id}}" style="display:none;">
|
||||
<video class="lg-video-object lg-html5 video-js vjs-default-skin" preload="none" controls>
|
||||
<source src="{{urls.video}}" type="video/mp4" />
|
||||
Your browser does not support HTML5 video
|
||||
</video>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||
<!-- VideoJS -->
|
||||
<script src="http://vjs.zencdn.net/4.12/video.js"></script>
|
||||
<!-- LightGallery -->
|
||||
<script src="public/light-gallery/js/lightgallery.js"></script>
|
||||
<script src="public/light-gallery/js/lg-autoplay.js"></script>
|
||||
<script src="public/light-gallery/js/lg-pager.js"></script>
|
||||
<script src="public/light-gallery/js/lg-thumbnail.js"></script>
|
||||
<script src="public/light-gallery/js/lg-video.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#gallery").lightGallery({
|
||||
thumbWidth: 80,
|
||||
controls: true,
|
||||
loop : false,
|
||||
download: true,
|
||||
counter: true,
|
||||
videojs: true
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{{> analytics}}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
||||
<title>{{title}} {{subtitle}}</title>
|
||||
<link rel="stylesheet" href="public/reset.css" />
|
||||
<link rel="stylesheet" href="public/theme.css" />
|
||||
{{#if css}}
|
||||
<link rel="stylesheet" href="public/{{css}}" />
|
||||
{{/if}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>{{title}}</h1>
|
||||
<h2>{{subtitle}}</h2>
|
||||
</header>
|
||||
|
||||
<ul id="galleries">
|
||||
{{#each galleries}}
|
||||
<li>
|
||||
<a href="{{url}}">
|
||||
<h3>{{name}}</h3>
|
||||
<div class="meta">
|
||||
{{stats}}<br />
|
||||
{{fromDate}} - {{toDate}}
|
||||
</div>
|
||||
{{#if grid}}
|
||||
<ul class="grid">
|
||||
{{#each grid}}<li><img src="{{this}}" /></li>{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<img class="single" src="{{single}}" />
|
||||
{{/if}}
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
{{> analytics}}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
<!-- This album -->
|
||||
<a href="{{filename}}.html">
|
||||
{{#times depth}}-{{/times}}
|
||||
{{title}}<span class="count">{{stats.total}}</span>
|
||||
</a>
|
||||
|
||||
<!-- And nested album -->
|
||||
{{#each albums}}
|
||||
{{> sidebar-album}}
|
||||
{{/each}}
|
@ -0,0 +1,20 @@
|
||||
var should = require('should/as-function');
|
||||
var File = require('../src/file');
|
||||
var fixtures = require('./fixtures');
|
||||
|
||||
describe('File', function() {
|
||||
|
||||
it('stores the file name', function(){
|
||||
var f = new File('holidays/newyork/IMG_000001.jpg', fixtures.metadata());
|
||||
should(f.filename).eql('IMG_000001.jpg');
|
||||
});
|
||||
|
||||
it('reads the date from the file <mdate>', function() {
|
||||
var meta = fixtures.metadata();
|
||||
meta.fileDate = fixtures.date('2016-09-23');
|
||||
meta.exif.date = null;
|
||||
var f = new File('IMG_000001.jpg', meta);
|
||||
should(f.date).eql(fixtures.date('2016-09-23'));
|
||||
})
|
||||
|
||||
});
|
@ -0,0 +1,45 @@
|
||||
var File = require('../src/file');
|
||||
|
||||
exports.metadata = function() {
|
||||
return {
|
||||
fileDate: new Date(),
|
||||
mediaType: 'photo',
|
||||
exif: {
|
||||
date: null,
|
||||
orientation: 1,
|
||||
caption: ''
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
exports.date = function(str) {
|
||||
return new Date(Date.parse(str));
|
||||
};
|
||||
|
||||
exports.photo = function(opts) {
|
||||
opts = opts || {};
|
||||
var date = opts.date ? new Date(Date.parse(opts.date)) : new Date();
|
||||
return new File(opts.path || 'tmp', {
|
||||
fileDate: date,
|
||||
mediaType: 'photo',
|
||||
exif: {
|
||||
date: null,
|
||||
orientation: 1,
|
||||
caption: ''
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.video = function(opts) {
|
||||
opts = opts || {};
|
||||
var date = opts.date ? new Date(Date.parse(opts.date)) : new Date();
|
||||
return new File(opts.path || 'tmp', {
|
||||
fileDate: date,
|
||||
mediaType: 'video',
|
||||
exif: {
|
||||
date: null,
|
||||
orientation: 1,
|
||||
caption: ''
|
||||
}
|
||||
});
|
||||
};
|
@ -0,0 +1 @@
|
||||
--recursive
|
@ -0,0 +1,118 @@
|
||||
var should = require('should/as-function');
|
||||
var Album = require('../../src/output-website/album');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
describe('Album', function() {
|
||||
|
||||
it('sanitises album titles for the file name', function() {
|
||||
var a = new Album('hello & world');
|
||||
should(a.filename).eql('helloworld');
|
||||
});
|
||||
|
||||
describe('stats', function() {
|
||||
|
||||
describe('single level', function() {
|
||||
|
||||
it('has no nested albums', function() {
|
||||
var a = new Album('single');
|
||||
a.finalize();
|
||||
should(a.stats.albums).eql(0);
|
||||
})
|
||||
|
||||
it('calculates counts for a single level', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.photo(), fixtures.photo(),
|
||||
fixtures.photo(), fixtures.photo(),
|
||||
fixtures.video(), fixtures.video(),
|
||||
];
|
||||
a.finalize();
|
||||
should(a.stats.photos).eql(4);
|
||||
should(a.stats.videos).eql(2);
|
||||
});
|
||||
|
||||
it('calculates dates', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.photo({date: '2016-09-14'}),
|
||||
fixtures.photo({date: '2016-09-02'}),
|
||||
fixtures.photo({date: '2016-10-21'}),
|
||||
];
|
||||
a.finalize();
|
||||
should(a.stats.fromDate).eql(fixtures.date('2016-09-02'));
|
||||
should(a.stats.toDate).eql(fixtures.date('2016-10-21'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('nested albums', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('summary', function() {
|
||||
|
||||
it('creates a summary with a single photos', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.photo()
|
||||
];
|
||||
a.finalize();
|
||||
should(a.summary).eql('1 photo')
|
||||
});
|
||||
|
||||
it('creates a summary with a single video', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.video()
|
||||
];
|
||||
a.finalize();
|
||||
should(a.summary).eql('1 video')
|
||||
});
|
||||
|
||||
it('creates a summary with several photos', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.photo(), fixtures.photo(),
|
||||
];
|
||||
a.finalize();
|
||||
should(a.summary).eql('2 photos')
|
||||
});
|
||||
|
||||
it('creates a summary with several videos', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.video(), fixtures.video(),
|
||||
];
|
||||
a.finalize();
|
||||
should(a.summary).eql('2 videos')
|
||||
});
|
||||
|
||||
it('creates a summary with several photos and videos', function() {
|
||||
var a = new Album('single');
|
||||
a.files = [
|
||||
fixtures.photo(), fixtures.photo(),
|
||||
fixtures.video(), fixtures.video(),
|
||||
];
|
||||
a.finalize();
|
||||
should(a.summary).eql('2 photos, 2 videos')
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('previews', function() {
|
||||
|
||||
it('adds <missing> thumbnails to fill the 2x2 grid', function() {
|
||||
var a = new Album({files: [
|
||||
fixtures.photo(), fixtures.photo(),
|
||||
]});
|
||||
a.finalize();
|
||||
should(a.previews).have.length(4);
|
||||
should(a.previews[2].urls.thumb).eql('public/missing.png');
|
||||
should(a.previews[3].urls.thumb).eql('public/missing.png');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,44 @@
|
||||
var should = require('should/as-function');
|
||||
var Album = require('../../src/output-website/album.js');
|
||||
var bydate = require('../../src/output-website/by-date.js');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
describe('ByDate', function() {
|
||||
|
||||
describe('date format', function() {
|
||||
|
||||
it('formats a date as YYYY-MM', function() {
|
||||
should(bydate.format(fixtures.date('2016-06-13T16:43:19'))).eql('2016-06')
|
||||
});
|
||||
|
||||
it('formats based on the local timezone', function() {
|
||||
// TODO: why doesn't 23:59:59 work? Seems to be converted
|
||||
should(bydate.format(fixtures.date('1999-01-01T00:00:00'))).eql('1999-01')
|
||||
should(bydate.format(fixtures.date('1999-12-31T00:00:00'))).eql('1999-12')
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('creates albums by date', function () {
|
||||
// create files from different dates
|
||||
var june1 = fixtures.photo({path: 'some/IMG_000001.jpg', date: fixtures.date('2016-06-01')});
|
||||
var june2 = fixtures.photo({path: 'folders/IMG_000003.jpg', date: fixtures.date('2016-06-10')});
|
||||
var july1 = fixtures.photo({path: 'random/IMG_000002.jpg', date: fixtures.date('2016-07-23')});
|
||||
var july2 = fixtures.video({path: 'and/subfolders/IMG_000004.mp4', date: fixtures.date('2016-07-18')});
|
||||
// group them per month
|
||||
var collection = { files: [june1, june2, july1, july2] };
|
||||
var albums = bydate.albums(collection, {});
|
||||
// assert on the result
|
||||
should(albums).eql([
|
||||
new Album({
|
||||
'title': '2016-06',
|
||||
files: [june1, june2]
|
||||
}),
|
||||
new Album({
|
||||
title: '2016-07',
|
||||
files: [july1, july2]
|
||||
})
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,30 @@
|
||||
var should = require('should/as-function');
|
||||
var Album = require('../../src/output-website/album.js');
|
||||
var byfolder = require('../../src/output-website/by-folder.js');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
describe('ByFolder', function() {
|
||||
|
||||
it('creates albums by folders', function () {
|
||||
// create files in different folders
|
||||
var london1 = fixtures.photo({path: 'london/IMG_000001.jpg'});
|
||||
var london2 = fixtures.photo({path: 'london/IMG_000002.jpg'});
|
||||
var newyork1 = fixtures.photo({path: 'newyork/IMG_000003.jpg'});
|
||||
var newyork2 = fixtures.video({path: 'newyork/IMG_000004.mp4'});
|
||||
// group them per folder
|
||||
var collection = {files: [london1, london2, newyork1, newyork2]};
|
||||
var albums = byfolder.albums(collection, {});
|
||||
// assert on the result
|
||||
should(albums).eql([
|
||||
new Album({
|
||||
title: 'london',
|
||||
files: [london1, london2]
|
||||
}),
|
||||
new Album({
|
||||
title: 'newyork',
|
||||
files: [newyork1, newyork2]
|
||||
})
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue