# Photish Photish is a simple, convention based (but configurable) static photo site generator. Photish allows you to group your photo collections by folder. Metadata can be written alongside the photo in a [YAML](http://yaml.org/) file with the same name as the photo. Photish will crawl through your directory of photos and metadata, and render the information in your website templates. Photish supports all template engines implemented by [Tilt](https://github.com/rtomayko/tilt) (currently over 30 formats). It will also read your configuration and automatically convert your images to your configured size, dimensions, colourscheme, etc using [ImageMagick](http://www.imagemagick.org/) or [GraphicsMagick](http://www.graphicsmagick.org/). Using this information, Photish creates a complete static website that can be hosted on an [NGINX](http://nginx.org/), [Apache HTTP Server](https://httpd.apache.org/), or even on [Github Pages](https://pages.github.com/). Photish has been created with speed and efficiency in mind. Threads are used to parallelize image transcoding to achieve maximum utilization of your CPU during generation. A cache file is then used to ensure that unless the image has changed, it is not needlessly regenerated. This results in a responsive and fast local development environment, making it easy to perfect the design of your photo based website without having to wait for regeneration. ## Example [Photish Montage](https://foinq.com/photish-montage/index.html) - A quick mockup to show what can be done with Photish. [Source here](https://github.com/henrylawson/photish-montage). ## Getting Started It is strongly recommended to read through the [Installation](#installation) and [Usage](#usage) sections before seriously using Photish, however to get up and running: 1. Ensure [ImageMagick](http://www.imagemagick.org/) (or [GraphicsMagick](http://www.graphicsmagick.org/)) and [Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) are installed (see [Dependencies](#dependencies)) 1. Install Photish with `gem install photish` or with a [native installer](#installation) 1. Create a base project with `photish init --example` 1. Generate the HTML using `photish generate` 1. Run a local HTTP server to view the site with `photish host` 1. View your photo site at [http://localhost:9876](http://localhost:9876/) ## Project Health Category | Purpose | Badge ---------|---------|------ **Package** | RubyGem | [](https://badge.fury.io/rb/photish) | Debian | [](https://bintray.com/henrylawson/deb/photish/_latestVersion) | RPM | [](https://bintray.com/henrylawson/rpm/photish/_latestVersion) **CI/CD Pipeline** | Main Build, Package and Release | [](https://snap-ci.com/henrylawson/photish/branch/master) | JRuby & Rubinius Builds | [](https://travis-ci.org/henrylawson/photish) | Windows Build | [](https://ci.appveyor.com/project/HenryLawson/photish) **Code Quality** | Dependency Versions | [](https://gemnasium.com/henrylawson/photish) | Code Climate GPA | [](https://codeclimate.com/github/henrylawson/photish) | Test Coverage | [](https://codeclimate.com/github/henrylawson/photish/coverage) | Quality Metrics | [](https://codeclimate.com/github/henrylawson/photish/issues) # Documentation - [Overview](#overview) - [Latest Version](#latest-version) - [Installation](#installation) - [Dependencies](#dependencies) - [Ruby Gem](#ruby-gem) - [Debian Package](#debian-package) - [RPM Package](#rpm-package) - [Linux Binaries](#linux-binaries) - [Windows Binaries](#windows-binaries) - [Usage](#usage) - [Initialize](#initialize) - [Basic Photish Structure](#basic-photish-structure) - [Template Engines](#template-engines) - [Site Assets](#site-assets) - [Config File Options](#config-file-options) - [Customizing Templates](#customizing-templates) - [Layout Template](#layout-template) - [Collection Template](#collection-template) - [Album Template](#album-template) - [Photo Template](#photo-template) - [Template Helpers](#template-helpers) - [Custom Rendered Content](#custom-rendered-content) - [Gallery Page](#gallery-page) - [Asset Page](#asset-page) - [Generate](#generate) - [Execution Order](#execution-order) - [Image Conversion Tools](#image-conversion-tools) - [Workers and Threads](#workers-and-threads) - [Caching](#caching) - [Automatic Rengeneration](#automatic-regeneration) - [Forced Regeneration](#forced-regeneration) - [Crude Performance Measures](#crude-performance-measures) - [Host](#host) - [Deploy](#deploy) - [Rake Task](#rake-task) - [Plugins](#plugins) - [Template Helper Plugins](#template-helper-plugins) - [Deployment Engine Plugins](#deployment-engine-plugins) - [Plugin Loading](#plugin-loading) - [Development](#development) - [Code Changes](#code-changes) - [Services](#services) - [Contributing](#contributing) - [Versioning](#versioning) - [License](#license) ## Overview Photish turns this: ./my_new_photo_site ├── config.yml ├── photos │ ├── Big Dogs │ │ ├── Tired Dogs.jpg │ │ └── Winking Dog.jpg │ └── Small Dogs │ ├── Fluffy Dogs │ │ ├── Exhausted Dogs.jpg │ │ ├── Exhausted Dogs.yml │ │ ├── Many Dogs.jpg │ │ └── Many Dogs.yml │ ├── Sleepy Dog.jpg │ ├── Sleepy Dog.yml │ └── Squishy Dogs │ └── Big Ear Dog.jpg └── site ├── _templates │ ├── album.slim │ ├── collection.slim │ ├── layout.slim │ └── photo.slim ├── custom.html ├── images │ └── crumbs.gif └── styles └── basic.css Into this: ./my_new_photo_site └── output ├── big-dogs │ ├── index.html │ ├── tired-dogs │ │ ├── images │ │ │ ├── tired-dogs-low.jpg │ │ │ └── tired-dogs-original.jpg │ │ └── index.html │ └── winking-dog │ ├── images │ │ ├── winking-dog-low.jpg │ │ └── winking-dog-original.jpg │ └── index.html ├── custom.html ├── index.html ├── small-dogs │ ├── fluffy-dogs │ │ ├── exhausted-dogs │ │ │ ├── images │ │ │ │ ├── exhausted-dogs-low.jpg │ │ │ │ └── exhausted-dogs-original.jpg │ │ │ └── index.html │ │ ├── index.html │ │ └── many-dogs │ │ ├── images │ │ │ ├── many-dogs-low.jpg │ │ │ └── many-dogs-original.jpg │ │ └── index.html │ ├── index.html │ ├── sleepy-dog │ │ ├── images │ │ │ ├── sleepy-dog-low.jpg │ │ │ └── sleepy-dog-original.jpg │ │ └── index.html │ └── squishy-dogs │ ├── big-ear-dog │ │ ├── images │ │ │ ├── big-ear-dog-low.jpg │ │ │ └── big-ear-dog-original.jpg │ │ └── index.html │ └── index.html ├── images │ └── crumbs.gif └── styles └── basic.css A breakdown of the before and after is as follows: 1. For the **Collection** of photos in "Photos" an _index.html_ was created 1. For each **Album** (that is a folder in the "Photos" collection), an _index.html_ was created in a slugified sub folder 1. For each **Photo** (an image file in the album), another _index.html_ was created in a slugified sub folder named after the original photo 1. For each of these Photos, a version of the **Image** was made in both "low" and "original" quality in a sub folder called _images_ The number of Images and the quality of each is completely configurable. Using the templating language of your choice you can easily generate a Photo collection driven website with all of your photos available in various qualities and formats. ## Latest Version Photish follows [Semantic Versioning 2.0.0](http://semver.org/). Releases happen regularly and automatically from [Snap-CI](https://snap-ci.com/henrylawson/photish/branch/master). The [latest version](https://github.com/henrylawson/photish/releases/latest) is published with artifacts on GitHub. ## Installation Photish is available across all platforms as a [Ruby Gem](#ruby-gem). The recommended installation is the [Ruby Gem](#ruby-gem) as not all features are currently available on the platform native packages. For convenience Photish is also packaged in platform native installers. The platform native installers come with all the Ruby Gems and Ruby runtime bundled inside the package. This means you simply need to install the package and you can immediately use Photish without having to configure Ruby or any Gems, this is done using [Travelling Ruby](phusion.github.io/traveling-ruby/). Instructions are provided for each platform native installation: - [Debian Package](#debian-package) - [RPM Package](#rpm-package) - [Linux Binaries](#linux-binaries) - [Windows Binaries](#windows-binaries) ### Dependencies Photish has dependencies on certain software: - [ImageMagick](http://www.imagemagick.org/) or [GraphicsMagick](http://www.graphicsmagick.org/) for image conversion - [Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) for image metadata retrieval These packages are not listed as hard dependencies in any of the provided packages as it is only needed during runtime, and in the case of [Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/), if [Exif Metadata](https://en.wikipedia.org/wiki/Exchangeable_image_file_format) is not read during the generation of any templates, the dependency is not required. **On MacOSX, using [Brew](http://brew.sh/)** $ brew install imagemagick # or brew install graphicsmagick $ brew install exiftool **On Ubuntu or Debian** $ sudo apt-get install imagemagick # or sudo apt-get install graphicsmagick $ sudo apt-get install libimage-exiftool-perl **On CentOS, RedHat, etc.** $ sudo yum install ImageMagick $ sudo yum install perl-Image-ExifTool **On Windows** Please check the dependencies website for the latest Windows installation steps. ### Ruby Gem Photish supports multiple ruby versions: Ruby Version | Minimum | Maximum | Comments ----------------------------------------- |---------|---------|--------- [MRI Ruby](https://www.ruby-lang.org/en/) | 2.0 | HEAD | Very stable, all tests pass consistently [JRuby](http://jruby.org/) | 9.0 | HEAD | Mostly stable, smoke test passes consistently, full feature test flakey [Rubinius](http://rubinius.com/) | 2.0 | HEAD | Mostly stable, smoke test passes consistently, full feature test flakey The latest version and all releases of Photish are tested against the above ruby versions in the [CI pipeline](https://travis-ci.org/henrylawson/photish). Before installing Photish, ensure you have the latest version of [Bundler](http://bundler.io/) for your ruby version. Install the gem locally by running: $ gem install photish Alternatively, use [Bundler](http://bundler.io/). Create a folder for your photo site so you can track the version of Photish you are building with: $ mkdir my_new_photo_site $ cd my_new_photo_site $ bundle init $ echo 'gem "photish"' >> Gemfile $ bundle install ### Debian Package The latest Debian package for amd64 and i386 architectures is available on [Bintray](https://bintray.com/henrylawson/deb) and uploaded to the latest [Photish Github Release](https://github.com/henrylawson/photish/releases/latest). To be up to date with the latest version of Photish, we recommend you add our Debian repository and install using apt-get: $ # add the repository and SSH key $ echo "deb https://dl.bintray.com/henrylawson/deb all main" | sudo tee -a /etc/apt/sources.list $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F608A664B7DFFFEA $ $ # update keys and latest packages $ sudo apt-get update && sudo apt-key update $ $ # install photish $ sudo apt-get install photish If you have downloaded the *.deb file, simply install it with `dpkg`: $ sudo dpkg -i photish*.deb ### RPM Package The latest RPM package for x86_64 and i386 architectures is available on [Bintray](https://bintray.com/henrylawson/rpm) and uploaded to the latest [Photish Github Release](https://github.com/henrylawson/photish/releases/latest). To be up to date with the latest version of Photish, we recommend you add our YUM repository and install using yum: $ # add the repository and SSH key $ wget https://bintray.com/henrylawson/rpm/rpm -O bintray-henrylawson-rpm.repo $ sudo mv bintray-henrylawson-rpm.repo /etc/yum.repos.d/ $ $ # install photish $ sudo yum install -y photish If you have downloaded the *.rpm file, simply install it with `rpm`: $ sudo rpm -Uh photish*.rpm ### Linux Binaries If you are using a distribution of Linux that we do not have a native package installer for, you can manually install Photish and use it by downloading the Photish x64 and x86 binaries from the [Photish Github Release](https://github.com/henrylawson/photish/releases/latest). You can then extract the binaries to your desired location and use them. $ tar -zxf photish-*-linux-*.tar.gz -C /destination ### Windows Binaries If you are using Windows, you can manually install Photish and use it by downloading the Photish x86 binaries from the [Photish Github Release](https://github.com/henrylawson/photish/releases/latest). You can then extract the binaries to your desired location and use them. ## Usage Once you have photish installed. Get started with the following commands: ### Initialize A skeleton site can be created by running the below command inside the `my_new_photo_site` folder: $ photish init --example A barebones site can be created with: $ photish init #### Basic Photish Structure Inside your `my_new_photo_site` folder, you will have a: File or Folder | Purpose --------------------------------- | ------- `photos` | folder, for your photo collection and metadata `site` | folder for your templates, assets and static pages `site/_plugins` | folder for plugins to be loaded from `site/_templates` | folder for your templates `site/_templates/layout.slim` | file for the basic layout for all pages `site/_templates/collection.slim` | template file for your collection page `site/_templates/album.slim` | template file for your album page(s) `site/_templates/photo.slim` | template file for your photo page(s) `config.yml` | file to store all configuration in YAML format #### Template Engines By default Photish uses [Slim](http://slim-lang.com/) as the template language. The templates can be in any format supported by [Tilt](https://github.com/rtomayko/tilt). To use a different template language: 1. Create a `layout`, `collection`, `album` and `photo` file in the `site/_templates` folder, with the file extension of the template engine you prefer, supported extensions are documented by [Tilt](https://github.com/rtomayko/tilt) 1. Update `config.yml` to reference your newly created template files 1. Re write the basic template code in your chosen language #### Site Assets Any content not starting with an `_` (underscore) in the `site` folder will be copied to the `output` folder. In the example in the Overview section. There are a few static asset files. These are: 1. `site/styles/basic.css` 1. `site/images/crumbs.gif` 1. `site/custom.html` Both of these files were copied by Photish to the output folder, respecting their folder/file hierarchy: 1. `output/styles/basic.css` 1. `site/custom.html` As documented in the Generate section, assets are copied before the site content is generated. If an asset has a conflicting name and path with a generated file, the generated file will clobber the asset. #### Config File Options The default way to express config is in the `config.yml` file. However config can also be overridden using the `--config_override` flag to any of the Photish commands. When using the `--config_override` flag, the config must be expressed as [JSON](http://www.json.org/). For example, to override logging when calling the Generate command, you can use: $ photish generate --config_override='{"logging":{"colorize":false}}' This method of config override is only recommended for cases where the value needs to be temporarily overridden, such as during a deployment or while debugging. Below is a complete `config.yml` file, recommended practice is to only set the config values you need, otherwise just use the defaults, the file can be empty and Photish will still function: ```yaml port: 9876 qualities: - name: Original params: [] - name: Low params: ['-resize', '200x200'] templates: layout: layout.slim collection: collection.slim album: album.slim photo: photo.slim logging: colorize: true level: 'debug' output: ['stdout', 'file'] url: host: http://mydomain.com base: 'subdirectory' type: 'relative_uri' workers: 4 threads: 2 force: false plugins: ['ssh_deploy', 'other_plugin'] image_extensions: ['jpg', 'gif'] page_extension: 'slim' dependencies: minimagick: cli: 'imagemagick' cli_path: '/usr/bin/convert' timeout: 3600 miniexiftool: command: '/usr/bin/' ``` The meanings and purpose of each field is defined below: Field | Purpose ---------------------- | ------- `port` | the port number that the `photish host` command will bind to, default is `9876` `qualities` | an array of `name` and `params` fields for **Images** `qualities[]/name` | the name of the **Image** quality `qualities[]/params` | the parameters to be provided to the ImageMagick or GraphicsMagick `convert` utility for the **Image** file quality `templates` | a listing of the various template files `templates/layout` | the layout template file in the `site/_templates` folder, must be overridden if using a different template engine `templates/collection` | the collection template file in the `site/_templates` folder, must be overridden if using a different template engine `templates/album` | the album template file in the `site/_templates` folder, must be overridden if using a different template engine `templates/photo` | the photo template file in the `site/_templates` folder, must be overridden if using a different template engine `logging` | a listing of the various logging options `logging/colorize` | when outputting to `STDOUT`, `true` to use color, `false` for none `logging/level` | the default logging level, it is advised to keep this at `debug`, supported are `debug`, `info`, `warn`, `error` and `fatal` `logging/output` | the appenders for the logger, `stdout` goes to `STDOUT`, `file` goes to `log/photish.log` `url` | a listing of the various url options `url/host` | if you would like URLs generated with a specific host prefix, you can define it here, otherwise leave it as '/' or do not set this configuration at all `url/base` | if your website will be hosted in a sub folder and will not be accessible at the root of the host, you can specify the sub folder(s) here, this will also mean your website will be hosted in a sub folder when ran using `photish host` `url/type` | if your website URLs require the host name in them, you can use `absolute_uri` (i.e. http://mysite.com/subdirectory/index.html), if you would prefer to generate URLs that end at the root, you can use `absolute_relative` (i.e. /subdirectory/index.html) `workers` | the number of workers to create, for computers with multiple processors, photish is configured by default to spawn a worker for each process, a worker is responsible for image generation and html generation, load balancing is done randomly via a simple round robin allocation `threads` | the number of threads each worker should create to handle image magick transcoding `force` | this should always be false, if true, all content will be regenerated and nothing cached `plugins` | an array of plugin names that have been included in your Gemfile and that Photish should require into it's runtime `image_extensions` | by default, Photish has a complete list of image extensions, however if you choose too, you can explicitly list the extensions that Photish should use to find images `page_extension` | the extension of **Pages** files that will live amongst the photo collection `dependencies` | this section is for the configuration of third party tools `dependencies/minimagick` | configuration for [minimagick](https://github.com/minimagick/minimagick), the wrapping library around [ImageMagick](http://www.imagemagick.org/) or [GraphicsMagick](http://www.graphicsmagick.org/) `dependencies/minimagick/cli` | provide `imagemagick`, or `graphicsmagick` depending on your chosen library `dependencies/minimagick/cli_path` | if the above executables are not in your PATH, you can provide the location explicitly here `dependencies/minimagick/timeout` | terminate a command after the provided number of seconds `dependencies/miniexiftool` | configuration for [mini_exiftool](https://github.com/janfri/mini_exiftool), the wrapping library around [Exif Tool](http://www.sno.phy.queensu.ca/~phil/exiftool/) `dependencies/miniexiftool/command` | if exiftool is not in your PATH, you can provide the location explicitly here #### Customizing Templates Below is the documentation for the various data available inside each of the templates. **Note:** `{type}` is a place holder depending on your chosen template engine the file extension will change. By default the template engine is [Slim](http://slim-lang.com/), so templates will end with the _slim_ extension. ##### Layout Template `site/_templates/layout.{type}` Example: ```slim doctype html html head title Master Layout body == yield ``` The layout template is the base layout for all the other templates. The `collection`, `album` and `photo` templates will be rendered inside this layout. The layout template **must** include the `yield` statement to bind the sub template inside it. Below is an example [Slim](http://slim-lang.com/) template, the other templates will be bound where the `yield` statement is: ##### Collection Template `site/_templates/collection.{type}` Example: ```slim h1 Photo Collection - albums.each do |album| div.album div.album-title a href=album.url | #{album.name} ``` The collection template becomes the `index.html` for the root of the website. This template is passed the [Collection](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/collection.rb) model when rendered. Attribute or Method | Description ------------------- | ----------- url | the URL of this page metadata | an object with methods for the attributes in the `photos.yml` file albums | an array of child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) within this folder all_albums | an array of all child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) all_photos | an array of all child [Photos](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb) all_images | an array of all child [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb) all_pages | an array of all child [Pages](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/page.rb) ##### Album Template `site/_templates/album.{type}` Example: ```slim h1 Album h2 a href=url | #{name} div.album-photos - photos.each do |photo| div.album-photo a href=photo.url title=photo.name img src=photo.images.find{ |i|i.quality_name=='Low' }.url alt=photo.name ``` For each folder in the `photos` directory, a slugified album folder is created with an `index.html` in it. This template is passed the [Album](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) model when rendered. Attribute or Method | Description ------------------- | ----------- name | the name of the folder, i.e. `photos/My album/` will become `My album` url | the URL of this page metadata | an object with methods for the attributes in the `{album_name}.yml` file stored at the same level as the album albums | an array of child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) within this folder all_albums | an array of all child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) all_photos | an array of all child [Photos](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb) all_images | an array of all child [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb) all_pages | an array of all child [Pages](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/page.rb) ##### Photo Template `site/_templates/photo.{type}` Example: ```slim h1 Photo h2 a href=url | #{name} div.album-photos - images.each do |image| div.album-photo a href=image.url title=image.name img src=image.url alt=image.quality_name ``` For each image in an Albums directory, a slugified photo folder is created with an `index.html` in it. This template is passed the [Photo](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb) model when rendered. Attribute or Method | Description ------------------- | ----------- name | the name of the photo, i.e. `photos/My album/My dog.jpg` will become `My dog` url | the URL of this page metadata | an object with methods for the attributes in the `{photo_name}.yml` file stored at the same level as the photo exif | an object with methods for the exif data of the original photo file images | an array of all the [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb) for this photo, an Image will be a version of the photo in the quality configured in `config.yml` #### Template Helpers A template helper is a simple method that is available in the template that can be called to render complex information. For example in a template, the method `breadcrumbs` can be called: ```slim div.content div.site-breadcrumbs == breadcrumbs ``` When rendered this will result in an unordered list of pages above the current page in the hierarchy: ```html