{"id":13696114,"url":"https://github.com/pelican-plugins/photos","last_synced_at":"2025-10-07T03:19:47.816Z","repository":{"id":38025088,"uuid":"393871103","full_name":"pelican-plugins/photos","owner":"pelican-plugins","description":"Pelican plugin that adds photos to articles","archived":false,"fork":false,"pushed_at":"2025-02-07T21:10:03.000Z","size":759,"stargazers_count":29,"open_issues_count":6,"forks_count":17,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-24T06:59:54.222Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pelican-plugins.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://donate.getpelican.com","liberapay":"pelican"}},"created_at":"2021-08-08T05:50:44.000Z","updated_at":"2025-05-21T04:31:06.000Z","dependencies_parsed_at":"2024-03-15T20:49:15.341Z","dependency_job_id":"bf45e53f-67d2-4aff-8a16-7cb1e344b2ba","html_url":"https://github.com/pelican-plugins/photos","commit_stats":{"total_commits":207,"total_committers":25,"mean_commits":8.28,"dds":0.5024154589371981,"last_synced_commit":"24fbe6cf79e2c25eead3361d1a29dbf14a77bf39"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/pelican-plugins/photos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fphotos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fphotos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fphotos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fphotos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pelican-plugins","download_url":"https://codeload.github.com/pelican-plugins/photos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fphotos/sbom","scorecard":{"id":726825,"data":{"date":"2025-08-11","repo":{"name":"github.com/pelican-plugins/photos","commit":"524208c4a5796f65026c7a593648029fe7995b70"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":1,"reason":"Found 3/21 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/main.yml:68","Info: topLevel 'contents' permission set to 'read': .github/workflows/main.yml:9"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:98: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/photos/main.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:82","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:83","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.6.2 not signed: https://api.github.com/repos/pelican-plugins/photos/releases/199136015","Warn: release artifact 1.6.1 not signed: https://api.github.com/repos/pelican-plugins/photos/releases/197671821","Warn: release artifact 1.6.0 not signed: https://api.github.com/repos/pelican-plugins/photos/releases/146919586","Warn: release artifact 1.5.0 not signed: https://api.github.com/repos/pelican-plugins/photos/releases/127253373","Warn: release artifact 1.4.0 not signed: https://api.github.com/repos/pelican-plugins/photos/releases/76632298","Warn: release artifact 1.6.2 does not have provenance: https://api.github.com/repos/pelican-plugins/photos/releases/199136015","Warn: release artifact 1.6.1 does not have provenance: https://api.github.com/repos/pelican-plugins/photos/releases/197671821","Warn: release artifact 1.6.0 does not have provenance: https://api.github.com/repos/pelican-plugins/photos/releases/146919586","Warn: release artifact 1.5.0 does not have provenance: https://api.github.com/repos/pelican-plugins/photos/releases/127253373","Warn: release artifact 1.4.0 does not have provenance: https://api.github.com/repos/pelican-plugins/photos/releases/76632298"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/main.yml:60"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"53 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3c5c-7235-994j","Warn: Project is vulnerable to: GHSA-3f63-hfp8-52jq","Warn: Project is vulnerable to: PYSEC-2021-41 / GHSA-3wvg-mj6g-m9cv","Warn: Project is vulnerable to: PYSEC-2020-77 / GHSA-3xv8-3j54-hgrp","Warn: Project is vulnerable to: PYSEC-2020-80 / GHSA-43fq-w8qq-v88h","Warn: Project is vulnerable to: GHSA-44wm-f244-xhp3","Warn: Project is vulnerable to: GHSA-4fx9-vc88-q2xc","Warn: Project is vulnerable to: PYSEC-2021-35 / GHSA-57h3-9rgr-c24m","Warn: Project is vulnerable to: PYSEC-2020-172 / GHSA-5gm3-px64-rw72","Warn: Project is vulnerable to: PYSEC-2021-331 / GHSA-7534-mm45-c74v","Warn: Project is vulnerable to: PYSEC-2021-92 / GHSA-7r7m-5h27-29hp","Warn: Project is vulnerable to: PYSEC-2020-78 / GHSA-8843-m7mw-mxqm","Warn: Project is vulnerable to: PYSEC-2023-227 / GHSA-8ghj-p4vj-mr35","Warn: Project is vulnerable to: PYSEC-2014-87 / GHSA-8m9x-pxwq-j236","Warn: Project is vulnerable to: PYSEC-2022-10 / GHSA-8vj2-vxx3-667w","Warn: Project is vulnerable to: PYSEC-2021-36 / GHSA-8xjq-8fcg-g5hw","Warn: Project is vulnerable to: PYSEC-2016-6 / GHSA-8xjv-v9xq-m5h9","Warn: Project is vulnerable to: PYSEC-2021-42 / GHSA-95q3-8gr9-gm8w","Warn: Project is vulnerable to: PYSEC-2022-168 / GHSA-9j59-75qj-795w","Warn: Project is vulnerable to: PYSEC-2014-10 / GHSA-cfmr-38g9-f2h7","Warn: Project is vulnerable to: PYSEC-2020-76 / GHSA-cqhg-xjhh-p8hf","Warn: Project is vulnerable to: PYSEC-2021-40 / GHSA-f4w8-cv6p-x6r5","Warn: Project is vulnerable to: PYSEC-2021-69 / GHSA-f5g8-5qq7-938w","Warn: Project is vulnerable to: PYSEC-2021-139 / GHSA-g6rj-rv7j-xwp4","Warn: Project is vulnerable to: PYSEC-2015-16 / GHSA-h5rf-vgqx-wjv2","Warn: Project is vulnerable to: PYSEC-2016-5 / GHSA-hggx-3h72-49ww","Warn: Project is vulnerable to: PYSEC-2020-84 / GHSA-hj69-c76v-86wr","Warn: Project is vulnerable to: PYSEC-2016-7 / GHSA-hvr8-466p-75rh","Warn: Project is vulnerable to: PYSEC-2015-15 / GHSA-j6f7-g425-4gmx","Warn: Project is vulnerable to: GHSA-j7hp-h8jx-5ppr","Warn: Project is vulnerable to: PYSEC-2019-110 / GHSA-j7mj-748x-7p78","Warn: Project is vulnerable to: GHSA-jgpv-4h4c-xhw3","Warn: Project is vulnerable to: PYSEC-2022-42979 / GHSA-m2vv-5vj5-2hm7","Warn: Project is vulnerable to: PYSEC-2021-37 / GHSA-mvg9-xffr-p774","Warn: Project is vulnerable to: PYSEC-2020-83 / GHSA-p49h-hjvm-jg3h","Warn: Project is vulnerable to: PYSEC-2022-8 / GHSA-pw3c-h7wp-cvhx","Warn: Project is vulnerable to: PYSEC-2021-93 / GHSA-q5hq-fp76-qmrc","Warn: Project is vulnerable to: PYSEC-2020-82 / GHSA-r7rm-8j6h-r933","Warn: Project is vulnerable to: PYSEC-2014-23 / GHSA-r854-96gq-rfg3","Warn: Project is vulnerable to: PYSEC-2016-8 / GHSA-rwr3-c2q8-gm56","Warn: Project is vulnerable to: PYSEC-2020-81 / GHSA-vcqg-3p29-xw73","Warn: Project is vulnerable to: PYSEC-2020-79 / GHSA-vj42-xq3r-hr3r","Warn: Project is vulnerable to: PYSEC-2021-70 / GHSA-vqcj-wrf2-7v73","Warn: Project is vulnerable to: PYSEC-2016-9 / GHSA-w4vg-rf63-f3j3","Warn: Project is vulnerable to: PYSEC-2014-22 / GHSA-x895-2wrm-hvp7","Warn: Project is vulnerable to: PYSEC-2022-9 / GHSA-xrcv-f9gm-v42c","Warn: Project is vulnerable to: PYSEC-2021-137","Warn: Project is vulnerable to: PYSEC-2021-138","Warn: Project is vulnerable to: PYSEC-2021-317","Warn: Project is vulnerable to: PYSEC-2021-38","Warn: Project is vulnerable to: PYSEC-2021-39","Warn: Project is vulnerable to: PYSEC-2021-94","Warn: Project is vulnerable to: PYSEC-2023-175"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T13:04:09.573Z","repository_id":38025088,"created_at":"2025-08-22T13:04:09.574Z","updated_at":"2025-08-22T13:04:09.574Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278713685,"owners_count":26032941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T18:00:36.393Z","updated_at":"2025-10-07T03:19:47.787Z","avatar_url":"https://github.com/pelican-plugins.png","language":"Python","funding_links":["https://donate.getpelican.com","https://liberapay.com/pelican"],"categories":["Plugins"],"sub_categories":["Migrated to new architecture"],"readme":"Photos: A Plugin for Pelican\n============================\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/pelican-plugins/photos/main.yml?branch=main)](https://github.com/pelican-plugins/photos/actions)\n[![PyPI Version](https://img.shields.io/pypi/v/pelican-photos)](https://pypi.org/project/pelican-photos/)\n![License](https://img.shields.io/pypi/l/pelican-photos?color=blue)\n\nUse Photos to add a photo or a gallery of photos to an article, or to include photos in the body text. Photos are kept separately, as an organized library of high resolution photos, and resized as needed.\n\nInstallation\n------------\n\nThis plugin can be installed via:\n\n    python -m pip install pelican-photos\n\nThe plug-in requires `Pillow`: the Python Imaging Library and optionally `Piexif`, whose installation are outside the scope of this document.\n\nUsage\n-----\n\nThe plug-in resizes the referred photos, and generates thumbnails for galleries and associated photos, based on the following configuration and default values:\n\n`PHOTO_LIBRARY = \"~/Pictures\"`\n:\tAbsolute path to the folder where the original photos are kept, organized in sub-folders.\n\n`PHOTO_GALLERY = (1024, 768, 80)`\n:\tFor photos in galleries, maximum width and height, plus JPEG quality as a percentage. This would typically be the size of the photo displayed when the reader clicks a thumbnail.\n\n`PHOTO_ARTICLE = (760, 506, 80)`\n:\tFor photos associated with articles, maximum width, height, and quality. The maximum size would typically depend on the needs of the theme. 760px is suitable for the theme `notmyidea`.\n\n`PHOTO_THUMB = (192, 144, 60)`\n:\tFor thumbnails, maximum width, height, and quality.\n\n`PHOTO_SQUARE_THUMB = False`\n:\tCrops thumbnails to make them square.\n\n`PHOTO_RESIZE_JOBS = 5`\n: Number of parallel resize jobs to be run. Defaults to 1.\n\n- `-1` = Do not use the Python multiprocessing module and enable additional debugging\n- `0` = Try to detect cpu count and start `CPU_COUNT + 1` processes\n- `1` = Use 1 process\n- `2` = Use 2 processes\n- `3` = Use 3 processes\n- ...\n\n`PHOTO_WATERMARK = True`\n: Adds a watermark to all photos in articles and pages. Defaults to using your site name.\n\n`PHOTO_WATERMARK_TEXT' = SITENAME`\n: Allow the user to change the watermark text or remove it completely. By default it uses [SourceCodePro-Bold](https://github.com/adobe-fonts/source-code-pro) as the font.\n\n`PHOTO_WATERMARK_IMG = ''`\n: Allows the user to add an image in addition to or as the only watermark. Set the variable to the location.\n\n**The following features require the piexif library**\n`PHOTO_EXIF_KEEP = True`\n: Keeps the exif of the input photo.\n\n`PHOTO_EXIF_REMOVE_GPS = True`\n: Removes any GPS information from the files exif data.\n\n`PHOTO_EXIF_COPYRIGHT = 'COPYRIGHT'`\n: Attaches an author and a license to the file. Choices include:\n\t- `COPYRIGHT`: Copyright\n\t- `CC0`: Public Domain\n\t- `CC-BY-NC-ND`: Creative Commons Attribution-NonCommercial-NoDerivatives\n\t- `CC-BY-NC-SA`: Creative Commons Attribution-NonCommercial-ShareAlike\n\t- `CC-BY`: Creative Commons Attribution\n\t- `CC-BY-SA`: Creative Commons Attribution-ShareAlike\n\t- `CC-BY-NC`: Creative Commons Attribution-NonCommercial\n\t- `CC-BY-ND`: Creative Commons Attribution-NoDerivatives\n\n`PHOTO_EXIF_COPYRIGHT_AUTHOR = 'Your Name Here'`\n: Adds an author name to the photo's exif and copyright statement. Defaults to `AUTHOR` value from the `pelicanconf.py`\n\n`PHOTO_INLINE_GALLERY_ENABLED`\n: Enable inline gallery processing. (Default: False)\n\n`PHOTO_INLINE_GALLERY_PATTERN`\n: The pattern to look for. The ```gallery_name``` is used to find the right gallery.\n\nDefaults:\n\n```python\nr\"gallery::(?P\u003cgallery_name\u003e[/{}\\w_-]+)\"\n```\n\n`PHOTO_INLINE_GALLERY_TEMPLATE`\n: Template to render the inline gallery.\n\nDefault: ```\"inline_gallery\"```\n\n`PHOTO_DEFAULT_IMAGE_OPTIONS`\n: Default keyword options to pass to the PIL.Image.save() function.\nYou can find all available options in the [Pillow: Image file formats](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#image-file-formats) section.\n\nDefaults:\n```python\n{\n\t\"jpeg\": {\n\t\t\"optimize\": True\n\t}\n}\n```\n\n`PHOTO_RESULT_IMAGE_AVERAGE_COLOR = False`\n: Calculate the average color for an result image. This can be used to provide a default background color while using lazy loading.\n\n`PHOTO_PROFILING_ENABLED = False`\n: Enable profiling of function calls and measure the time. You have to run pelican in debug mode to see the results.\n\nThe plug-in automatically resizes the photos and publishes them to the following output folder:\n\n    ./output/photos\n\n**WARNING:** The plug-in can take hours to resize 40,000 photos, therefore, photos and thumbnails are only generated once. Clean the output folders to regenerate the resized photos again.\n\n## How to use\n\nMaintain an organized library of high resolution photos somewhere on disk, using folders to group related images. The default path `~/Pictures` is convenient for Mac OS X users.\n\n* To create a gallery of photos, add the metadata field `gallery: {photo}folder` to an article. To simplify the transition from the plug-in Gallery, the syntax `gallery: {filename}folder` is also accepted.\n* You can now have multiple galleries. The galleries need to be seperated by a comma in the metadata field. The syntax is gallery: `{photo}folder, {photo}folder2`. You can also add titles to your galleries. The syntax is: `{photo}folder, {photo}folder2{This is a title}`. Using the following example the first gallery would have the title of the folder location and the second would have the title `This is a tile.`\n* To use an image in the body of the text, just use the syntax `{photo}folder/image.jpg` instead of the usual `{filename}/images/image.jpg`.\n* To use an image in the body of the text, which can be used with [Lightbox](http://lokeshdhakar.com/projects/lightbox2/) just use the syntax `{lightbox}folder/image.jpg`. For use with other implementations, the gallery and caption attribute names can be set with `PHOTO_LIGHTBOX_GALLERY_ATTR` and `PHOTO_LIGHTBOX_CAPTION_ATTR`.\n* To associate an image with an article, add the metadata field `image: {photo}folder/image.jpg` to an article. Use associated images to improve navigation. For compatibility, the syntax `image: {filename}/images/image.jpg` is also accepted.\n\n### Exif, Captions, and Blacklists\nFolders of photos may optionally have three text files, where each line describes one photo. You can use the `#` to comment out a line. Generating these optional files is left as an exercise for the reader (but consider using Phil Harvey's [exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/)). See below for one method of extracting exif data.\n\n`exif.txt`\n:\tAssociates compact technical information with photos, typically the camera settings. For example:\n\n\tbest.jpg: Canon EOS 5D Mark II - 20mm f/8 1/250s ISO 100\n\tnight.jpg: Canon EOS 5D Mark II - 47mm f/8 5s ISO 100\n\t# new.jpg: Canon EOS 5D Mark II - 47mm f/8 5s ISO 100\n\n`captions.txt`\n:\tAssociates comments with photos. For example:\n\n\tbest.jpg: My best photo ever! How lucky of me!\n\tnight.jpg: Twilight over the dam.\n\t# new.jpg: My new photo blog entry is not quite ready.\n\n`blacklist.txt`\n: Skips photos the user does not want to include. For example:\n\n\tthis-file-will-be-skipped.jpg\n\tthis-one-will-be-skipped-too.jpg\n\t# but-this-file-will-NOT-be-skipped.jpg\n\tthis-one-will-be-also-skipped.jpg\n\n\nHere is an example Markdown article that shows the four use cases:\n\n\ttitle: My Article\n\tgallery: {photo}favorite\n\timage: {photo}favorite/best.jpg\n\n\tHere are my best photos, taken with my favorite camera:\n\t![]({photo}mybag/camera.jpg).\n\t![]({lightbox}mybag/flash.jpg).\n\nThe default behavior of the Photos plugin removes the exif information from the file. If you would like to keep the exif information, you can install the `piexif` library for python and add the following settings to keep some or all of the exif information. This feature is not a replacement for the `exif.txt` feature but in addition to that feature. This feature currently only works with jpeg input files.\n\n## How to change the Jinja templates\n\nThe plugin provides the following variables to your templates:\n\n`article.photo_image`\n:\tFor articles with an associated photo, a tuple with the following information:\n\n* The filename of the original photo.\n* The output path to the generated photo.\n* The output path to the generated thumbnail.\n\nFor example, modify the template `article.html` as shown below to display the associated image before the article content:\n\n```html\n\u003cdiv class=\"entry-content\"\u003e\n\t{% if article.photo_image %}\u003cimg src=\"{{ SITEURL }}/{{ article.photo_image[1] }}\" /\u003e{% endif %}\n\t{% include 'article_infos.html' %}\n\t{{ article.content }}\n\u003c/div\u003e\u003c!-- /.entry-content --\u003e\n```\n\n`article.photo_gallery`\n:\tFor articles with a gallery, a list of the photos in the gallery. Each item in the list is a tuple with five elements:\n\n* The title of the gallery\n* The filename of the original photo.\n* The output path to the generated photo.\n* The output path to the generated thumbnail.\n* The EXIF information of the photo, as read from the file `exif.txt`.\n* The caption of the photo, as read from `captions.txt`.\n\nFor example, add the following to the template `article.html` to add the gallery as the end of the article:\n\n```html\n{% if article.photo_gallery %}\n\u003cdiv class=\"gallery\"\u003e\n\t\t{% for title, gallery in article.photo_gallery %}\n\t\t\t\u003ch1\u003e{{ title }}\u003c/h1\u003e\n\t\t\t\t{% for name, photo, thumb, exif, caption in gallery %}\n\t\t\t\t\t\t\u003ca href=\"{{ SITEURL }}/{{ photo }}\" title=\"{{ name }}\" exif=\"{{ exif }}\" caption=\"{{ caption }}\"\u003e\u003cimg src=\"{{ SITEURL }}/{{ thumb }}\"\u003e\u003c/a\u003e\n\t\t\t\t{% endfor %}\n\t\t{% endfor %}\n\u003c/div\u003e\n{% endif %}\n```\n\nFor example, add the following to the template `index.html`, inside the `entry-content`, to display the thumbnail with a link to the article:\n\n```html\n{% if article.photo_image %}\u003ca href=\"{{ SITEURL }}/{{ article.url }}\"\u003e\u003cimg src=\"{{ SITEURL }}/{{ article.photo_image[2] }}\"\n\tstyle=\"display: inline; float: right; margin: 2px 0 2ex 4ex;\" /\u003e\u003c/a\u003e\n{% endif %}\n```\n\n## How to make the gallery lightbox\n\nThere are several JavaScript libraries that display a list of images as a lightbox. The example below uses [Magnific Popup](http://dimsemenov.com/plugins/magnific-popup/), which allows the more complex initialization needed to display both the filename, the compact technical information, and the caption. The solution would be simpler if photos did not show any extra information.\n\nCopy the files `magnific-popup.css` and `magnific-popup.js` to the root of your Pelican template.\n\nAdd the following to the template `base.html`, inside the HTML `head` tags:\n\n```html\n{% if (article and article.photo_gallery) or (articles_page and articles_page.object_list[0].photo_gallery) %}\n\t\u003clink rel=\"stylesheet\" href=\"{{ SITEURL }}/{{ THEME_STATIC_DIR }}/magnific-popup.css\"\u003e\n{% endif %}\n```\n\nAdd the following to the template `base.html`, before the closing HTML `\u003c/body\u003e` tag:\n\n```JavaScript\n{% if (article and article.photo_gallery) or (articles_page and articles_page.object_list[0].photo_gallery) %}\n\u003c!-- jQuery 1.7.2+ or Zepto.js 1.0+ --\u003e\n\u003cscript src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js\"\u003e\u003c/script\u003e\n\n\u003c!-- Magnific Popup core JS file --\u003e\n\u003cscript src=\"{{ SITEURL }}/{{ THEME_STATIC_DIR }}/magnific-popup.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n$('.gallery').magnificPopup({\n\tdelegate: 'a',\n\ttype: 'image',\n\tgallery: {\n\t\tenabled: true,\n\t\tnavigateByImgClick: true,\n\t\tpreload: [1,2]\n\t},\n\timage: {\n\t\ttitleSrc: function(item) {\n\t\t\tif (item.el.attr('caption') \u0026\u0026 item.el.attr('exif')) {\n\t\t\t\treturn (item.el.attr('caption').replace(/\\\\n/g, '\u003cbr /\u003e') +\n\t\t\t\t\t'\u003csmall\u003e' + item.el.attr('title') + ' - ' + item.el.attr('exif') + '\u003c/small\u003e');\n\t\t\t}\n\t\treturn item.el.attr('title') + '\u003csmall\u003e' + item.el.attr('exif') + '\u003c/small\u003e';\n\t} }\n});\n\u003c/script\u003e\n{% endif %}\n```\n\n## How to make a Bootstrap Carousel\n\nIf you are using bootstrap, the following code is an example of how one could create a carousel.\n\n```html\n{% if article.photo_gallery %}\n  {% for title, gallery in article.photo_gallery %}\n    \u003ch1\u003e{{ title }}\u003c/h1\u003e\n    \u003cdiv id=\"carousel-{{ loop.index }}\" class=\"carousel slide\"\u003e\n      \u003col class=\"carousel-indicators\"\u003e\n          {% for i in range(0, gallery|length) %}\n          \u003cli data-target=\"#carousel-{{ loop.index }}\" data-slide-to=\"{{ i }}\" {% if i==0 %} class=\"active\" {% endif %}\u003e\u003c/li\u003e\n          {% endfor %}\n      \u003c/ol\u003e\n      \u003cdiv class=\"carousel-inner\"\u003e\n        {% for name, photo, thumb, exif, caption in gallery %}\n          {% if loop.first %}\n            \u003cdiv class=\"item active\"\u003e\n          {% else %}\n            \u003cdiv class=\"item\"\u003e\n          {% endif %}\n          \u003cimg src=\"{{ SITEURL }}/{{ photo }}\" exif=\"{{ exif }}\" alt=\"{{ caption }}\"\u003e\n          \u003cdiv class=\"carousel-caption\"\u003e\n              \u003ch5\u003e{{ caption }}\u003c/h5\u003e\n          \u003c/div\u003e \u003c!-- carousel-caption --\u003e\n        \u003c/div\u003e \u003c!-- item --\u003e\n        {% endfor %}\n      \u003c/div\u003e \u003c!-- carousel-inner --\u003e\n      \u003ca class=\"left carousel-control\" href=\"#carousel-{{ loop.index }}\" data-slide=\"prev\"\u003e\n        \u003cspan class=\"glyphicon glyphicon-chevron-left\"\u003e\u003c/span\u003e\n      \u003c/a\u003e\n      \u003ca class=\"right carousel-control\" href=\"#carousel-{{ loop.index }}\" data-slide=\"next\"\u003e\n        \u003cspan class=\"glyphicon glyphicon-chevron-right\"\u003e\u003c/span\u003e\n      \u003c/a\u003e\n    \u003c/div\u003e \u003c!-- closes carousel-{{ loop.index }} --\u003e\n    {% endfor %}\n{% endif %}\n```\n\n## Exiftool example\n\nYou can add the following stanza to your fab file if you are using `fabric` to generate the appropriate text files for your galleries. You need to set the location of `Exiftool` control files.\n\n```Python\ndef photo_gallery_gen(location):\n    \"\"\"Create gallery metadata files.\"\"\"\n    local_path = os.getcwd() + 'LOCATION OF YOUR EXIF CONTROL FILES'\n    with lcd(location):\n        local(\"exiftool -p {fmt_path}/exif.fmt . \u003e exif.txt\".format(\n            fmt_path=local_path))\n        local(\"exiftool -p {fmt_path}/captions.fmt . \u003e captions.txt\".format(\n            fmt_path=local_path))\n\n```\n\n`captions.fmt` example file\n\n```\n$FileName: $Description\n```\n\n`exif.fmt` example file\n\n```\n$FileName: $CreateDate - $Make $Model Stats:(f/$Aperture, ${ShutterSpeed}s, ISO $ISO Flash: $Flash) GPS:($GPSPosition $GPSAltitude)\n```\n\n## Known use cases\n\n[pxquim.pt](http://pxquim.pt/) uses Photos and the plug-in Sub-parts to publish 600 photo galleries with 40,000 photos. Photos keeps the high-resolution photos separate from the site articles.\n\n[pxquim.com](http://pxquim.com/) uses sub-parts to cover conferences, where it makes sense to have a sub-part for each speaker.\n\n## Alternatives\n\nGallery\n:\tGalleries are distinct entities, without the organizational capabilities of articles. Photos must be resized separately, and must be kept with the source of the blog. Gallery was the initial inspiration for Photos.\n\nImage_process\n:\tResize and process images in the article body in a more flexible way (based on the CSS class of the image), but without the ability to create galleries. The source photos must be kept with the source of the blog.\n\nContributing\n------------\n\nContributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][].\n\n To start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section.\n\n[existing issues]: https://github.com/pelican-plugins/photos/issues\n[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html\n\nLicense\n-------\n\nThis project is licensed under the AGPL-3.0 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpelican-plugins%2Fphotos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpelican-plugins%2Fphotos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpelican-plugins%2Fphotos/lists"}