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 ;)
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?
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?
Look at Davids post for some ideas
Similar concept
https://www.david-tec.com/2017/11/tokenised-content-in-episerver/
regards
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....
Still, the solution from Davids blog post is neat, here is the GIST https://gist.github.com/davidknipe/4dc89826ea00d4fc65df60965526b69d
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:
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.