From 1b511b2692d1890b658b13f9dfd32f5caca3da09 Mon Sep 17 00:00:00 2001 From: HermesSbicego-Laser Date: Wed, 26 Oct 2016 18:50:35 +0200 Subject: [PATCH] - Implement what described in #6688 Supported Syntaxes for Request and Form tokens are: 1. QueryString:(param1) or Form:(param1) 2. QueryString:param1 or Form:param1 3. QueryString:(param1).SomeOtherTextToken or Form:(param1).SomeOtherTextToken If you want to Chain TextTokens you have to use the 3rd syntax the element (here param1) has been surrounded with brackets in order to preserve backward compatibility. --- .../Orchard.Tokens/Providers/RequestTokens.cs | 77 +++++++++++++++++-- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Tokens/Providers/RequestTokens.cs b/src/Orchard.Web/Modules/Orchard.Tokens/Providers/RequestTokens.cs index a8380cd3a83..5e30bd90f23 100644 --- a/src/Orchard.Web/Modules/Orchard.Tokens/Providers/RequestTokens.cs +++ b/src/Orchard.Web/Modules/Orchard.Tokens/Providers/RequestTokens.cs @@ -1,16 +1,21 @@ using System; +using System.Linq; using System.Web; using Orchard.ContentManagement; using Orchard.Localization; +using System.Globalization; +using System.Text.RegularExpressions; namespace Orchard.Tokens.Providers { public class RequestTokens : ITokenProvider { private readonly IWorkContextAccessor _workContextAccessor; private readonly IContentManager _contentManager; + private static string[] _textChainableTokens; public RequestTokens(IWorkContextAccessor workContextAccessor, IContentManager contentManager) { _workContextAccessor = workContextAccessor; _contentManager = contentManager; + _textChainableTokens = new string[] { "QueryString", "Form" }; T = NullLocalizer.Instance; } @@ -18,8 +23,8 @@ public class RequestTokens : ITokenProvider { public void Describe(DescribeContext context) { context.For("Request", T("Http Request"), T("Current Http Request tokens.")) - .Token("QueryString:*", T("QueryString:"), T("The Query String value for the specified element.")) - .Token("Form:*", T("Form:"), T("The Form value for the specified element.")) + .Token("QueryString:*", T("QueryString:"), T("The Query String value for the specified element. If you want ot chain text, surround the with brackets [e.g. QueryString:(param1)].")) + .Token("Form:*", T("Form:"), T("The Form value for the specified element. If you want ot chain text, surround the with brackets [e.g. Form:(param1)].")) .Token("Route:*", T("Route:"), T("The Route value for the specified key.")) .Token("Content", T("Content"), T("The request routed Content Item."), "Content") ; @@ -29,20 +34,30 @@ public class RequestTokens : ITokenProvider { if (_workContextAccessor.GetContext().HttpContext == null) { return; } - + /* Supported Syntaxes for Request and Form tokens are: + * 1. QueryString:(param1) or Form:(param1) + * 2. QueryString:param1 or Form:param1 + * 3. QueryString:(param1).SomeOtherTextToken or Form:(param1).SomeOtherTextToken + * + * If you want to Chain TextTokens you have to use 3rd syntax + * the element (here param1) has been surrounded with brackets in order to preserve backward compatibility. + */ context.For("Request", _workContextAccessor.GetContext().HttpContext.Request) .Token( - token => token.StartsWith("QueryString:", StringComparison.OrdinalIgnoreCase) ? token.Substring("QueryString:".Length) : null, - (token, request) => request.QueryString.Get(token) + FilterTokenParam, + (token, request) => { + return request.QueryString.Get(token); + } ) .Token( - token => token.StartsWith("Form:", StringComparison.OrdinalIgnoreCase) ? token.Substring("Form:".Length) : null, + FilterTokenParam, (token, request) => request.Form.Get(token) ) .Token( token => token.StartsWith("Route:", StringComparison.OrdinalIgnoreCase) ? token.Substring("Route:".Length) : null, (token, request) => GetRouteValue(token, request) ) + .Chain(FilterChainParam, "Text", (token, request) => request.QueryString.Get(token)) .Token("Content", (request) => DisplayText(GetRoutedContentItem(request)) ) @@ -98,5 +113,53 @@ public class RequestTokens : ITokenProvider { return _contentManager.GetItemMetadata(content).DisplayText; } + + private static string FilterTokenParam(string token) { + string tokenPrefix; + int chainIndex, tokenLength; + if (token.IndexOf(":") == -1) { + return null; + } + tokenPrefix = token.Substring(0, token.IndexOf(":")); + if (!_textChainableTokens.Contains(tokenPrefix, StringComparer.OrdinalIgnoreCase)) { + return null; + } + + // use ")." as chars combination to discover the end of the parameter + chainIndex = token.IndexOf(").") + 1; + tokenLength = (tokenPrefix + ":").Length; + if (chainIndex == 0) {// ")." has not be found + return Regex.Replace(token.Substring(tokenLength), @"[\(|\)]", ""); + } + if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) { + return null; + } + return Regex.Replace(token.Substring(tokenLength, chainIndex - tokenLength), @"[\(|\)]", ""); + } + private static Tuple FilterChainParam(string token) { + string tokenPrefix; + int chainIndex, tokenLength; + + if (token.IndexOf(":") == -1) { + return null; + } + tokenPrefix = token.Substring(0, token.IndexOf(":")); + if (!_textChainableTokens.Contains(tokenPrefix, StringComparer.OrdinalIgnoreCase)) { + return null; + } + + // use ")." as chars combination to discover the end of the parameter + chainIndex = token.IndexOf(").") + 1; + tokenLength = (tokenPrefix + ":").Length; + if (chainIndex == 0) { // ")." has not be found + return new Tuple(Regex.Replace(token.Substring(tokenLength), @"[\(|\)]", ""), token.Length.ToString()); + } + if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) { + return null; + } + return new Tuple(Regex.Replace(token.Substring(tokenLength, chainIndex - tokenLength), @"[\(|\)]", ""), token.Substring(chainIndex + 1)); + + } } -} \ No newline at end of file + +}