Skip to content

Instantly share code, notes, and snippets.

@KKings
Last active February 8, 2017 15:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KKings/7b1edac4b8bd2372909e233c0cf224d8 to your computer and use it in GitHub Desktop.
Save KKings/7b1edac4b8bd2372909e233c0cf224d8 to your computer and use it in GitHub Desktop.
Sitecore 8: Example recipe that replaces text within text fields based on a simple regex pattern and replacement value. Adds a new pipeline and adds an additional processor to the renderField pipeline.

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>(?&lt;!&lt;sup&gt;)&amp;reg;</pattern>
<value>&lt;sup&gt;&amp;reg;&lt;/sup&gt;</value>
</trademark>
<copyright type="Recipe.Pipelines.TextReplacement.TextMapping, Recipe">
<pattern>(?&lt;!&lt;sup&gt;)&amp;copy;</pattern>
<value>&lt;sup&gt;&amp;copy;&lt;/sup&gt;</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));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment