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

Respect heights #66

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
59 changes: 48 additions & 11 deletions Our.Umbraco.TagHelpers/ImgTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ public ImgTagHelper(IOptions<OurUmbracoTagHelpersConfiguration> globalSettings,
[HtmlAttributeName("abovethefold")]
public bool AboveTheFold { get; set; }

[HtmlAttributeName("ignore-crops")]
public bool IgnoreCrops { get; set; }

protected HttpRequest Request => ViewContext.HttpContext.Request;

[ViewContext]
Expand Down Expand Up @@ -154,7 +157,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
var originalWidth = media.GetValue<double>("umbracoWidth"); // Determine the width from the originally uploaded image
var originalHeight = media.GetValue<double>("umbracoHeight"); // Determine the height from the originally uploaded image
width = ImgWidth > 0 ? ImgWidth : originalWidth; // If the element wasn't provided with a width property, use the width from the media object instead
if (!string.IsNullOrEmpty(ImgCropAlias))
if (!string.IsNullOrEmpty(ImgCropAlias) && !IgnoreCrops)
{
// The element contains a crop alias property, so pull through a cropped version of the original image
// Also, calculate the height based on the given width using the crop profile so it's to scale
Expand All @@ -170,14 +173,28 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
}
else
{
// Pull through an image based on the given width and calculate the height so it's to scale.
imgSrc = MediaItem.GetCropUrl(width: (int)width);
if (_globalSettings.OurImg.LazyLoadPlaceholder.Equals(ImagePlaceholderType.LowQualityImage))
if (IgnoreCrops)
{
// Generate a low quality placeholder image if configured to do so
placeholderImgSrc = MediaItem.GetCropUrl(width: (int)width, quality: _globalSettings.OurImg.LazyLoadPlaceholderLowQualityImageQuality);
imgSrc = MediaItem.GetCropUrl(width: (int)ImgWidth, height: (int)ImgHeight);
if (_globalSettings.OurImg.LazyLoadPlaceholder.Equals(ImagePlaceholderType.LowQualityImage))
{
// Generate a low quality placeholder image if configured to do so
placeholderImgSrc = MediaItem.GetCropUrl(width: (int)ImgWidth, height: (int)ImgHeight, quality: _globalSettings.OurImg.LazyLoadPlaceholderLowQualityImageQuality);
}
width = ImgWidth;
height = ImgHeight != 0 ? ImgHeight : (originalHeight / originalWidth) * width;
}
else
{
// Pull through an image based on the given width and calculate the height so it's to scale.
imgSrc = MediaItem.GetCropUrl(width: (int)width);
if (_globalSettings.OurImg.LazyLoadPlaceholder.Equals(ImagePlaceholderType.LowQualityImage))
{
// Generate a low quality placeholder image if configured to do so
placeholderImgSrc = MediaItem.GetCropUrl(width: (int)width, quality: _globalSettings.OurImg.LazyLoadPlaceholderLowQualityImageQuality);
}
height = (originalHeight / originalWidth) * width;
}
height = (originalHeight / originalWidth) * width;
}

#region Autogenerate alt text if unspecfied
Expand Down Expand Up @@ -312,7 +329,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
#region If multiple responsive image variants have been supplied, wrap the img element with a picture element and source elements per variant.
// Only one image will be rendered at a given time based on the current screen width.
// The configuration allows us to define whether images are configured "mobile first". This simply alternates between min-width & max-width media queries.
var imageSizes = GetImageSizes(MediaItem != null);
var imageSizes = GetImageSizes(MediaItem != null && !IgnoreCrops);

if (imageSizes != null && imageSizes.Any())
{
Expand Down Expand Up @@ -344,21 +361,41 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
null;
#endregion

if (!string.IsNullOrEmpty(cropAlias))
if (!string.IsNullOrEmpty(cropAlias) && !IgnoreCrops)
{
var cropWidth = MediaItem.LocalCrops.GetCrop(cropAlias).Width;
var cropHeight = MediaItem.LocalCrops.GetCrop(cropAlias).Height;
sourceHeight = (StringUtils.GetDouble(cropHeight) / StringUtils.GetDouble(cropWidth)) * size.ImageWidth;

sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{MediaItem.GetCropUrl(width: size.ImageWidth, cropAlias: cropAlias)}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{sourceHeight}\"" : "")} />");
}

sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{MediaItem.GetCropUrl(width: size.ImageWidth, cropAlias: cropAlias)}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{sourceHeight}\"" : "")} />");
else if (IgnoreCrops)
{
imgSrc = MediaItem.GetCropUrl(width: (int)ImgWidth, height: (int)ImgHeight);
if (_globalSettings.OurImg.LazyLoadPlaceholder.Equals(ImagePlaceholderType.LowQualityImage))
{
// Generate a low quality placeholder image if configured to do so
placeholderImgSrc = MediaItem.GetCropUrl(width: (int)ImgWidth, height: (int)ImgHeight, quality: _globalSettings.OurImg.LazyLoadPlaceholderLowQualityImageQuality);
}
width = ImgWidth;
height = ImgHeight;

sourceHeight = size.ImageHeight > 0 ? size.ImageHeight : (ImgHeight / ImgWidth) * size.ImageWidth;

sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{MediaItem.GetCropUrl(width: size.ImageWidth, height: size.ImageHeight, cropAlias: cropAlias)}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{size.ImageHeight}\"" : "")} />");
}
else
{
sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{MediaItem.GetCropUrl(width: size.ImageWidth, cropAlias: cropAlias)}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{sourceHeight}\"" : "")} />");
}
}

if (!string.IsNullOrEmpty(FileSource) && ImgWidth > 0 && ImgHeight > 0)
{
sourceHeight = size.ImageHeight > 0 ? size.ImageHeight : (ImgHeight / ImgWidth) * size.ImageWidth;
var sourceUrl = AddQueryToUrl(FileSource, "width", size.ImageWidth.ToString());
sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{sourceUrl}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{sourceHeight}\"" : "")} />");
sb.AppendLine($"<source {(jsLazyLoad ? "data-" : "")}srcset=\"{sourceUrl}&height={sourceHeight}\" media=\"({(_globalSettings.OurImg.MobileFirst ? $"min-width: {minWidth}" : $"max-width: {minWidth - 1}")}px)\" width=\"{size.ImageWidth}\"{(sourceHeight > 0 ? $" height=\"{sourceHeight}\"" : "")} />");

}
}
Expand Down
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ Applying any of the below configurations within your `appsettings.json` file wil

#### Example 1

This will produce a simple `<img>` tag with an alt tag either defined within the media properties in Umbraco, or auto generated based on the file name.
This will produce a simple `<img>` tag with an alt tag either defined within the media properties in Umbraco, or auto generated based on the file name. `width` and `height` are worked out based on image crops set on the media item.

```cshtml
<our-img media-item="Model.Image" />
Expand Down Expand Up @@ -615,6 +615,40 @@ This will produce an `<img>` tag with:
</picture>
```

#### Example 5

`ignore-crops` to use provided size

```cshtml
<our-img media-item="Model.Image" width="100" height="100" ignore-crops="true" />
```

**Output:**

```cshtml
<img alt="Some alt text" width="100" height="100" src="/media/path/image.jpg?width=100&amp;height="100"&amp;rnd=133087885756657361" loading="lazy" decoding="async" fetchpriority="low">
```


#### Example 6

`ignore-crops` to use provided responsive sizes

```cshtml
<our-img media-item="Model.Image" width="400" height="400" width--s="500" height--s="500" width--m="600" height--m="300" />
```

**Output:**

```cshtml
<picture>
<source srcset="/media/path/image.jpg?width=600&amp;height=300&amp;rnd=133087885756657361" media="(min-width: 768px)" width="600" height="300">
<source srcset="/media/path/image.jpg?width=500&amp;height=500&amp;rnd=133087885756657361" media="(min-width: 576px)" width="500" height="500">
<img alt="Some alt text" width="400" height="400" src="/media/path/image.jpg?width=400&amp;height=400&amp;rnd=133087885756657361" loading="lazy" decoding="async" fetchpriority="low">
</picture>
```


## `our-self-host`
This is a tag helper attribute that can be applied to any element using a `src` or `href` attribute in the razor template or partial. It will automatically download and self hosting of third party assets, like javascript, css or images. This was written by Soren Kottal for 24Days.in Umbraco Advent calendar 2022 article - https://24days.in/umbraco-cms/2022/static-assets-taghelper/

Expand Down