jeavon / slimsy Goto Github PK
View Code? Open in Web Editor NEWEffortless Responsive & Lazy Images with LazySizes and Umbraco
License: MIT License
Effortless Responsive & Lazy Images with LazySizes and Umbraco
License: MIT License
Create a version of ConvertImgToSrcSet that can be applied safely to rte.cshtml so the Slimsy magic can work on all RTE's, even if in a grid layout. i.e.
@Html.ConvertImgToSrcSet(Html.Raw(TemplateUtilities.ParseInternalLinks(Model.value.ToString())), true, true)
Firstly thank-you for v2, much kudos!
I've had a spin, and it's working really nicely, however once I set a CropAlias on the GetCropUrl method, I seem unable to set the width/height and quality. I figured, I would need to do this to make the Low Quality image fallback work?
Loads of detail below on how I'm using it, however I won't be offended if TLDR ;-)
I've implemented in a project via a single DisplayTemplate.
@Html.DisplayFor(m => Model.Photo)
I also support passing in some parameters:
@Html.DisplayFor(m => Model.Photo, new { Crop = "carousel", Width = 100, Height = 100 })
Works: var imgLqip = Url.GetCropUrl(Model.Content, width, height, quality: 30, furtherOptions: "&format=auto");
Works: var imgLqip = Url.GetCropUrl(Model.Content, cropAlias);
Fails: var imgLqip = Url.GetCropUrl(Model.Content, cropAlias, width);
@model Image
@if (Model != null)
{
var cropAlias = (string)ViewData["crop"];
int width = (int?)ViewData["width"] ?? 640;
int height = (int?)ViewData["height"] ?? 0;
// load javascript
Html.RequiresJs("~/scripts/vendor/picturefill.min.js");
Html.RequiresJs("~/scripts/vendor/lazysizes.min.js");
if (cropAlias == null)
{
var imgSrcSet = Url.GetSrcSetUrls(Model.Content, width, height);
var imgSrcSetWebP = Url.GetSrcSetUrls(Model.Content, width, height, Constants.Conventions.Media.File, "webp", 70);
var imgSrc = Url.GetCropUrl(Model.Content, width, height);
var imgLqip = Url.GetCropUrl(Model.Content, width, height, quality: 30, furtherOptions: "&format=auto");
<picture>
<!--[if IE 9]><video style="display: none"><![endif]-->
<source data-srcset="@imgSrcSetWebP" srcset="@imgLqip" type="image/webp" data-sizes="auto" />
<source data-srcset="@imgSrcSet" srcset="@imgLqip" type="image/jpeg" data-sizes="auto" />
<!--[if IE 9]></video><![endif]-->
<img src="@imgLqip"
data-src="@imgSrc"
class="lazyload"
data-sizes="auto"
alt="@Model.Name" />
</picture>
}
else
{
var imgSrcSet = Url.GetSrcSetUrls(Model.Content, cropAlias);
var imgSrcSetWebP = Url.GetSrcSetUrls(Model.Content, cropAlias, Constants.Conventions.Media.File, "webp");
var imgSrc = Url.GetCropUrl(Model.Content, cropAlias);
var imgLqip = Url.GetCropUrl(Model.Content, cropAlias);
<picture>
<!--[if IE 9]><video style="display: none"><![endif]-->
<source data-srcset="@imgSrcSetWebP" srcset="@imgLqip" type="image/webp" data-sizes="auto" />
<source data-srcset="@imgSrcSet" srcset="@imgLqip" type="image/jpeg" data-sizes="auto" />
<!--[if IE 9]></video><![endif]-->
<img src="@imgLqip"
data-src="@imgSrc"
class="lazyload"
data-sizes="auto"
alt="@Model.Name" />
</picture>
}
}
When testing the new beta version I ran across a strange issue.
I am using Url.GetSrcSetUrls(publishedContent, cropAlias, propertyAlias) method - it works as it should - freaking awesome!
Then I decide to add an alt attribute to please the seo gods, and after that the image loads but in the smallest size. Strange.
If the alt attribute is empty - everything is fine, and up to 5 characters it seems, but after 6 the smallest version is loaded.
Before adding the alt, the size was set to sizes="1663px", but after adding the alt it is sizes="46px"*
*it gets longer in relation to how long the alt attribute is set, 6 characters gives me 46px .
The same happens if I add a title attribute, if I have it longer than 5 characters, the smallest version of the image is loaded. BUT if I also add an alt attribute, and it is empty or not longer than 5 characters, I can have the title tag as long as I wish.
Am I doing something wrong here?
Create a version of ConvertImgToSrcSet that can be applied safely to media.cshtml so the Slimsy magic can work when adding an Image in a grid layout. Or, if it's already possible, document how it's done.
The urlhelper extension methods defaults outputformat to an empty string. In SlimsyService however defaultformat from options is only used if outputformat is 'null', which means that the defaultformat is never applied when using the urlhelper extensions.
Images that have been rotated using the EXIF attribute Orientation
are displayed in the wrong orientation when converted to a WebP.
In my opinion, the EXIF attribute Orientation
should be considered when the library converts the image to a WebP. Especially since browsers generally respect this attribute when displaying JPGs or other image types.
Please, add the possibility of changing the webp quality in the SlimsyPictureTagHelper.
Today it's fixed on 70% in the code and we wanted to use a custom value there.
Hi, several months ago, a website, which we manage, started logging errors like this:
Exception:
ImageProcessor.Common.Exceptions.ImageProcessingException: ProcessImageAsync 559 : The request /media/1357/product-transformator-2017-v1.jpg?center=0.2275,0.5&mode=crop&%E2%80%A6 could not be understood by the server due to malformed syntax.
We checked what was going on and we decided to ignore errors like this.
Now I'm investigating again, since these error are happening 1 per hour and I can't find any reason why this happens. The images are correctly rendered in the page and the URL logged with the error, returns correctly the image.
I found out that the issue might be related to the fact that some crawler only saves part of the url of the image, maybe because it's too long, see the screenshot:
This is exactly the reported URL (ending with the 3 dots). This URL is returned by the Slimsy package
data-srcset="@Url.GetSrcSetUrls(image, width, height)"
Actually now, we have these issues on 3 different Umbraco websites with Umbraco 7 and 8, on Cloud and on standard Umbraco
Umbraco 8 is using Slimsy 3, Umbraco 7 Slimsy 2
all of them uses the share the same code on the Grid media view (https://our.umbraco.com/packages/website-utilities/slimsy/
the snippet in the middle of the page)
I'm wondering if you guys have any idea about how to fix this issue.
Thanks.
Umbraco v13 have changed the objects returned by the RteMacroRenderingValueConverter which breaks how Slimsy works
There is a pending PR to make this possible to fix in a future v13 targeted release umbraco/Umbraco-CMS#15645
Umbraco 13 does not have a startup.cs file and I can't figure out where to put the ".AddSlimsy()" command. I saw a post here on Umbraco 11's location but "services.AddUmbraco()" does not seem to exist in an Umbraco 13 project either so I am a bit lost on this. What is the proper config for an Umbraco 13 install? Thank you
I had a case, where we had created a new media type for videos with fallback images. (Fallback images being saved to the umbracoFile property, to enable Slimsy).
We didn't have the other default properties (umbracoWidth, umbracoHeight etc.), so when Slimsy tried to find the maxwidth, the value of umbracoWidth was obviously 0, thus making the maxWidth equal to the first width step.
In cases where the width can't be read from umbracoWidth, I would suggest that it should just keep the configured Slimsy:MaxWidth (upscale=false would then prevent unnecessary upscaling), or find the images correct width using System.Drawing.Image.
Hi,
We are trying to get an HTML response as below with your plugin but we couldn't create the custom breakpoints. we do not want auto generated breakpoints. is it possible to do it with this package
<picture>
<source media="(min-width: 1440px)" srcset="/media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=1920&height=584&rnd=133330203507330000&format=webp&quality=80 1x, /media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=3840&height=1168&rnd=133330203507330000&format=webp&quality=80 2x" type="image/webp">
<source media="(min-width: 768px)" srcset="/media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=1200&height=464&rnd=133330203507330000&format=webp&quality=80 1x, /media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=2400&height=928&rnd=133330203507330000&format=webp&quality=80 2x" type="image/webp">
<source media="(min-width: 375px)" srcset="/media/tytmj3of/web-header-darkb.jpg?cc=0.48653172261789%2c0%2c0.07131845920029152%2c0&width=768&height=528&rnd=133330203507330000&format=webp&quality=80 1x, /media/tytmj3of/web-header-darkb.jpg?cc=0.48653172261789%2c0%2c0.07131845920029152%2c0&width=1536&height=1056&rnd=133330203507330000&format=webp&quality=80 2x" type="image/webp">
<img class="event-page__imag header-block__image" srcset="/media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=1920&height=584&rnd=133330203507330000&format=webp&quality=80 1x, /media/tytmj3of/web-header-darkb.jpg?rxy=0.7057628900729893%2c0.23142480436991725&width=3840&height=1168&rnd=133330203507330000&format=webp&quality=80 2x" alt="Web Header Darkb" loading="eager" height="584" width="1920">
</picture>
Hello, thanks for great plugin!
We have an issue, where its working in our local enviorment, but not working in our production env.
<picture class="block mb-6">
<source data-srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=180&height=121&format=webp&quality=70&v=1d9d1ca510fcfd0 180w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=360&height=243&format=webp&quality=70&v=1d9d1ca510fcfd0 360w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=540&height=364&format=webp&quality=70&v=1d9d1ca510fcfd0 540w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=720&height=485&format=webp&quality=70&v=1d9d1ca510fcfd0 720w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=900&height=606&format=webp&quality=70&v=1d9d1ca510fcfd0 900w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1080&height=728&format=webp&quality=70&v=1d9d1ca510fcfd0 1080w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1260&height=849&format=webp&quality=70&v=1d9d1ca510fcfd0 1260w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1440&height=970&format=webp&quality=70&v=1d9d1ca510fcfd0 1440w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1620&height=1092&format=webp&quality=70&v=1d9d1ca510fcfd0 1620w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1800&height=1213&format=webp&quality=70&v=1d9d1ca510fcfd0 1800w" srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=webp&quality=20&v=1d9d1ca510fcfd0" type="image/webp" data-sizes="auto" />
<source data-srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=180&height=121&format=jpg&quality=70&v=1d9d1ca510fcfd0 180w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=360&height=243&format=jpg&quality=70&v=1d9d1ca510fcfd0 360w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=540&height=364&format=jpg&quality=70&v=1d9d1ca510fcfd0 540w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=720&height=485&format=jpg&quality=70&v=1d9d1ca510fcfd0 720w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=900&height=606&format=jpg&quality=70&v=1d9d1ca510fcfd0 900w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1080&height=728&format=jpg&quality=70&v=1d9d1ca510fcfd0 1080w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1260&height=849&format=jpg&quality=70&v=1d9d1ca510fcfd0 1260w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1440&height=970&format=jpg&quality=70&v=1d9d1ca510fcfd0 1440w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1620&height=1092&format=jpg&quality=70&v=1d9d1ca510fcfd0 1620w,/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=1800&height=1213&format=jpg&quality=70&v=1d9d1ca510fcfd0 1800w" srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=jpg&quality=20&v=1d9d1ca510fcfd0" type="image/jpeg" data-sizes="auto" />
<img src="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=jpg&quality=20&v=1d9d1ca510fcfd0" data-src="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=650&height=438&format=jpg&v=1d9d1ca510fcfd0" class="lazyload" data-sizes="auto" alt="Deer" width="650" height="438" />
</picture>
Note: everything looks and work great !
When running on our production server we get this output in (using slimsy 4.1.0 beta 3) :
<picture class="block mb-6">
<source data-srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=180&height=121&format=webp&quality=75&v=1d9d1ca2a74b1b0 180w" srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=webp&quality=20&v=1d9d1ca2a74b1b0" type="image/webp" data-sizes="auto" />
<source data-srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=180&height=121&quality=70&v=1d9d1ca2a74b1b0 180w" srcset="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=&quality=20&v=1d9d1ca2a74b1b0" type="" data-sizes="auto" />
<img src="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=325&height=219&format=&quality=20&v=1d9d1ca2a74b1b0" data-src="/media/md0g0ixd/deer.jpg?rxy=0.47,0.4880239520958084&width=650&height=438&format=&v=1d9d1ca2a74b1b0" class="lazyload" data-sizes="auto" alt="Deer" width="650" height="438" />
</picture>
Note: It only shows the first first version, 180w.
We tried with latest beta release, beta 4, but now we only get this result:
<img src="/media/md0g0ixd/deer.jpg" class="lazyload" alt="Deer" width="650" height="438" />
Note: No picture tag at all, it also drops our two tailwind classes "block" and "mb-6"
Our local dev setup is using windows 11 latest IIS and our production server is using "Debian GNU/Linux 11 (bullseye) - mcr.microsoft.com/dotnet/aspnet:7.0"
Our appsettings looks like this:
"Slimsy": {
"WidthStep": 180,
"UseCropAsSrc": true,
"DefaultQuality": 70,
"TagHelper": {
"DefaultPictureSources": [
{
"Extension": "webp",
"Quality": "75"
}
],
"ImageDimensions": true
}
},
We used to have "SingleSources" in "TagHelper", but I dropped that thinking that might be related to our first issue only getting the first 180w. But that didn't affect anything sadly.
Any ideas where to continue to debug and identify what the issue is would be awesome, thanks!
I've noticed the test site uses the sample site build way back in Umbraco 9, sadly this gives errors on certain pages that use editors deleted in Umbraco 14, like the nested content editor. This makes it a bit harder to test the features of slimsy as I first need to fix render issues before I can check out images like products or create new editors.
Hi,
I made the following extensions to enable easy support for Block List and Grid-embedded Rich Text editor images:
public static class SlimsyExtensions
{
/// <summary>
/// Convert img to img srcset, extracts width and height from querystrings
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="publishedElement"></param>
/// <param name="propertyAlias">Alias of the TinyMce property</param>
/// <param name="generateLqip">Set to true if you want LQIP markup to be generated</param>
/// <param name="removeStyleAttribute">If you don't want the inline style attribute added by TinyMce to render</param>
/// <param name="renderPicture"></param>
/// <param name="pictureSources"></param>
/// <returns>HTML Markup</returns>
public static IHtmlEncodedString? ConvertImgToResponsive(this IHtmlHelper htmlHelper, IPublishedElement publishedElement, string propertyAlias, bool generateLqip = true, bool removeStyleAttribute = true, bool renderPicture = false, string[]? pictureSources = null)
{
var sourceValue = publishedElement.GetProperty(propertyAlias)?.GetSourceValue()?.ToString();
if (sourceValue is null) {
return null;
}
return htmlHelper.ConvertImgToResponsive(sourceValue, generateLqip, removeStyleAttribute, renderPicture, pictureSources);
}
/// <summary>
/// Convert img to img srcset, extracts width and height from querystrings
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="publishedElement"></param>
/// <param name="propertyAlias">Alias of the TinyMce property</param>
/// <param name="generateLqip">Set to true if you want LQIP markup to be generated</param>
/// <param name="removeStyleAttribute">If you don't want the inline style attribute added by TinyMce to render</param>
/// <param name="renderPicture"></param>
/// <param name="pictureSources"></param>
/// <returns>HTML Markup</returns>
public static IHtmlEncodedString? ConvertImgToResponsive(this IHtmlHelper htmlHelper, PublishedElementWrapped publishedElement, string propertyAlias, bool generateLqip = true, bool removeStyleAttribute = true, bool renderPicture = false, string[]? pictureSources = null)
{
return htmlHelper.ConvertImgToResponsive(publishedElement.Unwrap(), propertyAlias, generateLqip, removeStyleAttribute, renderPicture, pictureSources);
}
}
Then in a Block List view we can just use this:
@Html.ConvertImgToResponsive(Model.Content, "text", renderPicture: true, pictureSources: new []{"webp"})
So I have gotten everything set up as best I could following the instructions on the GitHub main page and can even get the image to render but I can't figure out how to get it to dynamically set the size. I tried the slimsy-picture tag but if I remove the height or width I get a "dived by 0 error" which means I have to force a size onto the picture and, depending on the picture, that warps it. I have tried the img data-srcset method but can't get the image to render and looking at the example I must, once again, set a size on it. I have tried to dig through the source code for the v6 example but I can't make heads or tails of it.
I don't want to be hard-coding image sizes as that defeats the purpose of responsive design and if I hard code say 423x423 for an image it will look fine on a desktop but then on mobile it takes up to much space.
Is there a more beginner friendly example and explanation of how to get Slimsy working?
Is Slimsy even meant for what I want (I only know of Simly cause I was asking in a discord how to dynamically resize RTE images and someone said to use this program)?
I know I have asked a few, probably stupid, questions already but I am not an expert at programming by far so any guidance, explained for a very stupid person, would be appreciated.
Using the following in Umbraco 12 and query string for format= is matching the source file and not setting format=webp for conversion.
Appsettings as follows:
"Slimsy": {
"WidthStep": 180,
"UseCropAsSrc": true,
"DefaultQuality": 70,
"TagHelper": {
"SingleSources": [ "gif" ],
"DefaultPictureSources": [
{
"Extension": "webp",
"Quality": 70
}
],
"ImageDimensions": true
}
}
I am using Slimsy v1.1.7
I have an grid editor to insert some image boxes in the grid and futhermore option for the editors to set a height and width of the image, which will crop the image.
It also use LeBlender for this.
int width = 0;
int height = 0;
if (item.GetValue("width") != null)
{
width = Convert.ToInt32(item.GetValue("width"));
}
if (item.GetValue("height") != null)
{
height = Convert.ToInt32(item.GetValue("height"));
}
var url = image.GetResponsiveImageUrl(width, height);
however if width is zero it fails to generate the image: An attempt was made to divide by zero.
E.g. var url = image.GetResponsiveImageUrl(0, 240);
but not an issue height when height is zero.
In this case could it just ignore width or use the original width of the image?
This scale the image to 480px
in width
/media/1234/my-image.jpg?anchor=center&mode=crop&width=480&heightratio=0.6&format=jpg&quality=90&slimmage=true&rnd=131027199800000000
and with height to 100px
it crop is height to 100px.
/media/1234/my-image.jpg?anchor=center&mode=crop&width=480&height=100&heightratio=0.6&format=jpg&quality=90&slimmage=true&rnd=131027199800000000
When following the instructions, and installing Slimsy using
Install-Package Our.Umbraco.Slimsy -Version 3.0.0-beta3
the WebP plugin is NOT installed.
This is also not really clearly stated in the docs:
"Below is an example of how to use the
element to provide automated WebP versions of your images using the ImageProcessor WebP plugin, this example also implements an optional LQIP image."
I would suggest to state in the docs that the ImageProcessor.Plugins.WebP needs to be installed for Umbraco to deliver WebP, or better, include the plugin as a dependency of Slimsy.
Hi,
please see below the error message after installing the package Slimsy. It breaks during the installation process
Server Error in '/' Application.
Could not load all types from "Slimsy, Version=3.0.0.230, Culture=neutral, PublicKeyToken=null" due to LoaderExceptions, skipping:
. System.TypeLoadException on Umbraco.Core.Composing.IUserComposer: Could not load type 'Umbraco.Core.Composing.IUserComposer' from assembly 'Umbraco.Core, Version=1.0.6073.15895, Culture=neutral, PublicKeyToken=null'.
. System.TypeLoadException on Umbraco.Core.PackageActions.IPackageAction: Could not load type 'Umbraco.Core.PackageActions.IPackageAction' from assembly 'Umbraco.Core, Version=1.0.6073.15895, Culture=neutral, PublicKeyToken=null'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Reflection.ReflectionTypeLoadException: Could not load all types from "Slimsy, Version=3.0.0.230, Culture=neutral, PublicKeyToken=null" due to LoaderExceptions, skipping:
. System.TypeLoadException on Umbraco.Core.Composing.IUserComposer: Could not load type 'Umbraco.Core.Composing.IUserComposer' from assembly 'Umbraco.Core, Version=1.0.6073.15895, Culture=neutral, PublicKeyToken=null'.
. System.TypeLoadException on Umbraco.Core.PackageActions.IPackageAction: Could not load type 'Umbraco.Core.PackageActions.IPackageAction' from assembly 'Umbraco.Core, Version=1.0.6073.15895, Culture=neutral, PublicKeyToken=null'.
Would you consider adding support for the h descriptor? It is used with a number of lazysizes plugins. Ex. https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/parent-fit#lazysizes-parent-fit-extension
Hey @Jeavon, can you provide some guidance/documentation on the following issue (since upgradng)?
I can't work out what is needed in the appSettings configuration to configure this...
I am trying to figure out how to make images inserted into the Umbraco RTE responsive and I think your package can do this but the only documentation on using your package with the RTE just says"
but I have no idea what any of those parameters are, what options they have, and how to adjust the width/height of displayed images depending on resolution with that. Is there clear documentation on how to use this with RTE or is this not the right package for me to be looking at?
This is on Umbraco 8.6
On my DocType ContentPage
, I have a RichText property editor with alias RichTextTest
. When I do this in a view:
@Html.ConvertImgToSrcSet(Model, ContentPage.GetModelPropertyType(m => m.RichTextTest).Alias)
then I get a System.MissingMethodException
. I get the exception whether there are images in the RTE or not.
I can use Slimsy's other methods like GetCropUrl
and GetSrcSetUrls
without trouble.
My Image
media type has the Upload
property set to Image Cropper
.
Any idea what I am doing wrong? Is this a bug or user error?
On Our, David Peck suggested it might be related to the constructor having been removed (see here) in Umbraco. However, it could also be related to me doing something wrong which would cause the code to try and call the wrong constructor. The strange thing is, I remember using ConvertImgToSrcSet in a somewhat similar scenario and it worked back then.
Here is the complete error trace:
[MissingMethodException: Method not found: 'Void Umbraco.Web.PropertyEditors.ValueConverters.RteMacroRenderingValueConverter..ctor(Umbraco.Web.IUmbracoContextAccessor, Umbraco.Web.Macros.IMacroRenderer)'.]
Slimsy.Slimsy.ConvertImgToSrcSet(HtmlHelper htmlHelper, String sourceValueHtml, Boolean generateLqip, Boolean removeStyleAttribute) +0
Slimsy.Slimsy.ConvertImgToSrcSet(HtmlHelper htmlHelper, IPublishedContent publishedContent, String propertyAlias, Boolean generateLqip, Boolean removeStyleAttribute) +58
ASP._Page_Views_ContentPage_cshtml.Execute() in C:\Users\Mikael\source\U8_1\Web\Views\ContentPage.cshtml:27
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +78
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in D:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:25
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +291
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass3_6.<BeginInvokeAction>b__4() +198
System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +11
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +45
System.Web.Mvc.<>c.<BeginExecute>b__151_2(IAsyncResult asyncResult, Controller controller) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +28
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +577
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +132
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163
When I try to apply slimsy on image tag in v3 on image tag srcset
attribute will automatically created but in v2 it's not created. Please see my code for Slimsy v3 & v2
<img data-srcset="@Url.GetSrcSetUrls(Model.PageContentPrimaryImage, new AspectRatio(2, 3)).ToHtmlString()" data-src="@Url.GetCropUrl(Model.PageContentPrimaryImage, quality: 99)" sizes="auto" class="lazyload" />
and after load the page I am getting result like this
In v3
<img data-srcset="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&width=1920&height=2880&format=auto&quality=80&rnd=132173430668530000 1920w" data-src="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&quality=99&rnd=132173430668530000" sizes="300" class="lazyautosizes lazyloaded" srcset="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&width=160&height=240&format=auto&quality=80&rnd=132173430668530000 1920w" src="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&quality=99&rnd=132173430668530000"/>
and in v2
<img data-srcset="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&width=1920&height=2880&format=auto&quality=80&rnd=132173430668530000 1920w" data-src="/media/adpfpobq/untitled_2-17-1.jpg?anchor=center&mode=crop&quality=99&rnd=132173430668530000" sizes="300" class="lazyautosizes lazyloaded" />
Hi,
I'm facing a strange issue.
When I add an alt attribute to the img tag, the image change size. Usually it small, but if I add more text in the "alt" tag, the image gets bigger.
My current workaround is to remove the attribute sizes="auto" but I guess this attribute shouldn't be removed?
Thank you in advance for the help,
Thomas
Hi,
I've been trying to install v3 into an Umbraco 8.6.2 site but the installation fails with the following error:
Install failed. Rolling back... Package 'Our.Umbraco.Slimsy.3.0.0 : UmbracoCms.Core [8.6.0, 8.99999.0), UmbracoCms.Web [8.6.0, 8.99999.0)' does not exist in project '*' Removing package 'Our.Umbraco.Slimsy.3.0.0 : UmbracoCms.Core [8.6.0, 8.99999.0), UmbracoCms.Web [8.6.0, 8.99999.0)' from folder '*' Removed package 'Our.Umbraco.Slimsy.3.0.0 : UmbracoCms.Core [8.6.0, 8.99999.0), UmbracoCms.Web [8.6.0, 8.99999.0)' from folder '*'
Hello,
I am using slimsy in umbraco v8.4 and slimsy v3.0.0-beta1 but after apply once image show blur but when I do inspect element then remove blur effect from image. Can you please explain what the issue.
Using slimsy from C# (not razor markup) is cumbersome, it would be helpful to have a version that does returns a plain string.
Hi Jeavon,
is Slimsy still useful for Umbraco 9, or are there new techniques in place to make it obsolete? WIll there be a Slimsy version for Umbraco 9?
Kind regards! Mikael
Hello for my website i use a hero background-image and it can be call if you can create a version for this using image-set().
https://developer.mozilla.org/en-US/docs/Web/CSS/image-set
Url need to be in "" and resolution need to be in x , dppx , dpi but not w.
Let's say I have uploaded a 700px width image. If my width step is 160px, it seems that it would be optimal if the URLs include 160, 320, 480, 640, and 700 pixel sizes.
Is there a way to currently do this?
Hello, I am using Slimsy with Umbraco File System Providers & Azure Blob Cache, when I have changed @Url.GetCropUrl to @SlimsyExtension.GetCropUrl the crop is getting ignored.
the following snippets works:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=" data-src="@Url.GetCropUrl(image, cropAlias: "Square - Small", useCropDimensions: true)" sizes="auto" alt="@(image.HasValue("alternateText") ? image.Value<string>("alternateText") : image.Name)" class="lazyload" /> <noscript><img src="@Url.GetCropUrl(image, cropAlias: "Square - Small", useCropDimensions: true)" alt="@(image.HasValue("alternateText") ? image.Value<string>("alternateText") : image.Name)" /></noscript>
The following ignore the crop and pull the default image even the crop is within the url parameters:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=" data-src="@Url.GetCropUrl(image, cropAlias: "Square - Small", useCropDimensions: true)" data-srcset="@Url.GetSrcSetUrls(image, cropAlias: "Square - Small")" sizes="auto" alt="@(image.HasValue("alternateText") ? image.Value<string>("alternateText") : image.Name)" class="lazyload" />
The following ignore the crop and pull the default image even the crop is within the url parameters:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=" data-src="@SlimsyExtensions.GetCropUrl(image, cropAlias: "Square - Small", useCropDimensions: true)" sizes="auto" alt="@(image.HasValue("alternateText") ? image.Value<string>("alternateText") : image.Name)" class="lazyload" />
using Umbraco 8.14.1
Slimsy 3.0.0
UmbracoFileSystemProviders.Azure 2.0.1
UmbracoFileSystemProviders.Azure.Media 2.0.1
ImageProcessor.Web.Plugins.AzureBlobCache 1.71
If you need more info/config please let me know.
Many Thanks.
Just had a usecase, where I needed to use ImageProcessors Tint module. But Umbracos further options parameter is not supported in Slimsy.
Hi Jeavon,
When I uninstall slimsy from the Umbraco Backend I receive numerous errors and the site won't load.
It's stating that the assembly still has references to Slimsy (and slimmage).
e.g. line 34: @using Slimsy;
How can I safely remove it from my Umbraco site?
Thank you & sincerely,
Laurens
Hi, I'm using Umbraco 11 with .NET 7, the nuget package adds correctly to the project, but the ".AddSlimsy()" is not being recognized on ConfigureServices method.
Slimsy namespace is recognized from "using", but service is not from IServiceCollection.
I saw from source code that the package .NET version is 6. Could this be the problem?
Hello,
My client like your plugin, but we want to go to the new version have you a plan for update.
For the moment we have a bug linked to your plugin because Umbraco update
[MissingMethodException: Méthode introuvable : 'Umbraco.Core.Models.PublishedContent.PublishedPropertyType Umbraco.Core.Models.PublishedContent.IPublishedProperty.get_PropertyType()'.]
Slimsy.Slimsy.GetSrcSetUrls(UrlHelper urlHelper, IPublishedContent publishedContent, String cropAlias, String propertyAlias, String outputFormat) +0
Slimsy.Slimsy.GetSrcSetUrls(UrlHelper urlHelper, IPublishedContent publishedContent, String cropAlias) +17
HEGFR.Web.Helpers.ImageHelper.GenerateHtmlImg(IPublishedContent image, String crop, CultureInfo culture, String htmlClass, UrlHelper url) in C:\HESSO\hegfr-web-umbraco\HEGFR.Web\Helpers\ImageHelper.cs:37
ASP._Page_Views_Partials_NewsEvents_NewsImageCardUrl_cshtml.Execute() in C:\HESSO\hegfr-web-umbraco\HEGFR.Web\Views\Partials\NewsEvents\NewsImageCardUrl.cshtml:30
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in d:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:25
System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +277
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData) +91
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model) +32
ASP._Page_Views_Components_TdcomponentNews_cshtml.Execute() in C:\HESSO\hegfr-web-umbraco\HEGFR.Web\Views\Components\TdcomponentNews.cshtml:52
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in d:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:25
System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +277
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData) +91
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model) +32
ASP._Page_Views_Components_ComponentInsertion_cshtml.Execute() in C:\HESSO\hegfr-web-umbraco\HEGFR.Web\Views\Components\ComponentInsertion.cshtml:10
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in d:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:25
System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +277
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData) +91
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName) +32
ASP._Page_Views_Home_cshtml.Execute() in C:\HESSO\hegfr-web-umbraco\HEGFR.Web\Views\Home.cshtml:14
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +78
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in d:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:25
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +290
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass3_6.<BeginInvokeAction>b__4() +198
System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +11
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +45
System.Web.Mvc.<>c.<BeginExecute>b__151_2(IAsyncResult asyncResult, Controller controller) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +28
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +576
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +132
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163
Thanks in advance,
When calling GetSrcSetUrls with a width / height greater than the provided images width / height you get an axception
Length cannot be less than zero.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at Slimsy.Slimsy.GetSrcSetUrls(UrlHelper urlHelper, IPublishedContent publishedContent, Int32 width, Int32 height, Nullable`1 imageCropMode, String outputFormat)
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at Umbraco.Core.Profiling.ProfilingView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)````
From what I can tell it's because you do a substring in the return statement that always assumes the string builder contains something, which if your size is bigger than the max width (ie, your image natural width) then it doesn't and so throws and index error as your requested substring will be a length of -1.
It'd be nice to be able to specify a "slimmer" srcset in specific use cases.
If I understand the code correctly, there's only one SlimsyOptions
with settings for WidthStep and MaxWidth, and you'd have to create the service manually to do it differently.
Maybe as simple as making those two optional parameters all the way. I think the remaining config options are already overridable?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.