Try our conversational search powered by Generative AI!

Altering image attributes before displaying in CMS

Vote:
 

Hello. My team has just finished an integration task where all images are to be lazyloaded on the website. For the individual images, this involves adding a lazyload class and changing the src attribute to data-src. In the CMS, I was able to hook into the PublishEventInitializer to capture properties in the IContentData and determine if the value was an image. Then I would proceed to modify the attributes. The problem I am having is that because I changed the attribute to data-src, it doesn't render in the CMS anymore as it doesn't understand data-src. What I need is to be able to alter the images as they are pulled from the database before they display in the CMS TinyMCE editor and change the attribute back to src from data-src. BUT I only want to do this on the rendered image, I do not want to alter the value in the database ever. 

Is there a way to do this on the backend? Or do I need to capture the value somehow in Javascript? Thanks. 

#182984
Edited, Oct 03, 2017 0:17
Vote:
 

Are you talking about images in TinyMCE?

I usually change the XHtmlString to a replaced version by parsing it with HtmlAgilityPack.

Then you need to connect the replaced text from view model with content model, ex:

            var editHints = ViewData.GetEditHints<ArticleLikePageViewModel, ArticlePage>();
            editHints.AddConnection(m => m.ReplacedMainBody, p => p.MainBody);

The code itself would look sth like this:

        public XhtmlString FixXhtmlText(XhtmlString xhtmlString)
        {
            if (xhtmlString != null)
            {
                var doc = new HtmlDocument();
                doc.LoadHtml(xhtmlString.ToHtmlString());

                var images = doc.DocumentNode.SelectNodes("//img");

                if (images != null && images.Any())
                {
                    foreach (var image in images)
                    {
                        var src = iframe.Attributes["src"].Value;

                        var replacedImg = $"<img something something />";

                        var replacedImgNode = HtmlNode.CreateNode(replacedImg);

                        var parent = image.ParentNode ?? doc.DocumentNode;
                        parent.ReplaceChild(replacedImgNode, image);
                    }
                }

                var outerHtml = doc.DocumentNode.OuterHtml;
                return new XhtmlString(outerHtml);
            }

            return null;
        }

BR,
Marija

#182998
Oct 03, 2017 10:50
Vote:
 

Hello Marija, 

Thank you for your reply. Yes, I am talking about images in the TinyMCE. I have seen users drop an image in the main editor of the TinyMCE as well as use the insert/edit image button. 

Following your guidelines, I created a ContentBlockController and added the following code:

            ViewData.GetEditHints<ContentBlockVm, ContentBlock>()
                .AddConnection(m => m.Html, m => m.Editor);

Then I added a ContentBlockVmFactory to house the core logic:

        public XhtmlString FixText(XhtmlString xhtmlString)
        {
            if (xhtmlString == null)
                return null;

            var doc = new HtmlDocument();

            doc.LoadHtml(xhtmlString.ToHtmlString());

            var images = doc.DocumentNode.SelectNodes("//img");

            if (images != null && images.Any())
            {
                foreach (var image in images)
                {
                    var attributes = string.Empty;

                    foreach (var attribute in image.Attributes)
                    {
                        if (attribute.ToString() == "data-src")
                        {
                            attributes += " src=" + attribute.Value;
                        }
                        else
                        {
                            var value = attribute.Value == string.Empty ? " " : attribute.Value;
                            attributes += $" {attribute.Name}=\"{value}\"";
                        }
                    }

                    var replacedImg = $"<img {attributes} />";

                    var replacedImgNode = HtmlNode.CreateNode(replacedImg);

                    var parent = image.ParentNode ?? doc.DocumentNode;

                    parent.ReplaceChild(replacedImgNode, image);
                }
            }

            var outerHtml = doc.DocumentNode.OuterHtml;

            return new XhtmlString(outerHtml);
        }
    }

When I log into the CMS and select edit to view the home page, this code executes fine and does what I need it to do. However, when I click on any other page, this code doesn't execute again. Am I doing something wrong or do I need to hook into some other method? Thanks in advance. 

Scott

#183050
Oct 04, 2017 3:02
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.