The Attribution in the files section of a media edit form: the five items that would be written, where each comes from, and what each image style derivative carries.

This project is not covered by Drupal’s security advisory policy.

Writes the photographer, copyright and license into every image style derivative, as IPTC, XMP and EXIF metadata, so the credit travels with every downloaded copy.

An image on your site is downloaded and shared. The photographer's name and the licence stay with it. Other modules read image metadata into fields; this one writes it into the files your visitors get.

Embedded Attribution writes the maker, the rights, the source, an identifier, a licence link, a credit line, a licensor URL and the alt text into every image style derivative Drupal makes: the versions your visitors actually see and save. Where the original file already says who made it, that wins. Where it says nothing, the module fills the gaps from fields you choose, such as a Photographer field or an Attribution field.

Alpha release: 1.0.0-alpha4

The test suite runs on Drupal 11.3 and 11.4, with GD and with ImageMagick, and exiftool validates every file the module writes. It has not run on a production site yet. Try it on a test or staging site, and report what you find in the issue queue.

What goes into the file

Item XMP IPTC EXIF
Maker dc:creator By-line Artist
Rights (copyright) dc:rights Copyright Notice Copyright
Source dc:source
Identifier dc:identifier
Link (license) xmpRights:WebStatement
Alt text Iptc4xmpCore:AltTextAccessibility
Credit line photoshop:Credit Credit
Licensor URL plus:Licensor › plus:LicensorURL

JPEG derivatives get XMP, IPTC and EXIF. WebP and AVIF derivatives get XMP and EXIF. PNG derivatives get XMP, EXIF, and PNG's own Author and Copyright text.

The original may be a JPEG, a WebP, an AVIF or a PNG, so an image exported as AVIF from Preview or Photos on a Mac keeps its maker and rights in every derivative.

Features

  • The alt text travels with the image. The description Drupal keeps for screen readers is written into the file as well, so it survives a download. On by default, switchable per media type or content type.
  • The original wins. Fields only fill what the file does not say.
  • You choose the fields, per media type or content type: text fields and Attribution fields.
  • Only what an anonymous visitor may see. Fields of unpublished content never go into a file.
  • JPEG, WebP, AVIF and PNG derivatives, including Drupal 11's own AVIF image styles. GIF derivatives are cleaned, but get no attribution.
  • Cleaned when it is made. A derivative is cleaned before it is put in place, also when it is made in advance with drush image:derive, so there is never a moment when the toolkit's file can be fetched.
  • Changes reach the files. Saving a changed item deletes its derivatives, and Drupal makes them again with the new values. After you change the mapping, one button refreshes all derivatives.
  • See it on the edit form: what would be written now, and what each existing derivative carries, read from the file.
  • Photo credit in Google Images. Google Images reads the creator, the copyright notice, the credit line, the Web Statement of Rights and the licensor URL from image metadata, and the module can write all five; the Web Statement of Rights, the license link, makes an image eligible for the Licensable badge. Google does not guarantee that it shows them.
  • Works with C2PA Sign. The attribution is written before C2PA Sign signs the derivative, so it is inside the signature. Tested with C2PA Sign 1.4.11.
  • Privacy: only the attribution leaves the site. By default every other piece of metadata is removed from derivatives. Drupal's GD toolkit writes none, but ImageMagick copies the GPS position, the camera's serial number, the date, the owner and the like from the original; the module keeps only the attribution, the orientation and the colour profile. An AI mark, such as the one AI Disclosure Image writes into the derivatives of AI images, is kept as well. Switch it off on the settings page if you want to show camera data.
  • Fails closed. A derivative the module cannot clean is not served: it is deleted, the visitor gets an error instead of the image, and the reason is logged.
  • No network. The module sends nothing anywhere.

What it does not do

  • It never changes the original file, nor removes its metadata. A site that offers originals for download gives all their metadata away.
  • Originals must be JPEG, WebP, AVIF or PNG. Nothing is read from GIF and TIFF originals.
  • Only image style derivatives. Images pasted into body text and links to the original file are not covered.
  • Images served by an external image bank or IIIF server never pass through Drupal's image styles.
  • Only media items and content (nodes) supply fields, and only their default translation counts.
  • No PDF, video or audio.

Known limitations, described in the README:

  • Storage modules that send the visitor to their own storage, such as s3fs or flysystem, are not covered.
  • A module that replaces Drupal's image factory over this module's stops derivatives from being cleaned when they are made; the status report then says so. Derivatives requested through Drupal are still cleaned before they are served.
  • A module that changes a derivative after Drupal made it, such as imageapi_optimize, can remove the attribution again.
  • With ImageMagick, a TIFF or HEIC original gives a derivative in the same format, which is not served while cleaning is on. Add a "Convert" effect to JPEG or WebP in the image style.
  • The colour profile is kept as it is. It can hold free text, such as a copyright line or the maker and model of a device.
  • The module reads no file larger than a sixteenth of PHP's memory_limit (16 MB with 256M). Raise memory_limit for larger images.

Requirements

Drupal 11.3 or later, PHP 8.3 or later. Media and Attribution are optional.

Installation

composer require 'drupal/embedded_attribution:^1.0@alpha'

Enable the module, go to Configuration → Media → Embedded Attribution, and choose for each media type or content type which field supplies which item.

AI use

This module is developed with the help of an AI coding assistant (Claude). I review and test every change, and each change is logged in AI-LOG.md in the repository.

Project information

Releases