A4YDN3ZM5CNM43BMK4BAEB6I2GVQQZUKBCZYMYCRVZSS6EXRY3VAC
}
#albums .page-teaser,
#container .page-teaser{
position: relative;
height:620px;
width:100%;
background-color: @body-background;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
background-size: cover;
margin-bottom: 0;
text-transform: uppercase;
color: @headertitle;
}
#container .page-teaser{
border:20px solid @body-background;
.page-teaser h2{
margin: 1.6em 1em 1.6em 1em;
font-size: 3.0em;
color:@headertitle;
font-weight: 600;
text-shadow: 0px 2px 3px #555;
}
.page-teaser h3{
font-size: 2.0em;
margin: 0 1em 0 1em;
color:@headertitle;
font-weight: 600;
text-transform: none;
}
.page-teaser .page-teaser-desc{
position: relative;
margin-top:150px;
color: @headertitle;
font-size: 1.2em;
line-height: 1.5em;
}
.page-teaser .avatar-small{
position:relative;
object-fit: cover;
border-radius:50%;
width: 50px;
height: 50px;
}
#albums .page-teaser,
#container .page-teaser{
position: relative;
height:620px;
width:100%;
background-color: @body-background;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
background-size: cover;
margin-bottom: 0;
text-transform: uppercase;
color: @headertitle;
}
#container .page-teaser{
border-width: 0 20px 36px 20px;
border-style: solid;
border-color: @body-background;
}
.page-teaser h2{
margin: 1.6em 1em 1.6em 1em;
font-size: 3.0em;
color:@headertitle;
font-weight: 600;
text-shadow: 0px 2px 3px #555;
}
.page-teaser h3{
font-size: 2.0em;
margin: 0 1em 0 1em;
color:@headertitle;
font-weight: 600;
text-transform: none;
}
.page-teaser .page-teaser-desc{
position: relative;
margin-top:120px;
color: @headertitle;
font-size: 1.2em;
line-height: 1.5em;
}
.page-teaser .avatar-small{
position:relative;
object-fit: cover;
border-radius:50%;
width: 50px;
height: 50px;
}
.page-teaser a.cover-link{
color: @cardcolor;
font-size: 1.0em;
text-decoration: none;
display:inline-block;
line-height: 3em;
text-transform: lowercase;
}
.page-teaser a.cover-link:hover{
color: @fontcolor;
}
{{!--
TODO:// better handling for meta descripton for the gallery ??
data.gallery.headline
data.gallery.teaserImage
data.gallery.description
data.gallery.autorAvatar
data.gallery.autorName
--}}
{{#compare album.depth '==' 0}}
<div style="height:24px;">
{{!-- homepage add additonal infos here --}}
</div>
{{/compare}}
{{#compare album.depth '!=' 0}}
<h2 class="gallerytitle"> {{albumname album.title}}</h2>
<div>
{{!-- nested album - add the description here --}}
</div>
{{/compare}}
{{!--
TODO:// better handling for meta descripton for the album ??
data.album.headline
data.album.teaserImage
data.album.description
data.album.autorAvatar
data.album.autorName
data.album.link
--}}
<div class="page-teaser" style="background-image: url('{{relative album.files.[0].urls.large}}')">
<h2>{{album.title}}</h2>
<h3>{{albuminfo album}}</h3>
<div class="page-teaser-desc">
<img src="public/assets/avatar.jpg" class="avatar-small"></img>
<p>Peter Siebler<br>Album: {{album.summary}}</p>
</div>
</div>
{{!--
Image/Video thumbnails
how to trim meta.caption ??
--}}
<div class="albumList"
data-sub-html="{{meta.caption_notused}}"
data-download-url="{{relative urls.download}}"
{{~#if isVideo~}}
data-html="#media{{id}}"
{{~else~}}
data-src="{{relative urls.large}}"
{{~/if~}}
data-exthumbimage="{{relative urls.thumbnail}}"
data-filename="{{filename}}"
{{#if meta.exif}}
data-datetimeoriginal="{{meta.exif.DateTimeOriginal}}"
data-fnumber="{{meta.exif.FNumber}}"
data-exposuretime="{{meta.exif.ExposureTime}}"
data-isospeedratings="{{meta.exif.ISO}}"
data-focallength="{{meta.exif.FocalLength}}"
data-lens="{{meta.exif.Lens}}"
data-model="{{meta.exif.Model}}"
data-make="{{meta.exif.Make}}"
data-gpslatitude="{{meta.exif.GPSLatitude}}"
data-gpslongitude="{{meta.exif.GPSLongitude}}"
data-gpslatituderef="{{meta.exif.GPSLatitudeRef}}"
data-gpslongituderef="{{meta.exif.GPSLongitudeRef}}"
data-gpsaltitude="{{meta.exif.GPSAltitude}}"
{{/if}}>
{{!-- Image or Video thumbnail --}}
{{~#if isVideo~}}
<a href="{{relative urls.download}}">
{{~else~}}
<a href="{{relative urls.large}}">
{{~/if~}}
<img src="{{relative urls.small}}" alt="{{#if meta.exif}} {{{meta.exif.DateTimeOriginal}}} {{else}} {{{meta.date}}} {{/if}}" />
<span class="show-gallery icon-zoom-in"></span>
</a>
{{#compare meta.animated "||" isVideo}}
<div class="video-overlay">
<img src="{{relative 'public/play.png'}}" />
</div>
{{/compare}}
</div>
{{!-- All photos and videos --}}
{{#compare album.files.length '>' 1}}
{{#if album.files}}
{{!-- render album description if we can find a ImageDescription --}}
{{#if album.files.0.meta.exif.ImageDescription.length }}
{{> coverItem}}
{{/if}}
{{!-- all fotos for this album as justified gallery fotos --}}
<div id="media" class="clearfix justified-gallery">
{{#each album.files~}}
{{#if album.files.0.meta.exif.ImageDescription.length }}
{{!-- skip the cover image file --}}
{{~else~}}
<div class="albumList"
data-sub-html="{{meta.caption_notused}}"
data-download-url="{{relative urls.download}}"
{{~#if isVideo~}}
data-html="#media{{id}}"
{{~else~}}
data-src="{{relative urls.large}}"
{{~/if~}}
data-exthumbimage="{{relative urls.thumbnail}}"
data-filename="{{filename}}"
{{#if meta.exif}}
data-datetimeoriginal="{{meta.exif.DateTimeOriginal}}"
data-fnumber="{{meta.exif.FNumber}}"
data-exposuretime="{{meta.exif.ExposureTime}}"
data-isospeedratings="{{meta.exif.ISO}}"
data-focallength="{{meta.exif.FocalLength}}"
data-lens="{{meta.exif.Lens}}"
data-model="{{meta.exif.Model}}"
data-make="{{meta.exif.Make}}"
data-gpslatitude="{{meta.exif.GPSLatitude}}"
data-gpslongitude="{{meta.exif.GPSLongitude}}"
data-gpslatituderef="{{meta.exif.GPSLatitudeRef}}"
data-gpslongituderef="{{meta.exif.GPSLongitudeRef}}"
data-gpsaltitude="{{meta.exif.GPSAltitude}}"
{{/if}}>
{{!-- Image or Video thumbnail --}}
{{~#if isVideo~}}
<a href="{{relative urls.download}}">
{{~else~}}
<a href="{{relative urls.large}}">
{{~/if~}}
<img src="{{relative urls.small}}" alt="{{#if meta.exif}} {{{meta.exif.DateTimeOriginal}}} {{else}} {{{meta.date}}} {{/if}}" />
<span class="show-gallery icon-zoom-in"></span>
</a>
{{#compare meta.animated "||" isVideo}}
<div class="video-overlay">
<img src="{{relative 'public/play.png'}}" />
</div>
{{/compare}}
</div>
{{/if}}
{{~/each}}
</div>
{{/if}}
{{/compare}}
{{!-- Optional footer --}}
{{#if gallery.footer}}
<footer><p>{{{gallery.footer}}}</p></footer>
{{/if}}
<div style="height:20px;"></div>
{{!-- check if we can find images --}}
{{#compare album.files.length '==' 1}}
{{!-- check if the first image is a cover images --}}
{{#if album.files.0.meta.exif.ImageDescription.length }}
<div class="page-teaser" style="background-image: url('{{relative album.files.[0].urls.large}}')">
<h2>{{albumname album.title}}</h2>
<h3>{{album.files.0.meta.exif.ImageDescription}}</h3>
{{#if album.files.0.meta.exif.DocumentName.length }}
<a class="cover-link icon-external-link" href="{{album.files.0.meta.exif.DocumentName}}"> {{album.files.0.meta.exif.DocumentName}}</a>
{{/if}}
<div class="page-teaser-desc">
<img src="public/assets/{{album.files.0.meta.exif.Copyright}}" class="avatar-small"></img>
<p>{{album.files.0.meta.exif.Artist}}<br>{{album.summary}}</p>
</div>
</div>
{{/if}}
{{/compare}}
{{!-- Nested albums, if any --}}
{{#if album.albums}}
{{!-- include the gallery description --}}
{{> galleryDescription}}
<div id="albums" class="cards clearfix">
{{#each album.albums~}}
{{#if @first}}
{{/if}}
{{!-- album teaser --}}
<a href="{{relative url}}" class="card">
<div class="card-photo" style="background-image: url('{{relative previews.0.urls.large}}')"></div>
<div class="card-info">
<h3>{{title}}</h3>
<div class="summary">{{summary}}</div>
<div class="date">{{{date stats.fromDate}}} - {{{date stats.toDate}}}</div>
</div>
</a>
{{~/each}}
</div>
{{/if}}
{{!-- All photos and videos --}}
{{#if album.files}}
{{!-- include the album description --}}
{{> albumDescription}}
{{!-- all fotos for this album as justified gallery fotos --}}
<div id="media" class="clearfix justified-gallery">
{{#each album.files~}}
{{#if @first}}
{{~else~}}
{{> thumbnail}}
{{/if}}
{{~/each}}
</div>
{{/if}}
{{!-- Optional footer --}}
{{#if gallery.footer}}
<footer>
<p>{{{gallery.footer}}}</p>
</footer>
{{/if}}
{{> ablumTeaser}}
{{> mediaItems}}
{{> footer}}
{{!--
Analytics script
register the analytics lib here
--}}
{{#if album.albums}}
{{!-- include the album description as cover item --}}
{{> coverItem}}
{{!-- render all album teaser--}}
<div id="albums" class="cards clearfix">
{{#each album.albums~}}
<a href="{{relative url}}" class="card">
<div class="card-photo" style="background-image: url('{{relative previews.0.urls.large}}')"></div>
<div class="card-info">
<h3>{{title}}</h3>
<div class="summary">{{summary}}</div>
<div class="date">{{{date stats.fromDate}}} - {{{date stats.toDate}}}</div>
</div>
</a>
{{~/each}}
</div>
{{/if}}
Used as a replacement for the album config setting. Not perfect but currently the only workaround.
Used as a replacement for the album config setting. Not perfect but currently the only workaround.
* **Gallery- and Mediaitem Teaser**
the first mediaitem (foto) is used to render the gallery- or album cover teaser.
if the exif auto properties is set, the cover teaser will be rendered.
```
{{!-- cover teaser for the home page --}}
{{#compare album.depth '==' 0}}
{{#compare album.files.length '==' 1}}
<pre>
Headline: {{gallery.title}}
Autor: {{album.files.0.meta.exif.Artist}}
Avatar: {{album.files.0.meta.exif.Copyright}}
Description: {{album.files.0.meta.exif.ImageDescription}}
Link: {{album.files.0.meta.exif.DocumentName}}
</pre>
{{/compare}}
{{/compare}}
```
// {{{albumsDescription album}}}
"use strict";
const path = require('path')
const map = {
'1985 Rom': 'Unser erster Kurzurlaub, Rom die ewige Stadt.',
'1988 Bahamas': 'Reise nach New York, New Jersey und dann ein paar Tage auf die Bahamas',
'2000 Kalabrien': 'Erste Flugreise mit der Familie nach Italien',
'2001 Amateurfunk': 'Einige Erinnerungen an die Amateurfunkzeit',
'2001 Florida': 'Hochzeitsreise nach Florida, Ausflüge und Badeurlaub in Miami Beach.',
'2001 Ascona': 'Unser erster Urlaub im Tessin, im Schloss...',
'Ascona': 'Unser erster Urlaub im Tessin, im Schloss...',
'2001 Tunesien': '',
'2003 Ägypthen Hurgada': '',
'2004 Ägypten Sharm el Sheikh': '',
'2006 Alicante': '',
'2006 Griechenland': '',
'2007 Mallorca': '',
'2009 Ägypten Sharm El Sheikh': '',
'2009 Bikes': '',
'2009 Griechenland': '',
'2010 Alicante': '',
'2010 Haus Garten': '',
'2011 Mallorca': '',
'2012 Dubai': '',
'2013 England': '',
'2013 Haus PV-Anlage': '',
'2014 Spanien': '',
'2014 Thailand': '',
'2015 Festtage': '',
'2015 Haus FitnessRaum': '',
'2015 Kambodscha': '',
'2015 Kuba': '',
'2015 Thailand': '',
'2016 Bulgarien Goldstrand': 'Hotel Grifid Metropol',
'2016 Indien': '',
'2017 Thailand': '',
'2018 Bali': '',
'2018 Gran Canaria': '',
'2018 Mallorca': '',
'2019 Thailand': ''
}
module.exports = album => {
const name = map[album.title];
return name ? [name] : [''];
}
/*
* get the additional albumdata
* {{albumdata album}}
*/
"use strict";
var data = {};
module.exports = albumdata => {
data.name = albumdata.title;
data.foto = '';
data.description = "Reise nach New York, New Jersey und dann ein paar Tage auf die Bahamas";
data.summary = albumdata.summary;
return data;
}
/*
* check album name
*/
"use strict";
module.exports = name => {
return (name == 'Home') ? 'Fotobuch' : name;
}
#!/bin/bash
# -----------------------------
# call ./setcover.sh cover.jpg
# -----------------------------
fileName=$1
echo $fileName
AUTOR="Peter Siebler"
AVATAR="avatar.jpg"
DESCRIPTION="Unser erste Thailandurlaub"
LINK="https://www.siebler.at"
exiftool -Artist="$AUTOR" -Copyright="$AVATAR" -ImageDescription="$DESCRIPTION" -DocumentName="$LINK" $fileName
- check the helpers files to handle the album description
- OPTIONAL
- add cover images for the gallery and albums
- add EXIF Data (Artist, Copyright, ImageDescription, DocumentName) to the cover image
- Update the avatar images (see public/assets/avatar*.*)
- Update the header backimage (see public/assets/header.jpg)
## Opentask:
I'm still looking for a way to read in a json file in the application and the settings contained therein as a global object, so that they can be used in the templates.
Special case is the album, in this case the current album (basename) should be handed over at the call to find the corresponding data in the list.
see: "sample for gallerydata.json"
1. load gallery settings from file. see galleryDescription.hbs
* Autor name
* Gallery Description
* ... more
2. load album settings from file. see albumDescription.hbs
* Teaser Image / Album Image
* description
* autor
* ... addional informations
```
## Cover Text & Image
- For this application, the first photo is checked if the EXIF data (Artist, Copyright, ImageDescription, DocumentName) is set there.
If these are present, then the cover teaser is displayed.
- If the ImageDescription is empty, no Cover Background Image will be displayed.
- if ... a simpe cover w/o a background image will be displayed.
### **Folder Structur**
```
folder fotos
cover.img
+ Album 1
cover.img
foto1.img
foto2.img
+ Ablum 1.1
cover.img
foto1.img
foto2.img
+ Ablum 2
Album 2.1
cover.img
foto1.img
foto2.img
Album 2.2
cover.img
foto1.img
foto2.img
+ Ablum 3
foto1.img
foto2.img
{
"gallery": {
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"headline": "Fotobuch",
"teaserImage": "public/assets/gallery/mygallery.jpg",
"autorName": "Name autor",
"autorAvatar": "avatar1.png"
},
"album": [
{
"basename": "Album 1",
"headline": "Travel Asia",
"autor": "Name autor",
"autorAvatar": "avatar1.png",
"teaserImage": "public/assets/albums/album1.jpg",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"link": null
},
{
"basename": "Album 2",
"headline": "Travel Europa",
"autor": "Name autor2",
"autorAvatar": "avatar2.png",
"teaserImage": "public/assets/albums/album2.jpg",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"link": null
}
]
}
AUTOR="AUTOR NAME"
AVATAR="avatar.jpg"
DESCRIPTION="Lorem Ipsum is simply dummy text of the printing and typesetting industry."
LINK="URL"
exiftool -Artist="$AUTOR" -Copyright="$AVATAR" -ImageDescription="$DESCRIPTION" -DocumentName="$LINK" $fileName