This is an examle of how to add a processor to the renderField pipeline to replace content authored text with preconfigured text.
Example:
Content author inputs:
Copyright © Some Company
This gist will override the output:
Copyright © Some Company
This is an examle of how to add a processor to the renderField pipeline to replace content authored text with preconfigured text.
Example:
Content author inputs:
Copyright © Some Company
This gist will override the output:
Copyright © Some Company
| #region GlassMapperSc generated code | |
| /************************************* | |
| DO NOT CHANGE THIS FILE - UPDATE GlassMapperScCustom.cs | |
| **************************************/ | |
| using Glass.Mapper.Maps; | |
| using Glass.Mapper.Sc.Configuration.Fluent; | |
| using Glass.Mapper.Sc.IoC; | |
| using Glass.Mapper.Sc.Pipelines.GetChromeData; | |
| using Sitecore.Pipelines; | |
| // WebActivator has been removed. If you wish to continue using WebActivator uncomment the line below | |
| // and delete the Glass.Mapper.Sc.CastleWindsor.config file from the Sitecore Config Include folder. | |
| // [assembly: WebActivatorEx.PostApplicationStartMethod(typeof(Recipe.App_Start.GlassMapperSc), "Start")] | |
| namespace Recipe.App_Start | |
| { | |
| using System; | |
| using Glass.Mapper.Sc.DataMappers; | |
| using Mappers; | |
| public class GlassMapperSc | |
| { | |
| public void Process(PipelineArgs args) | |
| { | |
| GlassMapperSc.Start(); | |
| } | |
| public static void Start() | |
| { | |
| //install the custom services | |
| var resolver = GlassMapperScCustom.CreateResolver(); | |
| //create a context | |
| var context = Glass.Mapper.Context.Create(resolver); | |
| LoadConfigurationMaps(resolver, context); | |
| context.Load( | |
| GlassMapperScCustom.GlassLoaders() | |
| ); | |
| GlassMapperScCustom.PostLoad(); | |
| //EditFrameBuilder.EditFrameItemPrefix = "Glass-"; | |
| } | |
| public static void LoadConfigurationMaps(IDependencyResolver resolver, Glass.Mapper.Context context) | |
| { | |
| var dependencyResolver = resolver as DependencyResolver; | |
| if (dependencyResolver == null) | |
| { | |
| return; | |
| } | |
| // Replace the existing string mapper | |
| dependencyResolver.DataMapperFactory?.Replace(21, () => new SitecoreFieldStringExtendedMapper()); | |
| if (dependencyResolver.ConfigurationMapFactory is ConfigurationMapConfigFactory) | |
| { | |
| GlassMapperScCustom.AddMaps(dependencyResolver.ConfigurationMapFactory); | |
| } | |
| IConfigurationMap configurationMap = new ConfigurationMap(dependencyResolver); | |
| SitecoreFluentConfigurationLoader configurationLoader = | |
| configurationMap.GetConfigurationLoader<SitecoreFluentConfigurationLoader>(); | |
| context.Load(configurationLoader); | |
| } | |
| } | |
| } | |
| #endregion |
| <?xml version="1.0"?> | |
| <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> | |
| <sitecore> | |
| <pipelines> | |
| <textReplacement> | |
| <processor type="Recipe.Pipelines.TextReplacement.TextReplacementProcessor, Recipe" singleInstance="true"> | |
| <textMappings hint="list"> | |
| <!-- | |
| All patterns and values must be encoded | |
| --> | |
| <trademark type="Recipe.Pipelines.TextReplacement.TextMapping, Recipe"> | |
| <pattern>(?<!<sup>)&reg;</pattern> | |
| <value><sup>&reg;</sup></value> | |
| </trademark> | |
| <copyright type="Recipe.Pipelines.TextReplacement.TextMapping, Recipe"> | |
| <pattern>(?<!<sup>)&copy;</pattern> | |
| <value><sup>&copy;</sup></value> | |
| </copyright> | |
| </textMappings> | |
| </processor> | |
| </textReplacement> | |
| <renderField> | |
| <processor patch:after="processor[@type='Sitecore.Pipelines.RenderField.GetTextFieldValue, Sitecore.Kernel']" | |
| type="Recipe.Pipelines.RenderField.RunTextReplacement, Recipe" resolve="true"/> | |
| </renderField> | |
| </pipelines> | |
| </sitecore> | |
| </configuration> |
| namespace Recipe.Pipelines.RenderField | |
| { | |
| using Sitecore.Abstractions; | |
| using Sitecore.Diagnostics; | |
| using Sitecore.Pipelines.RenderField; | |
| using TextReplacement; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| public class RunTextReplacement | |
| { | |
| /// <summary> | |
| /// Sitecore Pipeline Manager Implementation | |
| /// </summary> | |
| private readonly BaseCorePipelineManager _pipelineRunner; | |
| /// <summary> | |
| /// Field Types that can contain text that should be replaced | |
| /// </summary> | |
| private static readonly IList<string> AllowedFieldTypes = new[] { "rich text", "multi-line text", "single-line text" }; | |
| public RunTextReplacement(BaseCorePipelineManager pipelineRunner) | |
| { | |
| this._pipelineRunner = pipelineRunner; | |
| } | |
| /// <summary> | |
| /// Main method called within RenderField pipeline | |
| /// </summary> | |
| /// <param name="args"></param> | |
| public void Process(RenderFieldArgs args) | |
| { | |
| if (!this.CanFieldBeProcessed(args)) | |
| { | |
| return; | |
| } | |
| args.Result.FirstPart = this.ReplaceText(args.Result.FirstPart); | |
| } | |
| /// <summary> | |
| /// Verifies that the field being rendered should be processed | |
| /// </summary> | |
| /// <param name="args">The args</param> | |
| /// <returns><c>True</c> if the field data can be processed</returns> | |
| public virtual bool CanFieldBeProcessed(RenderFieldArgs args) | |
| { | |
| Assert.ArgumentNotNull(args, "args"); | |
| Assert.ArgumentNotNull(args.FieldTypeKey, "args.FieldTypeKey"); | |
| var fieldTypeKey = args.FieldTypeKey.ToLower(); | |
| return RunTextReplacement.AllowedFieldTypes.Any(f => f.Equals(fieldTypeKey)); | |
| } | |
| /// <summary> | |
| /// Replaces text within the Content by running the textReplacement pipeline | |
| /// </summary> | |
| /// <param name="content">The content</param> | |
| /// <returns>Content with values replaced</returns> | |
| public virtual string ReplaceText(string content) | |
| { | |
| if (String.IsNullOrEmpty(content)) | |
| { | |
| return content; | |
| } | |
| var args = new TextReplacementArgs | |
| { | |
| Content = content | |
| }; | |
| this._pipelineRunner.Run("textReplacement", args); | |
| return args.Content; | |
| } | |
| } | |
| } |
| namespace Recipe.Mappers | |
| { | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using Glass.Mapper.Sc; | |
| using Glass.Mapper.Sc.Configuration; | |
| using Glass.Mapper.Sc.DataMappers; | |
| using Sitecore.Data.Fields; | |
| public class SitecoreFieldStringExtendedMapper : SitecoreFieldStringMapper | |
| { | |
| /// <summary> | |
| /// Field Types that can contain text that should run through the RenderField pipeline | |
| /// </summary> | |
| private static readonly IList<string> AllowedFieldTypes = new[] { "rich text", "multi-line text", "single-line text" }; | |
| /// <summary> | |
| /// Gets the field. | |
| /// </summary> | |
| /// <param name="field">The field.</param> | |
| /// <param name="config">The config.</param> | |
| /// <param name="context">The context.</param> | |
| /// <returns>System.Object.</returns> | |
| public override object GetField(Field field, SitecoreFieldConfiguration config, SitecoreDataMappingContext context) | |
| { | |
| if (field == null) | |
| { | |
| return string.Empty; | |
| } | |
| if (config.Setting == SitecoreFieldSettings.RichTextRaw) | |
| { | |
| return field.Value; | |
| } | |
| if (config.Setting == SitecoreFieldSettings.ForceRenderField) | |
| { | |
| return this.RunPipeline(field); | |
| } | |
| var runRenderPipeline = AllowedFieldTypes.Any(type => field.TypeKey.Equals(type, StringComparison.InvariantCultureIgnoreCase)); | |
| return this.GetResult(field, runRenderPipeline); | |
| } | |
| /// <summary> | |
| /// Gets the Result of the Field | |
| /// </summary> | |
| /// <param name="field">The Field</param> | |
| /// <param name="runRenderPipeline"><c>True</c> if the field should run through the renderField pipeline.</param> | |
| /// <returns>The field value</returns> | |
| protected override string GetResult(Field field, bool runRenderPipeline) | |
| { | |
| return !runRenderPipeline ? field.Value : this.RunPipeline(field); | |
| } | |
| } | |
| } | |
| namespace Recipe.Pipelines.TextReplacement | |
| { | |
| using System; | |
| public class TextMapping | |
| { | |
| /// <summary> | |
| /// Gets or sets the Regex Pattern | |
| /// </summary> | |
| public string Pattern { get; set; } = String.Empty; | |
| /// <summary> | |
| /// Gets or sets the Value to replace the <see cref="Pattern"/> | |
| /// </summary> | |
| public string Value { get; set; } = String.Empty; | |
| } | |
| } |
| namespace Recipe.Pipelines.TextReplacement | |
| { | |
| using Sitecore.Pipelines; | |
| /// <summary> | |
| /// Pipeline Arguments for the textReplacement pipeline | |
| /// </summary> | |
| public class TextReplacementArgs : PipelineArgs | |
| { | |
| /// <summary> | |
| /// Gets or sets the content containing shortcodes | |
| /// </summary> | |
| public string Content { get; set; } | |
| } | |
| } |
| namespace Recipe.Pipelines.TextReplacement | |
| { | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Text.RegularExpressions; | |
| public class TextReplacementProcessor | |
| { | |
| /// <summary> | |
| /// Gets or sets the Text Mappings | |
| /// <para>Set by Sitecores Configuration Factory on instantiation</para> | |
| /// </summary> | |
| public virtual List<TextMapping> TextMappings { get; set; } = new List<TextMapping>(); | |
| /// <summary> | |
| /// Gets if the Context is currently editing | |
| /// </summary> | |
| public virtual bool IsEditing { get { return Sitecore.Context.PageMode.IsExperienceEditorEditing; } } | |
| /// <summary> | |
| /// Process the <see cref="args"/> and replaces markup based on the configured <see cref="TextMappings"/> | |
| /// </summary> | |
| /// <param name="args">The args to process</param> | |
| public virtual void Process(TextReplacementArgs args) | |
| { | |
| if (this.IsEditing || String.IsNullOrEmpty(args.Content)) | |
| { | |
| return; | |
| } | |
| if (!this.TextMappings.Any()) | |
| { | |
| return; | |
| } | |
| args.Content = this.TextMappings.Aggregate(args.Content, | |
| (content, mapping) => Regex.Replace(content, mapping.Pattern, mapping.Value)); | |
| } | |
| } | |
| } |