Optionally displaying XHTML embedded elements that place marketing cookies

Vote:
 

Hi,

We are working on an Episerver 10 website where the visitor has the option to en/disable marketing cookies. For example, when you embed a Twitter or Youtube video in a XHTML field, when the video displays also cookies are set by those parties. So I am looking for a solution where:

  • a content editor can just embed Twitter or Youtube videos inside a rich text field without having to think about marketing cookies etc. They are already doing this, so nothing would need to change for that.
  • when displaying the contents of the XHTML field, some controller or view logic should, in some way, rewrite the XHTML so that the Youtube/Twitter videos are not initially loaded/displayed. That decision should be made by either backend or Javascript code, based on the visitors setting for allowing marketing cookies. 

So I am looking for a generic solution to build this. My idea is to load the XHTML in a DOM and process it, rewriting certain embedded elements ie using a DIV-element with data-attributes to indicate the original embed content. Anyone has some advice or experience with this type of problem and possible solutions?

Should we do this in the backend, in the frontend? Any advice or experiences is appreciated.

#189742
Edited, Mar 23, 2018 13:45
Vote:
 

Cool task!

I would do it backend, by hijacking the property

In appstart:

PropertyDataCollection.GetHandler = new GetPropertyDelegate(MyNameSpace.Rewriters.RewriteStuff);

public static PropertyData RewriteStuff(string name, PropertyDataCollection properties)
        {
            PropertyData propertyData = PropertyGetHandler.DefaultPropertyHandler(name, properties);

            if (propertyData != null &&
                propertyData.Type == PropertyDataType.LongString &&
                propertyData.Name != "GoogleAnalyticsCode" &&
                propertyData.Name != "ScriptCodeBodyStart" &&
                propertyData.Name != "CommerceMediaCollection" &&
                propertyData.IsNull == false
                )
            {
                Boolean dirty = false;

                string value = "";

                if (propertyData.Value is EPiServer.Core.XhtmlString)
                {
                    StringBuilder str = new StringBuilder();
                    foreach (var frag in ((EPiServer.Core.XhtmlString)propertyData.Value).Fragments)
                    {
                        try
                        {
                            string part = frag.GetEditFormat();
                            if (part == null)
                                part = frag.GetViewFormat();
                            checkStuff(ref part, ref dirty);
                            str.Append(part);

                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex.Message, ex);
                            //System.Diagnostics.Debugger.Launch();
                        }
                    }

                    if (dirty)
                    {
                        EPiServer.Core.XhtmlString x = new XhtmlString(str.ToString());
                        PropertyData clone = propertyData.CreateWritableClone();
                        clone.Value = x;
                        propertyData = clone;
                    }
                }
            }

            return propertyData;
        }

Then implement your own checkstuff =)

It is on my list to blog about this, maybe now would be time.

Be carefull with this high end code ;)

#189747
Edited, Mar 23, 2018 14:53
Vote:
 

Hi Gosso,

Thanks for the idea! I am not familiar with this handler approach. Is this not also changing the contents of the XHTML field in the DB? Or is this only used when the property is read for viewing it like in a view? 

#189761
Mar 23, 2018 16:50
Vote:
 

Read only. Safe. And powerfull. 

#189763
Mar 23, 2018 16:53
Vote:
 

Hi GOSSO,

I am working on a proof of concept using your approach. I do not want to process all XhtmlString properties that are passed through the RewriteStuff method. So I created a custom Attrubute, ie [RewriteXhtml], which I put only only some of the XhtmlString properties I actually want to be processed. Now I have the problem that, in order to get the custom attributes of a property, I need the Page/Block type that is being processed in the RewriteStuff method. However, I only have access to the property name and the properties.

How would I be able to get the page or block type so that I can get the property and it custom attributes?   

#189788
Mar 24, 2018 11:37
Vote:
 

Look at Davids post for some ideas

Similar concept

https://www.david-tec.com/2017/11/tokenised-content-in-episerver/

regards

#189795
Mar 24, 2018 12:46
Vote:
 

Found out how to do it, however it is a bit cumbersome this way:

       private static bool ShouldProcess(PropertyDataCollection properties, string propName)
        {
            var pageIdData = properties["PageTypeID"];
            if (pageIdData == null)
            {
                return false;
            }
            int pageTypeId = Convert.ToInt32(pageIdData.Value);
            var contentType = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load(pageTypeId);
            var propInfo = contentType.ModelType.GetProperty(propName);
            return (propInfo != null) && propInfo.GetCustomAttributes(typeof(RewriteEmbeddedAttribute), true).Any();
        }

By checking this way, my code only tries to process/rewrite XhtmlString properties that are also decorated with the [RewriteEmbedded] attribute. However, I do not like having a hardcoded propertyname PageTypeID in there. But so far, I did not find a string constants for that in the EPI core....

#189796
Mar 24, 2018 13:02
Vote:
 

Still, the solution from Davids blog post is neat, here is the GIST https://gist.github.com/davidknipe/4dc89826ea00d4fc65df60965526b69d

#189841
Edited, Mar 26, 2018 10:45
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.