[#7729] Text tokens enhancements (#7730)

Fixes #7729
This commit is contained in:
Hermes Sbicego
2017-06-22 21:25:39 +02:00
committed by Sébastien Ros
parent 598b99871f
commit 044f079e28
2 changed files with 99 additions and 3 deletions

View File

@@ -152,7 +152,7 @@ namespace Orchard.Tokens.Providers {
chainIndex = token.IndexOf(").") + 1;
tokenLength = (tokenPrefix + ":").Length;
if (chainIndex == 0) { // ")." has not be found
return new Tuple<string, string>(token.Substring(tokenLength).Trim(new char[] { '(', ')' }), token.Length.ToString());
return new Tuple<string, string>(token.Substring(tokenLength).Trim(new char[] { '(', ')' }), "");
}
if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) {
return null;

View File

@@ -1,11 +1,15 @@
using System;
using System.Linq;
using System.Web;
using Orchard.Localization;
namespace Orchard.Tokens.Providers {
public class TextTokens : ITokenProvider {
private static string[] _textChainableTokens;
public TextTokens() {
T = NullLocalizer.Instance;
_textChainableTokens = new string[] { "Limit", "Format", "TrimEnd", "TrimStart" };
}
public Localizer T { get; set; }
@@ -15,6 +19,7 @@ namespace Orchard.Tokens.Providers {
.Token("Limit:*", T("Limit:<text length>[,<ellipsis>]"), T("Limit text to specified length and append an optional ellipsis text."))
.Token("Format:*", T("Format:<text format>"), T("Optional format specifier (e.g. foo{0}bar)."))
.Token("TrimEnd:*", T("TrimEnd:<chars|number>"), T("Trims the specified characters or number of them from the end of the string."))
.Token("TrimStart:*", T("TrimStart:<chars|number>"), T("Trims the specified characters or number of them from the beginning of the string."))
.Token("UrlEncode", T("Url Encode"), T("Encodes a URL string."), "Text")
.Token("HtmlEncode", T("Html Encode"), T("Encodes an HTML string."), "Text")
.Token("JavaScriptEncode", T("JavaScript Encode"), T("Encodes a JavaScript string."), "Text")
@@ -32,12 +37,18 @@ namespace Orchard.Tokens.Providers {
.Token(
token => FilterTokenParam("Limit:", token),
(token, t) => Limit(t, token))
.Chain(FilterChainLimitParam, "Text", (token, t) => Limit(t, token))
// {Text.Format:<formatstring>}
.Token(
token => FilterTokenParam("Format:", token),
(token, d) => String.Format(token, d))
.Chain(FilterChainFormatParam, "Text", (token, d) => String.Format(token, d))
// {Text.TrimEnd:<chars|number>}
.Token(token => FilterTokenParam("TrimEnd:", token), TrimEnd)
.Chain(FilterChainTrimEndParam, "Text", TrimEnd)
// {Text.TrimStart:<chars|number>}
.Token(token => FilterTokenParam("TrimStart:", token), TrimStart)
.Chain(FilterChainTrimStartParam, "Text", TrimStart)
.Token("UrlEncode", HttpUtility.UrlEncode)
.Chain("UrlEncode", "Text", HttpUtility.UrlEncode)
.Token("HtmlEncode", HttpUtility.HtmlEncode)
@@ -57,10 +68,95 @@ namespace Orchard.Tokens.Providers {
.Replace("\n", "<br />");
}
private static string FilterTokenParam(string tokenName, string token) {
return token.StartsWith(tokenName, StringComparison.OrdinalIgnoreCase) ? token.Substring(tokenName.Length) : null;
private Tuple<string, string> FilterChainLimitParam(string token) {
return FilterChainParam("Limit:", token);
}
private Tuple<string, string> FilterChainFormatParam(string token) {
return FilterChainParam("Format:", token);
}
private Tuple<string, string> FilterChainTrimEndParam(string token) {
return FilterChainParam("TrimEnd:", token);
}
private Tuple<string, string> FilterChainTrimStartParam(string token) {
return FilterChainParam("TrimStart:", token);
}
private static string FilterTokenParam(string tokenName, string token) {
if (!token.StartsWith(tokenName, StringComparison.OrdinalIgnoreCase)) return null;
string tokenPrefix;
int chainIndex, tokenLength;
if (token.IndexOf(":") == -1) {
tokenPrefix = token;
}
else {
tokenPrefix = token.Substring(0, token.IndexOf(":"));
}
if (!_textChainableTokens.Contains(tokenPrefix, StringComparer.OrdinalIgnoreCase)) {
return token.StartsWith(tokenName, StringComparison.OrdinalIgnoreCase) ? token.Substring(tokenName.Length) : 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 token.Substring(tokenLength).Trim(new char[] { '(', ')' });
}
if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) {
return null;
}
return token.Substring(tokenLength, chainIndex - tokenLength).Trim(new char[] { '(', ')' });
}
/// <summary>
///
/// </summary>
/// <param name="tokenName">The name of the Token (e.g. "Limit:")</param>
/// <param name="token">The entire Token (e.g. "Limit:(3).TrimStart:4")</param>
/// <returns>Tuple representing the token parameter and next tokens (e.g. for token "Limit:(3).TrimStart:4", first string have to be "3", second one have to be "TrimStart:4")</returns>
private static Tuple<string, string> FilterChainParam(string tokenName, string token) {
if (!token.StartsWith(tokenName, StringComparison.OrdinalIgnoreCase)) return null;
string tokenPrefix;
int chainIndex, tokenLength;
if (token.IndexOf(":") == -1) {
tokenPrefix = token;
}
else {
tokenPrefix = token.Substring(0, token.IndexOf(":"));
}
if (!_textChainableTokens.Contains(tokenPrefix, StringComparer.OrdinalIgnoreCase)) {
return new Tuple<string, string>(token, token);
}
// 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<string, string>(token.Substring(tokenLength).Trim(new char[] { '(', ')' }), "");
}
if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) {
return null;
}
return new Tuple<string, string>(token.Substring(tokenLength, chainIndex - tokenLength).Trim(new char[] { '(', ')' }), token.Substring(chainIndex + 1));
}
private static string TrimStart(string param, string token) {
if (string.IsNullOrEmpty(param)) {
return token;
}
int n;
if (!int.TryParse(param, out n)) {
return token.TrimStart(param.ToCharArray());
}
n = Math.Max(0, n); // prevent negative numbers
return token.Substring(n);
}
private static string TrimEnd(string param, string token) {
if (String.IsNullOrEmpty(param)) {
return token;