Skip to content

Commit ddaec3e

Browse files
committed
[FEATURE] Add ImageViewHelper
1 parent 3fa947f commit ddaec3e

File tree

4 files changed

+223
-71
lines changed

4 files changed

+223
-71
lines changed

Classes/Fusion/SrcSetImplementation.php

+7-71
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@
1313

1414
use Neos\Flow\Annotations as Flow;
1515
use Neos\Media\Domain\Model\AssetInterface;
16-
use Neos\Media\Domain\Model\ImageInterface;
17-
use Neos\Media\Domain\Model\ThumbnailConfiguration;
18-
use Neos\Media\Domain\Service\AssetService;
1916
use Neos\Fusion\FusionObjects\AbstractFusionObject;
20-
use Neos\Media\Domain\Service\ThumbnailService;
17+
use Visol\Neos\ResponsiveImages\Service\SrcSetService;
2118

2219
/**
2320
* Render the srcset attribute with responsive images. Accepts mostly the same parameters as the uri.image ViewHelper of the Neos.Media package:
@@ -26,19 +23,12 @@
2623
*/
2724
class SrcSetImplementation extends AbstractFusionObject
2825
{
29-
/**
30-
* Resource publisher
31-
*
32-
* @Flow\Inject
33-
* @var AssetService
34-
*/
35-
protected $assetService;
3626

3727
/**
3828
* @Flow\Inject
39-
* @var ThumbnailService
29+
* @var SrcSetService
4030
*/
41-
protected $thumbnailService;
31+
protected $srcSetService;
4232

4333
/**
4434
* Asset
@@ -119,68 +109,14 @@ public function getQuality()
119109
public function evaluate()
120110
{
121111
$asset = $this->getAsset();
112+
$ratio = $this->getRatio();
122113
$maximumWidth = $this->getMaximumWidth();
123114
$maximumHeight = $this->getMaximumHeight();
124-
$ratio = $this->getRatio();
125-
115+
$allowCropping = $this->getAllowCropping();
116+
$quality = $this->getQuality();
126117
$sizes = $this->getSizes();
127-
128-
if (!is_array($sizes) || !count($sizes) > 0) {
129-
throw new \Exception('No sizes defined.', 1519837126);
130-
}
131-
132-
if (!$asset instanceof AssetInterface) {
133-
throw new \Exception('No asset given for rendering.', 1415184217);
134-
}
135-
136-
if ($asset instanceof ImageInterface) {
137-
$assetWidth = $asset->getWidth();
138-
$assetHeight = $asset->getHeight();
139-
}
140-
141118
$request = $this->getRuntime()->getControllerContext()->getRequest();
142119

143-
$srcSetData = [];
144-
foreach ($sizes as $size) {
145-
$currentWidth = null;
146-
$currentMaximumWidth = $size;
147-
$currentHeight = null;
148-
$currentMaximumHeight = null;
149-
$currentAllowCropping = false;
150-
151-
if ($currentMaximumWidth > $assetWidth) {
152-
continue;
153-
}
154-
155-
if (isset($maximumWidth) && $currentMaximumWidth > $maximumWidth) {
156-
continue;
157-
}
158-
159-
if ($ratio) {
160-
$currentWidth = $currentMaximumWidth;
161-
$currentMaximumHeight = $size / $ratio;
162-
$currentHeight = $currentMaximumHeight;
163-
$currentAllowCropping = true;
164-
165-
if ($currentMaximumHeight > $assetHeight) {
166-
continue;
167-
}
168-
169-
if (isset($maximumHeight) && $currentMaximumHeight > $maximumHeight) {
170-
continue;
171-
}
172-
}
173-
174-
$thumbnailConfiguration = new ThumbnailConfiguration($currentWidth, $currentMaximumWidth, $currentHeight, $currentMaximumHeight, $currentAllowCropping, false, false, $this->getQuality());
175-
$thumbnailData = $this->assetService->getThumbnailUriAndSizeForAsset($asset, $thumbnailConfiguration, $request);
176-
177-
if ($thumbnailData === null) {
178-
continue;
179-
}
180-
181-
$srcSetData[] = $thumbnailData['src'] . ' ' . $thumbnailData['width'] . 'w ' . $thumbnailData['height'] . 'h ';
182-
}
183-
184-
return implode(', ', $srcSetData);
120+
return $this->srcSetService->getSrcSetAttribute($asset, $ratio, $maximumWidth, $maximumHeight, $allowCropping, $quality, $sizes, $request);
185121
}
186122
}

Classes/Service/SrcSetService.php

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
namespace Visol\Neos\ResponsiveImages\Service;
3+
4+
/*
5+
* This file is part of the Visol.Neos.ResponsiveImages package.
6+
*
7+
* (c) visol digitale Dienstleistungen GmbH, www.visol.ch
8+
*
9+
* This package is Open Source Software. For the full copyright and license
10+
* information, please view the LICENSE file which was distributed with this
11+
* source code.
12+
*/
13+
14+
use Neos\Flow\Annotations as Flow;
15+
use Neos\Flow\Mvc\RequestInterface;
16+
use Neos\Media\Domain\Model\AssetInterface;
17+
use Neos\Media\Domain\Model\ImageInterface;
18+
use Neos\Media\Domain\Model\ThumbnailConfiguration;
19+
use Neos\Media\Domain\Service\AssetService;
20+
use Neos\Media\Domain\Service\ThumbnailService;
21+
22+
/**
23+
* Render the srcset attribute with responsive images. Accepts mostly the same parameters as the uri.image ViewHelper of the Neos.Media package:
24+
* asset, maximumWidth, maximumHeight, allowCropping, ratio.
25+
*
26+
*/
27+
class SrcSetService
28+
{
29+
30+
/**
31+
* Resource publisher
32+
*
33+
* @Flow\Inject
34+
* @var AssetService
35+
*/
36+
protected $assetService;
37+
38+
39+
/**
40+
* @Flow\Inject
41+
* @var ThumbnailService
42+
*/
43+
protected $thumbnailService;
44+
45+
46+
/**
47+
* Returns a processed image path
48+
*
49+
* @param AssetInterface $asset
50+
* @param float $ratio
51+
* @param int $maximumWidth
52+
* @param int $maximumHeight
53+
* @param boolean $allowCropping
54+
* @param int $quality
55+
* @param array $sizes
56+
* @param RequestInterface $request
57+
* @return string
58+
* @throws \Exception
59+
*/
60+
public function getSrcSetAttribute($asset, $ratio, $maximumWidth, $maximumHeight, $allowCropping, $quality, array $sizes, $request = null)
61+
{
62+
if (!is_array($sizes) || !count($sizes) > 0) {
63+
throw new \Exception('No sizes defined.', 1519837126);
64+
}
65+
66+
if (!$asset instanceof AssetInterface) {
67+
throw new \Exception('No asset given for rendering.', 1519844659);
68+
}
69+
70+
if ($asset instanceof ImageInterface) {
71+
$assetWidth = $asset->getWidth();
72+
$assetHeight = $asset->getHeight();
73+
}
74+
75+
$srcSetData = [];
76+
foreach ($sizes as $size) {
77+
$currentWidth = null;
78+
$currentMaximumWidth = $size;
79+
$currentHeight = null;
80+
$currentMaximumHeight = null;
81+
$currentAllowCropping = $allowCropping;
82+
83+
if ($currentMaximumWidth > $assetWidth) {
84+
continue;
85+
}
86+
87+
if (isset($maximumWidth) && $currentMaximumWidth > $maximumWidth) {
88+
continue;
89+
}
90+
91+
if ($ratio) {
92+
$currentWidth = $currentMaximumWidth;
93+
$currentMaximumHeight = $size / $ratio;
94+
$currentHeight = $currentMaximumHeight;
95+
$currentAllowCropping = true;
96+
97+
if ($currentMaximumHeight > $assetHeight) {
98+
continue;
99+
}
100+
101+
if (isset($maximumHeight) && $currentMaximumHeight > $maximumHeight) {
102+
continue;
103+
}
104+
}
105+
106+
$thumbnailConfiguration = new ThumbnailConfiguration($currentWidth, $currentMaximumWidth, $currentHeight, $currentMaximumHeight, $currentAllowCropping, false, false, $quality);
107+
$thumbnailData = $this->assetService->getThumbnailUriAndSizeForAsset($asset, $thumbnailConfiguration, $request);
108+
109+
if ($thumbnailData === null) {
110+
continue;
111+
}
112+
113+
$srcSetData[] = $thumbnailData['src'] . ' ' . $thumbnailData['width'] . 'w ' . $thumbnailData['height'] . 'h ';
114+
}
115+
116+
return implode(', ', $srcSetData);
117+
}
118+
}
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
namespace Visol\Neos\ResponsiveImages\ViewHelpers;
3+
4+
/*
5+
* This file is part of the Visol.Neos.ResponsiveImages package.
6+
*
7+
* (c) visol digitale Dienstleistungen GmbH, www.visol.ch
8+
*
9+
* This package is Open Source Software. For the full copyright and license
10+
* information, please view the LICENSE file which was distributed with this
11+
* source code.
12+
*/
13+
14+
use Neos\Flow\Annotations as Flow;
15+
use Neos\FluidAdaptor\Core\ViewHelper\AbstractTagBasedViewHelper;
16+
use Neos\Media\Domain\Model\ImageInterface;
17+
use Visol\Neos\ResponsiveImages\Service\SrcSetService;
18+
19+
/**
20+
* Renders an <img> HTML tag from a given Neos.Media's image instance
21+
*
22+
*/
23+
class ImageViewHelper extends AbstractTagBasedViewHelper
24+
{
25+
/**
26+
* @Flow\Inject
27+
* @var SrcSetService
28+
*/
29+
protected $srcSetService;
30+
31+
/**
32+
* @Flow\InjectConfiguration(package="Visol.Neos.ResponsiveImages.SizesPresets")
33+
* @var array
34+
*/
35+
protected $sizesPresets = array();
36+
37+
/**
38+
* name of the tag to be created by this view helper
39+
*
40+
* @var string
41+
*/
42+
protected $tagName = 'img';
43+
44+
/**
45+
* @return void
46+
*/
47+
public function initializeArguments()
48+
{
49+
parent::initializeArguments();
50+
$this->registerUniversalTagAttributes();
51+
$this->registerTagAttribute('alt', 'string', 'Specifies an alternate text for an image', true);
52+
}
53+
54+
/**
55+
* Renders an HTML img tag with a thumbnail image, created from a given image.
56+
*
57+
* @param ImageInterface $image The image to be rendered as an image
58+
* @param integer $width Desired width of the image
59+
* @param integer $maximumWidth Desired maximum width of the image
60+
* @param integer $height Desired height of the image
61+
* @param integer $maximumHeight Desired maximum height of the image
62+
* @param boolean $allowCropping Whether the image should be cropped if the given sizes would hurt the aspect ratio
63+
* @param boolean $allowUpScaling Whether the resulting image size might exceed the size of the original image
64+
* @param boolean $async Return asynchronous image URI in case the requested image does not exist already
65+
* @param string $preset Preset used to determine image configuration
66+
* @param integer $quality Quality of the image
67+
* @return string an <img...> html tag
68+
*/
69+
public function render(ImageInterface $image = null, $ratio = 1, $maximumWidth = null, $maximumHeight = null, $allowCropping = false, $quality = null)
70+
{
71+
$sizes = $this->sizesPresets['Default'];
72+
73+
$srcSetString = $this->srcSetService->getSrcSetAttribute($image, $ratio, $maximumWidth, $maximumHeight, $allowCropping, $quality, $sizes, null);
74+
75+
$this->tag->addAttributes([
76+
'class' => 'lazyload',
77+
'data-sizes' => 'auto',
78+
'data-srcset' => $srcSetString,
79+
]);
80+
81+
// alt argument must be set because it is required (see $this->initializeArguments())
82+
if ($this->arguments['alt'] === '') {
83+
// has to be added explicitly because empty strings won't be added as attributes in general (see parent::initialize())
84+
$this->tag->addAttribute('alt', '');
85+
}
86+
87+
return $this->tag->render();
88+
}
89+
}

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ Just replace usages of the `Neos.Fusion:Image` prototype with `Visol.Neos.Respon
3131
```
3232

3333

34+
Or use the ViewHelper provided. e.g.
35+
36+
```
37+
{namespace responsiveImages=Visol\Neos\ResponsiveImages\ViewHelpers}
38+
39+
<responsiveImages:image image="{item.properties.sliderImage}" ratio="1.89583" />
40+
```
41+
42+
3443
## Configuration
3544

3645
Adjust the desired image sizes in your `Settings.yaml`

0 commit comments

Comments
 (0)