Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for loading attribute #1730

Merged
merged 2 commits into from
Feb 11, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ indent_size = 4
indent_style = space
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
trim_trailing_whitespace = false
freekmurze marked this conversation as resolved.
Show resolved Hide resolved

[*.blade.php]
insert_final_newline = false

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to `laravel-medialibrary` will be documented in this file
- the `UrlGenerator` interface now contains all required methods (#1656)
- use PHP 7.4 features where possible
- the namespace has been renamed from `Spatie\MediaLibrary` to `Spatie\Medialibrary`.
- added support for the `loading` attribute (#1667)

## 7.18.2 - 2020-01-25

Expand Down
11 changes: 11 additions & 0 deletions config/medialibrary.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@
'tiny_placeholder_generator' => Spatie\Medialibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
],

/*
* When converting Media instances to response the medialibrary will add
* a `loading` attribute to the `img` tag. Here you can set the default
* value of that attribute.
*
* Possible values: 'auto', 'lazy' and 'eager,
*
* More info: https://css-tricks.com/native-lazy-loading/
*/
"default_loading_attribute_value" => 'auto',
freekmurze marked this conversation as resolved.
Show resolved Hide resolved

/*
* When urls to files get generated, this class will be called. Leave empty
* if your files are stored locally above the site root or on s3.
Expand Down
8 changes: 7 additions & 1 deletion docs/api/defining-conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ public function performOnCollections($collectionNames)
*
* @return $this
*/
public function nonQueued()
public function nonQueued(): self
```

### useLoadingAttributeValue

This is the value that, when this conversation is converted to html, will be used in the `loading` attribute. The loading attribute is a standardised attribute that controls lazy loading behaviour of the browser. Possible values are `lazy`, `eager` and `auto`.

You can learn more on native lazy loading [in this post on css-tricks](https://css-tricks.com/native-lazy-loading/).

## Image manipulations

You may add any call to one of [the manipulation functions](https://docs.spatie.be/image) available on [the spatie/image package](https://github.com/spatie/image).
Expand Down
16 changes: 13 additions & 3 deletions docs/installation-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ This is the default content of the config file:

```php
return [

/*
/*
* The disk on which to store added files and derived images by default. Choose
* one or more of the disks you've configured in config/filesystems.php.
*/
Expand Down Expand Up @@ -73,7 +72,7 @@ return [
* images. By default we optimize for filesize and create variations that each are 20%
* smaller than the previous one. More info in the documentation.
*
* https://docs.spatie.be/laravel-medialibrary/v8/advanced-usage/generating-responsive-images
* https://docs.spatie.be/laravel-medialibrary/v7/advanced-usage/generating-responsive-images
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be v8?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right!

*/
'width_calculator' => Spatie\Medialibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,

Expand All @@ -90,6 +89,17 @@ return [
'tiny_placeholder_generator' => Spatie\Medialibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
],

/*
* When converting Media instances to response the medialibrary will add
* a `loading` attribute to the `img` tag. Here you can set the default
* value of that attribute.
*
* Possible values: 'auto', 'lazy' and 'eager,
*
* More info: https://css-tricks.com/native-lazy-loading/
*/
"default_loading_attribute_value" => 'auto',
freekmurze marked this conversation as resolved.
Show resolved Hide resolved

/*
* When urls to files get generated, this class will be called. Leave empty
* if your files are stored locally above the site root or on s3.
Expand Down
2 changes: 1 addition & 1 deletion resources/views/image.blade.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<img{!! $attributeString !!} src="{{ $media->getUrl($conversion) }}" alt="{{ $media->name }}">
<img{!! $attributeString !!} loading="{{ $loadingAttributeValue }}" src="{{ $media->getUrl($conversion) }}" alt="{{ $media->name }}">
2 changes: 1 addition & 1 deletion resources/views/responsiveImage.blade.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<img{!! $attributeString !!} srcset="{{ $media->getSrcset($conversion) }}" src="{{ $media->getUrl($conversion) }}" width="{{ $width }}">
<img{!! $attributeString !!} loading="{{ $loadingAttributeValue }}" srcset="{{ $media->getSrcset($conversion) }}" src="{{ $media->getUrl($conversion) }}" width="{{ $width }}">
2 changes: 1 addition & 1 deletion resources/views/responsiveImageWithPlaceholder.blade.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<img{!! $attributeString !!} srcset="{{ $media->getSrcset($conversion) }}" onload="this.onload=null;this.sizes=Math.ceil(this.getBoundingClientRect().width/window.innerWidth*100)+'vw';" sizes="1px" src="{{ $media->getUrl($conversion) }}" width="{{ $width }}">
<img{!! $attributeString !!} loading="{{ $loadingAttributeValue }}" srcset="{{ $media->getSrcset($conversion) }}" onload="this.onload=null;this.sizes=Math.ceil(this.getBoundingClientRect().width/window.innerWidth*100)+'vw';" sizes="1px" src="{{ $media->getUrl($conversion) }}" width="{{ $width }}">
16 changes: 16 additions & 0 deletions src/Conversion/Conversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ class Conversion

protected bool $generateResponsiveImages = false;

protected string $loadingAttributeValue;

public function __construct(string $name)
{
$this->name = $name;

$this->manipulations = (new Manipulations())
->optimize(config('medialibrary.image_optimizers'))
->format(Manipulations::FORMAT_JPG);

$this->loadingAttributeValue = config('medialibrary.default_loading_attribute_value');
}

public static function create(string $name)
Expand Down Expand Up @@ -211,4 +215,16 @@ public function getConversionFile(string $file): string

return "{$fileName}-{$this->getName()}.{$extension}";
}

public function useLoadingAttributeValue(string $value): self
{
$this->loadingAttributeValue = $value;

return $this;
}

public function getLoadingAttributeValue(): string
{
return $this->loadingAttributeValue;
}
}
9 changes: 9 additions & 0 deletions src/Models/Media.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ public function img($conversion = '', array $extraAttributes = []): string
$attributeString = ' '.$attributeString;
}

$loadingAttributeValue = config('medialibrary.default_loading_attribute_value');
if ($conversion !== '') {
/** @var Conversion $conversionObject */
$conversionObject = ConversionCollection::createForMedia($this)->getByName($conversion);

$loadingAttributeValue = $conversionObject->getLoadingAttributeValue();
}

$media = $this;

$viewName = 'image';
Expand All @@ -299,6 +307,7 @@ public function img($conversion = '', array $extraAttributes = []): string
'media',
'conversion',
'attributeString',
'loadingAttributeValue',
'width'
));
}
Expand Down
34 changes: 27 additions & 7 deletions tests/Feature/Media/ToHtmlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Illuminate\Support\Str;
use Spatie\Medialibrary\Models\Media;
use Spatie\Medialibrary\Tests\Support\TestModels\TestModel;
use Spatie\Medialibrary\Tests\Support\TestModels\TestModelWithConversion;
use Spatie\Medialibrary\Tests\Support\TestModels\TestModelWithCustomLoadingAttribute;
use Spatie\Medialibrary\Tests\TestCase;
use Spatie\Snapshots\MatchesSnapshots;

Expand All @@ -24,20 +27,20 @@ public function setUp(): void
/** @test */
public function it_can_render_itself_as_an_image()
{
$this->assertEquals('<img src="/media/1/test.jpg" alt="test">', Media::first()->img());
$this->assertEquals('<img loading="auto" src="/media/1/test.jpg" alt="test">', Media::first()->img());
}

/** @test */
public function it_can_render_a_conversion_of_itself_as_an_image()
{
$this->assertEquals('<img src="/media/1/conversions/test-thumb.jpg" alt="test">', Media::first()->img('thumb'));
$this->assertEquals('<img loading="auto" src="/media/1/conversions/test-thumb.jpg" alt="test">', Media::first()->img('thumb'));
}

/** @test */
public function it_can_render_extra_attributes()
{
$this->assertEquals(
'<img class="my-class" id="my-id" src="/media/1/conversions/test-thumb.jpg" alt="test">',
'<img class="my-class" id="my-id" loading="auto" src="/media/1/conversions/test-thumb.jpg" alt="test">',
Media::first()->img('thumb', ['class' => 'my-class', 'id' => 'my-id'])
);
}
Expand All @@ -46,7 +49,7 @@ public function it_can_render_extra_attributes()
public function attributes_can_be_passed_to_the_first_argument()
{
$this->assertEquals(
'<img class="my-class" id="my-id" src="/media/1/test.jpg" alt="test">',
'<img class="my-class" id="my-id" loading="auto" src="/media/1/test.jpg" alt="test">',
Media::first()->img(['class' => 'my-class', 'id' => 'my-id'])
);
}
Expand All @@ -55,7 +58,7 @@ public function attributes_can_be_passed_to_the_first_argument()
public function both_the_conversion_and_extra_attributes_can_be_passed_as_the_first_arugment()
{
$this->assertEquals(
'<img class="my-class" id="my-id" src="/media/1/conversions/test-thumb.jpg" alt="test">',
'<img class="my-class" id="my-id" loading="auto" src="/media/1/conversions/test-thumb.jpg" alt="test">',
Media::first()->img(['class' => 'my-class', 'id' => 'my-id', 'conversion' => 'thumb'])
);
}
Expand All @@ -67,7 +70,7 @@ public function a_media_instance_is_htmlable()

$renderedView = $this->renderView('media', compact('media'));

$this->assertEquals('<img src="/media/1/test.jpg" alt="test"> <img src="/media/1/conversions/test-thumb.jpg" alt="test">', $renderedView);
$this->assertEquals('<img loading="auto" src="/media/1/test.jpg" alt="test"> <img loading="auto" src="/media/1/conversions/test-thumb.jpg" alt="test">', $renderedView);
}

/** @test */
Expand Down Expand Up @@ -119,6 +122,23 @@ public function it_will_not_rendering_extra_javascript_or_including_base64_svg_w

$imgTag = $media->refresh()->img();

$this->assertEquals('<img srcset="http://localhost/media/2/responsive-images/test___medialibrary_original_340_280.jpg 340w, http://localhost/media/2/responsive-images/test___medialibrary_original_284_233.jpg 284w, http://localhost/media/2/responsive-images/test___medialibrary_original_237_195.jpg 237w" src="/media/2/test.jpg" width="340">', $imgTag);
$this->assertEquals('<img loading="auto" srcset="http://localhost/media/2/responsive-images/test___medialibrary_original_340_280.jpg 340w, http://localhost/media/2/responsive-images/test___medialibrary_original_284_233.jpg 284w, http://localhost/media/2/responsive-images/test___medialibrary_original_237_195.jpg 237w" src="/media/2/test.jpg" width="340">', $imgTag);
}

/** @test */
public function the_loading_attribute_can_be_specified_on_the_conversion()
{
$media = TestModelWithCustomLoadingAttribute::create(['name' => 'test'])
->addMedia($this->getTestJpg())
->toMediaCollection();

$originalImgTag = $media->refresh()->img();
$this->assertEquals('<img loading="auto" src="/media/2/test.jpg" alt="test">', $originalImgTag);

$lazyConversionImageTag = $media->refresh()->img('lazy-conversion');
$this->assertEquals('<img loading="lazy" src="/media/2/conversions/test-lazy-conversion.jpg" alt="test">', $lazyConversionImageTag);

$eagerConversionImageTag = $media->refresh()->img('eager-conversion');
$this->assertEquals('<img loading="eager" src="/media/2/conversions/test-eager-conversion.jpg" alt="test">', $eagerConversionImageTag);
}
}
21 changes: 21 additions & 0 deletions tests/Support/TestModels/TestModelWithCustomLoadingAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Spatie\Medialibrary\Tests\Support\TestModels;

use Spatie\Medialibrary\Models\Media;

class TestModelWithCustomLoadingAttribute extends TestModelWithConversion
{
public function registerMediaConversions(Media $media = null): void
{
$this
->addMediaConversion('lazy-conversion')
->useLoadingAttributeValue('lazy')
->nonQueued();

$this
->addMediaConversion('eager-conversion')
->useLoadingAttributeValue('eager')
->nonQueued();
}
}