images as $image) { * // $page->images is a Pageimages object * // $image and $thumb are both Pageimage objects * $thumb = $image->size(200, 200); * echo ""; * echo "$image->description"; * echo ""; * } * ~~~~~ * #pw-body * * Typically a Pageimages object will be associated with a specific field attached to a Page. * There may be multiple instances of Pageimages attached to a given Page (depending on what fields are in it's fieldgroup). * * ProcessWire 3.x, Copyright 2019 by Ryan Cramer * https://processwire.com * * @method string render($markup = '', $options = array()) * */ class Pageimages extends Pagefiles { /** * Per the WireArray interface, items must be of type Pagefile * * #pw-internal * * @param mixed $item * @return bool * */ public function isValidItem($item) { return $item instanceof Pageimage; } /** * Add a new Pageimage item, or create one from given filename and add it. * * @param Pageimage|string $item If item is a string (filename) then the Pageimage instance will be created automatically. * @return Pageimages|Pagefiles * */ public function add($item) { if(is_string($item)) $item = $this->wire(new Pageimage($this, $item)); return parent::add($item); } /** * Per the WireArray interface, return a blank Pageimage * * #pw-internal * * @return Pageimage * */ public function makeBlankItem() { return $this->wire(new Pageimage($this, '')); } /** * Does this field have the given file name? If so, return it, if not return null. * * @param string $name Basename is assumed * @return null|Pagefile|Pageimage Returns Pagefile object if found, null if not * */ public function getFile($name) { $hasFile = parent::getFile($name); if($hasFile) return $hasFile; // populate $base with $name sans ImageSizer info and extension $name = basename($name); $pos = strpos($name, '.'); $base = ($pos ? substr($name, 0, $pos) : null); foreach($this as $pagefile) { /** @var Pageimage $pagefile */ if($base !== null && strpos($pagefile->basename, $base) !== 0) continue; // they start the same, is it a variation? if(!$pagefile->isVariation($name)) continue; // if we are here we found a variation $hasFile = $pagefile; break; } return $hasFile; } /** * Get an array of all image variations on this field indexed by original file name. * * More information on any variation filename can be retrieved from `Pageimage::isVariation()`. * * ~~~~~ * $variations = $page->images->getAllVariations(); * print_r($variations); * // Example output: * // array( * // 'foo.jpg' => array( * // 'foo.100x100.jpg', * // 'foo.200x200.jpg' * // ), * // 'bar.jpg' => array( * // 'bar.300x300.jpg' * // ) * // ); * ~~~~~ * * @return array Array indexed by file name, each containing array of variation file names * @see Pageimage::isVariation() * */ public function getAllVariations() { $variations = array(); $extensions = array(); $basenames = array(); foreach($this as $pageimage) { /** @var Pageimage $pageimage */ $name = $pageimage->basename; $ext = $pageimage->ext; $extensions[$name] = $ext; $basenames[$name] = basename($name, ".$ext"); $variations[$name] = array(); } foreach(new \DirectoryIterator($this->path()) as $file) { if($file->isDir() || $file->isDot()) continue; $_ext = $file->getExtension(); $_name = $file->getBasename(); $_base = basename($_name, ".$_ext"); foreach($variations as $name => $unused) { // if filenames match then it's an original, not a variation if($name === $_name) continue; // if files don't share same extension, skip $ext = $extensions[$name]; if($ext != $_ext) continue; // if files don't start the same, it's not a variation $base = $basenames[$name]; if(strpos($_base, $base) !== 0) continue; // if the part up to the first period isn't the same, then it's not a variation $test1 = substr($name, 0, strpos($name, '.')); $test2 = substr($_name, 0, strpos($_name, '.')); if($test1 !== $test2) continue; // if we reach this point, we've found a variation $variations[$name][] = $_name; } } return $variations; } /** * Render markup for all images here (optionally using a provided markup template string and/or image size options) * * Given template string can contain any of the placeholders, which will be replaced: * - `{url}` or `{src}` Image URL (typically used for src attribute) * - `{httpUrl}` File URL with scheme and hostname (alternate for src attribute) * - `{URL}` Same as url but with cache busting query string * - `{HTTPURL}` Same as httpUrl but with cache busting query string * - `{description}` or `{alt}` Image description (typically used in alt attribute) * - `{tags}` File tags (might be useful in class attribute) * - `{width}` Width of image * - `{height}` Height of image * - `{hidpiWidth}` HiDPI width of image * - `{hidpiHeight}` HiDPI height of image * - `{ext}` File extension * - `{original.name}` Replace “name” with any of the properties above to refer to original/full-size image. * If there is no original image then these just refer back to the current image. * * ~~~~~ * // default output * echo $page->images->render(); * * // custom output * echo $page->images->render("{alt}"); * * // custom output with options * echo $page->images->render("{alt}", [ 'width' => 300 ]); * * // options can go in first argument if you prefer * echo $page->images->render([ 'width' => 300, 'height' => 200 ]); * * // if only width/height are needed, they can also be specified as a string (1st or 2nd arg) * echo $page->images->render('300x200'); * * // custom output with link to original/full-size and square crop of 300x300 for thumbnails * echo ""; * ~~~~~ * * @param string|array $markup Markup template string or optional $options array if you do not want the template string here. * @param array|string $options Optionally resize image with these options sent to size() method: * - `width` (int): Target width or 0 for current image size (or proportional if height specified). * - `height` (int): Target height or 0 for current image size (or proportional if width specified). * - `markup` (string): Markup template string (same as $markup argument), or omit for default (same as $markup argument). * - `link` (bool): Link image to original size? Though you may prefer to do this with your own $markup (see examples). (default=false) * - `limit` (int): Render no more than this many images (default=0, no limit). * - Plus any option available to the $options argument on the `Pageimage::size()` method. * - If you only need width and/or height, you can specify a width x height string, i.e. 123x456 (use 0 for proportional). * @return string * @since 3.0.126 * */ public function ___render($markup = '', $options = array()) { $out = ''; $limit = 0; $n = 0; if(isset($options['limit'])) { $limit = (int) $options['limit']; unset($options['limit']); } foreach($this as $image) { /** @var Pageimage $image */ $out .= $image->render($markup, $options); if($limit > 0 && ++$n >= $limit) break; } return $out; } }