Skip to content

Commit 0446b6c

Browse files
committed
Liquid template engine (work in progress)
1 parent c77680a commit 0446b6c

12 files changed

Lines changed: 105 additions & 41 deletions

File tree

src/Libraries/SmartStore.Core/Collections/TreeNode.cs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Collections.ObjectModel;
45
using System.IO;
@@ -21,16 +22,22 @@ public TreeNode(TValue value)
2122
}
2223

2324
public TreeNode(TValue value, IEnumerable<TValue> children)
25+
: this(value)
2426
{
25-
Value = value;
26-
AppendRange(children);
27+
if (children != null && children.Any())
28+
{
29+
AppendRange(children);
30+
}
2731
}
2832

2933
public TreeNode(TValue value, IEnumerable<TreeNode<TValue>> children)
34+
: this(value)
3035
{
3136
// for serialization
32-
Value = value;
33-
AppendRange(children);
37+
if (children != null && children.Any())
38+
{
39+
AppendRange(children);
40+
}
3441
}
3542

3643
public TValue Value
@@ -178,7 +185,11 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
178185
reader.Read();
179186
}
180187

181-
var treeNode = Activator.CreateInstance(objectType, new object[] { objValue, objChildren });
188+
var ctorParams = objChildren != null
189+
? new object[] { objValue, objChildren }
190+
: new object[] { objValue };
191+
192+
var treeNode = Activator.CreateInstance(objectType, ctorParams);
182193

183194
// Set Metadata
184195
if (metadata != null && metadata.Count > 0)
@@ -198,26 +209,39 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
198209

199210
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
200211
{
201-
var idProp = FastProperty.GetProperty(value.GetType(), "Id", PropertyCachingStrategy.Cached);
202-
var valueProp = FastProperty.GetProperty(value.GetType(), "Value", PropertyCachingStrategy.Cached);
203-
var childrenProp = FastProperty.GetProperty(value.GetType(), "Children", PropertyCachingStrategy.Cached);
204-
var metadataProp = FastProperty.GetProperty(value.GetType(), "Metadata", PropertyCachingStrategy.Cached);
205-
206212
writer.WriteStartObject();
207213
{
208-
writer.WritePropertyName("Id");
209-
serializer.Serialize(writer, idProp.GetValue(value));
214+
// Id
215+
if (GetPropValue("Id", value) is object o)
216+
{
217+
writer.WritePropertyName("Id");
218+
serializer.Serialize(writer, o);
219+
}
210220

221+
// Value
211222
writer.WritePropertyName("Value");
212-
serializer.Serialize(writer, valueProp.GetValue(value));
223+
serializer.Serialize(writer, GetPropValue("Value", value));
213224

214-
writer.WritePropertyName("Metadata");
215-
serializer.Serialize(writer, metadataProp.GetValue(value));
225+
// Metadata
226+
if (GetPropValue("Metadata", value) is IDictionary<string, object> dict && dict.Count > 0)
227+
{
228+
writer.WritePropertyName("Metadata");
229+
serializer.Serialize(writer, dict);
230+
}
216231

217-
writer.WritePropertyName("Children");
218-
serializer.Serialize(writer, childrenProp.GetValue(value));
232+
// Children
233+
if (GetPropValue("HasChildren", value) is bool b && b == true)
234+
{
235+
writer.WritePropertyName("Children");
236+
serializer.Serialize(writer, GetPropValue("Children", value));
237+
}
219238
}
220239
writer.WriteEndObject();
221240
}
241+
242+
private object GetPropValue(string name, object instance)
243+
{
244+
return FastProperty.GetProperty(instance.GetType(), name, PropertyCachingStrategy.Cached).GetValue(instance);
245+
}
222246
}
223247
}

src/Libraries/SmartStore.Core/Extensions/TypeExtensions.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ public static string AssemblyQualifiedNameWithoutVersion(this Type type)
2626
return null;
2727
}
2828

29-
public static bool IsSequenceType(this Type seqType)
29+
public static bool IsSequenceType(this Type type)
3030
{
31-
return seqType.IsArray || typeof(IEnumerable).IsAssignableFrom(seqType);
31+
if (type == typeof(string))
32+
return false;
33+
34+
return type.IsArray || typeof(IEnumerable).IsAssignableFrom(type);
3235
}
3336

3437
public static bool IsPredefinedSimpleType(this Type type)
@@ -37,6 +40,7 @@ public static bool IsPredefinedSimpleType(this Type type)
3740
{
3841
return true;
3942
}
43+
4044
if (type.IsEnum)
4145
{
4246
return true;

src/Libraries/SmartStore.Core/Templating/Liquid/Drops/TestDrop.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public object this[object key]
3939
if (key is string name)
4040
{
4141
var modelPrefix = _modelPrefix + name;
42-
var pi = FastProperty.GetProperty(_type, name)?.Property;
42+
var fastProp = FastProperty.GetProperty(_type, name);
43+
var pi = fastProp?.Property;
4344
bool invalid = false;
4445

4546
if (pi == null)
@@ -51,7 +52,7 @@ public object this[object key]
5152
{
5253
value = "{{ " + modelPrefix + " }}";
5354
}
54-
else if (pi.PropertyType.IsSequenceType())
55+
else if (fastProp.IsSequenceType)
5556
{
5657
var seqType = pi.PropertyType.GetGenericArguments()[0];
5758
if (typeof(BaseEntity).IsAssignableFrom(seqType))

src/Libraries/SmartStore.Core/Templating/Liquid/LiquidUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal static object CreateSafeObject(object value)
2929
{
3030
fn = x => new DictionaryDrop((IDictionary<string, object>)x);
3131
}
32-
else if (valueType.IsSequenceType() && !(value is string))
32+
else if (valueType.IsSequenceType())
3333
{
3434
var genericArgs = valueType.GetGenericArguments();
3535
var isEnumerable = genericArgs.Length == 1 && valueType.IsSubClass(typeof(IEnumerable<>));

src/Libraries/SmartStore.Services/Messages/New/MessageFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public virtual (QueuedEmail Email, dynamic Model) CreateMessage(MessageContext m
118118

119119
// Model tree
120120
var modelTree = _modelProvider.BuildModelTree(model);
121-
var modelTreeJson = JsonConvert.SerializeObject(modelTree, Formatting.Indented);
121+
var modelTreeJson = JsonConvert.SerializeObject(modelTree, Formatting.None);
122122
if (modelTreeJson != messageTemplate.LastModelTree)
123123
{
124124
messageContext.MessageTemplate.LastModelTree = modelTreeJson;

src/Presentation/SmartStore.Web/Administration/Views/Shared/EditorTemplates/CodeMirror.cshtml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@
55
Html.AddScriptParts(true,
66
cdn + "codemirror.min.js",
77
cdn + "addon/hint/show-hint.min.js",
8-
cdn + "addon/hint/xml-hint.min.js",
9-
cdn + "addon/hint/html-hint.min.js",
8+
//cdn + "addon/hint/xml-hint.min.js",
9+
//cdn + "addon/hint/html-hint.min.js",
10+
//cdn + "addon/hint/css-hint.min.js",
11+
cdn + "addon/hint/javascript-hint.min.js",
12+
cdn + "addon/fold/xml-fold.min.js",
13+
cdn + "addon/fold/foldcode.min.js",
14+
cdn + "addon/edit/closetag.min.js",
15+
cdn + "addon/edit/closebrackets.min.js",
16+
cdn + "addon/edit/matchtags.min.js",
1017
cdn + "addon/mode/multiplex.min.js",
1118
cdn + "addon/mode/overlay.min.js",
1219
cdn + "mode/xml/xml.min.js",
@@ -15,13 +22,13 @@
1522
cdn + "mode/htmlmixed/htmlmixed.min.js",
1623
cdn + "addon/selection/active-line.min.js",
1724
cdn + "addon/edit/matchbrackets.min.js",
18-
"~/Content/editors/CodeMirror/mode/liquid/liquid.js");
25+
"~/Content/editors/CodeMirror/liquid.js");
1926

2027
Html.AddCssFileParts(true,
2128
cdn + "codemirror.min.css",
2229
cdn + "addon/hint/show-hint.min.css",
2330
cdn + "theme/eclipse.min.css",
24-
"~/Content/editors/CodeMirror/mode/liquid/liquid.css");
31+
"~/Content/editors/CodeMirror/liquid.css");
2532
}
2633

2734
<script type="text/javascript">
@@ -35,8 +42,12 @@
3542
lineWrapping: true,
3643
tabSize: 2,
3744
smartIndent: true,
45+
matchTags: true,
3846
matchBrackets: true,
47+
autoCloseTags: true,
48+
autoCloseBrackets: true,
3949
styleActiveLine: true,
50+
extraKeys: { "Ctrl-Space": "autocomplete" },
4051
continueComments: "Enter"
4152
});
4253
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<MessageTemplate>
3+
<To>{{ Email.DisplayName }} &lt;{{ Email.Email }}&gt;</To>
4+
<Subject>{{ Store.Name }}. Neuer Blog-Kommentar</Subject>
5+
<Body><![CDATA[
6+
{% extends 'master' %}
7+
8+
{% block 'body' %}
9+
<p>
10+
Ein neuer Kommentar wurde zu dem Blog-Eintrag "{{ BlogComment.BlogPostTitle }}" abgegeben.
11+
</p>
12+
{% endblock %}
13+
]]></Body>
14+
</MessageTemplate>
15+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<MessageTemplate>
3+
<To>{{ Email.DisplayName }} &lt;{{ Email.Email }}&gt;</To>
4+
<Subject>{{ Store.Name }}. New blog comment</Subject>
5+
<Body><![CDATA[
6+
{% extends 'master' %}
7+
8+
{% block 'body' %}
9+
<p>
10+
A new blog comment has been created for blog post "{{ BlogComment.BlogPostTitle }}".
11+
</p>
12+
{% endblock %}
13+
]]></Body>
14+
</MessageTemplate>
15+

src/Presentation/SmartStore.Web/Content/editors/CodeMirror/mode/liquid/liquid.css renamed to src/Presentation/SmartStore.Web/Content/editors/CodeMirror/liquid.css

File renamed without changes.

src/Presentation/SmartStore.Web/Content/editors/CodeMirror/mode/liquid/liquid.js renamed to src/Presentation/SmartStore.Web/Content/editors/CodeMirror/liquid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ CodeMirror.defineMode("liquid", function (config, parserConfig) {
131131
// Immediately work off any autocompletion objects on the stack
132132
while (cc.length && cc[cc.length - 1].ac)
133133
cc.pop()();
134-
134+
135135
if (cx.marked) return cx.marked;
136136
return null;
137137
}

0 commit comments

Comments
 (0)