Ejemplo n.º 1
0
        public void TestScriptObjectImport()
        {
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject));

                Assert.True(obj.ContainsKey("static_field_a"));
                Assert.Equal("ValueStaticFieldA", obj["static_field_a"]);
                Assert.True(obj.ContainsKey("static_field_b"));
                Assert.Equal("ValueStaticFieldB", obj["static_field_b"]);
                Assert.True(obj.ContainsKey("static_property_a"));
                Assert.Equal("ValueStaticPropertyA", obj["static_property_a"]);
                Assert.True(obj.ContainsKey("static_property_b"));
                Assert.Equal("ValueStaticPropertyB", obj["static_property_b"]);
                Assert.True(obj.ContainsKey("static_yoyo"));
                Assert.False(obj.ContainsKey("invalid"));
            }

            // Test MemberFilterDelegate
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject), filter: member => member.Name.Contains("Property"));

                Assert.False(obj.ContainsKey("static_field_a"));
                Assert.False(obj.ContainsKey("static_field_b"));
                Assert.True(obj.ContainsKey("static_property_a"));
                Assert.Equal("ValueStaticPropertyA", obj["static_property_a"]);
                Assert.True(obj.ContainsKey("static_property_b"));
                Assert.Equal("ValueStaticPropertyB", obj["static_property_b"]);
                Assert.False(obj.ContainsKey("static_yoyo"));
                Assert.False(obj.ContainsKey("invalid"));
            }

            // Test MemberRenamerDelegate
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject), renamer: member => member.Name);

                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticFieldA)));
                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticFieldB)));
                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticPropertyA)));
                Assert.Equal("ValueStaticPropertyA", obj[nameof(MyStaticObject.StaticPropertyA)]);
                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticPropertyB)));
                Assert.Equal("ValueStaticPropertyB", obj[nameof(MyStaticObject.StaticPropertyB)]);
                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticYoyo)));
                Assert.False(obj.ContainsKey(nameof(MyStaticObject.Invalid)));
            }

            {
                var obj = new ScriptObject();
                obj.Import(new MyObject2(), renamer: member => member.Name);

                Assert.Equal(9, obj.Count);
                Assert.True(obj.ContainsKey(nameof(MyStaticObject.StaticFieldA)));
                Assert.True(obj.ContainsKey(nameof(MyObject.PropertyA)));
                Assert.True(obj.ContainsKey(nameof(MyObject2.PropertyC)));
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Adds or updates a value
 /// </summary>
 /// <param name="scriptObject">Script object that is being updated</param>
 /// <param name="key">Key</param>
 /// <param name="value">Value</param>
 public static void AddOrUpdate(this ScriptObject scriptObject, string key, object value)
 {
     if (scriptObject.ContainsKey(key))
     {
         scriptObject[key] = value;
     }
     else
     {
         scriptObject.Add(key, value);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// <b>布局递归渲染器.</b><br />
        ///     例如, 给定一个 ScriptObject, 一个布局模板文件(解析过meta 的)<br />
        ///     本函数将把 ScriptObject 渲染至其中, 然后读取该布局文件的上层布局文件,<br />
        ///     在此把 ScriptObject 渲染至其中, 重复进行这一过程, 直到没有上层布局文件, 最后返回渲染结果 html<br />
        /// </summary>
        /// <returns></returns>
        public static string Render(ScriptObject pageModel, ScriptObject layoutPageModel)
        {
            var store = Engine.App.Store;

            var layoutContext = new TemplateContext()
            {
                TemplateLoader = store.TemplateLoader
            };
            var paginatorModel = Converter.ObjectToScriptObject(
                new
            {
                Page          = 1,
                Previous_Page = 0,
                Next_Page     = 2,
                Total_Pages   = 10
            }
                );

            // 0. 导入 pipe 函数
            layoutContext.BuiltinObject.Import(typeof(PipeFunctions));
            // 1. 将全局数据推送给模板
            layoutContext.PushGlobal(Converter.WrapScriptObject("site", store.SiteModel));
            layoutContext.PushGlobal(Converter.WrapScriptObject("content", pageModel["_content"]));
            layoutContext.PushGlobal(Converter.WrapScriptObject("page", new[]
            {
                pageModel,      // 2. 将内容的模板数据推送给模板
                layoutPageModel // 3. 将布局自身的模板数据推送给模板
            }));

            // 4. 对于分页的处理
            layoutContext.PushGlobal(Converter.WrapScriptObject("paginator", paginatorModel));
            var layoutTemplate   = Template.Parse(layoutPageModel.GetSafeValue <string>("_rawText"));
            var layoutResultHtml = layoutTemplate.Render(layoutContext);

            Logger.Info("* 渲染结束");
            // 判断是否需要递归渲染
            if (!layoutPageModel.ContainsKey("layout") || layoutPageModel.GetSafeValue <string>("layout") == "null")
            {
                return(layoutResultHtml);
            }
            var outLayoutShortName = layoutPageModel.GetSafeValue <string>("layout");

            Logger.Info("发现上级布局, 进行递归渲染. 布局文件为: " + layoutPageModel.GetSafeValue <string>("layout"));
            var outLayout = store.GetLayoutFromCache(outLayoutShortName);

            //Logger.Info(Logger.Indent(isRecRendering) + "递归渲染中, 当前层数: " + isRecRendering);
            isRecRendering++;
            pageModel["_content"] = layoutResultHtml;
            var html = Render(pageModel, outLayout);

            isRecRendering--;
            Logger.Info(Logger.Indent(isRecRendering) + "递归渲染结束, 层数: " + isRecRendering);
            return(html);
        }
        /// <summary>
        /// Collects the values for an export
        /// </summary>
        /// <param name="templateType">Template type</param>
        /// <param name="parsedTemplate">Parsed scriban template</param>
        /// <param name="scriptObject">Scriban script object to fill</param>
        /// <param name="data">Export Data</param>
        /// <returns>Task</returns>
        public override Task CollectValues(TemplateType templateType, Template parsedTemplate, ScriptObject scriptObject, ExportObjectData data)
        {
            List <DailyRoutineFunction> inputFunction = data.ExportData[ExportConstants.ExportDataObject] as List <DailyRoutineFunction>;

            if (inputFunction == null)
            {
                return(Task.CompletedTask);
            }

            List <ScribanExportDailyRoutineFunction> scribanFunctions = inputFunction.Select(i => new ScribanExportDailyRoutineFunction(i)).ToList();

            scriptObject.AddOrUpdate(ExportConstants.ScribanDailyRoutineFunctionListObjectKey, scribanFunctions);

            if (!scriptObject.ContainsKey(DailyRoutineEventFunctionRenderer.DailyRoutineEventFunctionName))
            {
                scriptObject.AddOrUpdate(DailyRoutineEventFunctionRenderer.DailyRoutineEventFunctionName, new DailyRoutineEventFunctionRenderer(_templatePlaceholderResolver, _cachedDbAccess, _defaultTemplateProvider, _errorCollection));
            }

            return(Task.CompletedTask);
        }
Ejemplo n.º 5
0
        public void TestScriptObjectImport()
        {
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject));

                Assert.That(obj, Does.ContainKey("static_field_a"));
                Assert.AreEqual("ValueStaticFieldA", obj["static_field_a"]);
                Assert.True(obj.ContainsKey("static_field_b"));
                Assert.AreEqual("ValueStaticFieldB", obj["static_field_b"]);
                Assert.True(obj.ContainsKey("static_property_a"));
                Assert.AreEqual("ValueStaticPropertyA", obj["static_property_a"]);
                Assert.True(obj.ContainsKey("static_property_b"));
                Assert.AreEqual("ValueStaticPropertyB", obj["static_property_b"]);
                Assert.True(obj.ContainsKey("static_yoyo"));
                Assert.False(obj.ContainsKey("invalid"));
            }

            // Check new overrides
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject2));

                Assert.True(obj.ContainsKey("static_yoyo"));
                var function = (IScriptCustomFunction)obj["static_yoyo"];
                var context  = new TemplateContext();
                var result   = function.Invoke(context, new ScriptFunctionCall(), new ScriptArray()
                {
                    "a"
                }, null);
                Assert.AreEqual("yoyo2 a", result);
            }

            // Test MemberFilterDelegate
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject), filter: member => member.Name.Contains("Property"));

                Assert.That(obj, Does.Not.ContainKey("static_field_a"));
                Assert.That(obj, Does.Not.ContainKey("static_field_b"));
                Assert.That(obj, Does.ContainKey("static_property_a"));
                Assert.AreEqual("ValueStaticPropertyA", obj["static_property_a"]);
                Assert.That(obj, Does.ContainKey("static_property_b"));
                Assert.AreEqual("ValueStaticPropertyB", obj["static_property_b"]);
                Assert.That(obj, Does.Not.ContainKey("static_yoyo"));
                Assert.That(obj, Does.Not.ContainKey("invalid"));
            }

            // Test MemberRenamerDelegate
            {
                var obj = new ScriptObject();
                obj.Import(typeof(MyStaticObject), renamer: member => member.Name);

                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticFieldA)));
                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticFieldB)));
                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticPropertyA)));
                Assert.AreEqual("ValueStaticPropertyA", obj[nameof(MyStaticObject.StaticPropertyA)]);
                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticPropertyB)));
                Assert.AreEqual("ValueStaticPropertyB", obj[nameof(MyStaticObject.StaticPropertyB)]);
                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticYoyo)));
                Assert.That(obj, Does.Not.ContainKey(nameof(MyStaticObject.Invalid)));
            }

            {
                var obj = new ScriptObject();
                obj.Import(new MyObject2(), renamer: member => member.Name);

                Assert.AreEqual(9, obj.Count);
                Assert.That(obj, Does.ContainKey(nameof(MyStaticObject.StaticFieldA)));
                Assert.That(obj, Does.ContainKey(nameof(MyObject.PropertyA)));
                Assert.That(obj, Does.ContainKey(nameof(MyObject2.PropertyC)));
            }
        }
Ejemplo n.º 6
0
 public bool HasGlobalValue(string name)
 {
     return(Globals.ContainsKey(name));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// This is similar to the Powershell command `ConvertFrom-StringData`, but uses the character "`" instead
        /// of "\"" as the escape character.
        ///
        /// For a list of characters that must be escaped, refer to
        /// the [MSDN documentation](https://msdn.microsoft.com/library/system.text.regularexpressions.regex.unescape)
        /// </summary>
        /// <param name="context">The template context.</param>
        /// <param name="span">The source span.</param>
        /// <param name="text">Text in the string data syntax.</param>
        /// <returns>
        /// An object representing key-value pairs of strings.
        /// </returns>
        /// <remarks>
        /// ```template-text
        /// {{ localized = include 'localization.txt' | object.from_string
        /// localized.foo
        /// }}
        /// ```
        /// ```html
        /// bar!
        /// ```
        /// </remarks>
        public static ScriptObject FromString(TemplateContext context, SourceSpan span, string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(new ScriptObject());
            }

            // char ` is our escape char
            // we need to escape `` so it turns out as `
            const string escapeChar       = "`";
            const string reservedSequence = escapeChar + escapeChar;

            // encodeAs is just an arbitary string. you don't need to escape encodeAs but choosing
            // something unique helps with the speed
            const string encodeAs = "^~^";

            string inputEscaped      = text.Replace(encodeAs, encodeAs + "2").Replace(reservedSequence, encodeAs + "1");
            string inputRegexEscaped = inputEscaped.Replace("\\", "\\\\").Replace(escapeChar, "\\");

            ScriptObject dataObj = new ScriptObject();

            string[] textLines = inputRegexEscaped.Split('\n');
            foreach (string textLine in textLines)
            {
                if (string.IsNullOrEmpty(textLine))
                {
                    continue;
                }

                string line = textLine.Trim();

                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }
                else if (line[0] == '#')
                {
                    continue;
                }

                const string kvpDelimiter      = "=";
                int          kvpDelimiterIndex = line.IndexOf(kvpDelimiter);

                if (kvpDelimiterIndex <= 0)
                {
                    throw new ScriptRuntimeException(span, RS.InvalidStringDataLine);
                }

                string itemName = line.Substring(0, kvpDelimiterIndex).Trim();
                // +1 is ok, b'cos we already know there is a = somewhere
                string itemRawValue = line.Substring(kvpDelimiterIndex + 1).TrimStart();
                string itemValue    = Regex.Unescape(itemRawValue).Replace(
                    encodeAs + "1", reservedSequence).Replace(
                    encodeAs + "2", encodeAs).Replace(
                    reservedSequence, escapeChar);

                if (dataObj.ContainsKey(itemName))
                {
                    dataObj[itemName] = itemValue;
                }
                else
                {
                    dataObj.Add(itemName, itemValue);
                }
            }

            return(dataObj);
        }