public override DataTemplate SelectTemplate(Object item, DependencyObject container) { FrameworkElement element = container as FrameworkElement; if (element != null && item != null) { element.DataContext = item; InspectorNode node = item as InspectorNode; Type nodeType = node.Type; // Enums are handled differently if (nodeType.IsEnum) { nodeType = typeof(Enum); } //// The root has a especial case. //if (node.Parent == null) //{ // if (rootTemplateCache.DataTemplate == null) // rootTemplateCache.DataTemplate = element.FindResource(rootTemplateCache.Name) as DataTemplate; // return rootTemplateCache.DataTemplate; //} if (TypeTemplateMap.ContainsKey(nodeType)) { CachedTemplate cache = TypeTemplateMap[nodeType]; if (cache.DataTemplate == null) { cache.DataTemplate = element.FindResource(cache.Name) as DataTemplate; } return(cache.DataTemplate); } else if (typeof(GearConfig).IsAssignableFrom(nodeType)) { if (gearConfigTemplateCache.DataTemplate == null) { gearConfigTemplateCache.DataTemplate = element.FindResource(gearConfigTemplateCache.Name) as DataTemplate; } return(gearConfigTemplateCache.DataTemplate); } else { if (genericTemplateCache.DataTemplate == null) { genericTemplateCache.DataTemplate = element.FindResource(genericTemplateCache.Name) as DataTemplate; } return(genericTemplateCache.DataTemplate); } } return(null); }
public static CachedTemplate Parse(string input, bool bypass = false) { Guard.NotNull(input); CachedTemplate result; if (!bypass) { LockObject.EnterWriteLock(); try { if (Cache.TryGetValue(input, out result)) { return(result); } } finally { LockObject.ExitWriteLock(); } } Parser.TryParse(input, out var template, out var errorMessage); var error = TemplateError.Parse(errorMessage); result = new CachedTemplate(template, error); if (!bypass) { LockObject.EnterWriteLock(); try { Cache.Set(input, result); } finally { LockObject.ExitWriteLock(); } } return(result); }
public override async ValueTask <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context) { context.IncrementSteps(); var relativePath = (await Path.EvaluateAsync(context)).ToStringValue(); if (!relativePath.EndsWith(ViewExtension, StringComparison.OrdinalIgnoreCase)) { relativePath += ViewExtension; } if (_cachedTemplate == null || !string.Equals(_cachedTemplate.Name, System.IO.Path.GetFileNameWithoutExtension(relativePath), StringComparison.Ordinal)) { await _semaphore.WaitAsync(); try { if (_cachedTemplate == null || !string.Equals(_cachedTemplate.Name, System.IO.Path.GetFileNameWithoutExtension(relativePath), StringComparison.Ordinal)) { var fileProvider = context.Options.FileProvider; var fileInfo = fileProvider.GetFileInfo(relativePath); if (fileInfo == null || !fileInfo.Exists) { throw new FileNotFoundException(relativePath); } var content = ""; using (var stream = fileInfo.CreateReadStream()) using (var streamReader = new StreamReader(stream)) { content = await streamReader.ReadToEndAsync(); } if (!_parser.TryParse(content, out var template, out var errors)) { throw new ParseException(errors); } var identifier = System.IO.Path.GetFileNameWithoutExtension(relativePath); _cachedTemplate = new CachedTemplate(template, identifier); } } finally { _semaphore.Release(); } } try { context.EnterChildScope(); if (With != null) { var with = await With.EvaluateAsync(context); context.SetValue(Alias ?? _cachedTemplate.Name, with); await _cachedTemplate.Template.RenderAsync(writer, encoder, context); } else if (AssignStatements != null) { var length = AssignStatements.Count; for (var i = 0; i < length; i++) { await AssignStatements[i].WriteToAsync(writer, encoder, context); } await _cachedTemplate.Template.RenderAsync(writer, encoder, context); } else if (For != null) { try { var forloop = new ForLoopValue(); var list = (await For.EvaluateAsync(context)).Enumerate(context).ToList(); var length = forloop.Length = list.Count; context.SetValue("forloop", forloop); for (var i = 0; i < length; i++) { context.IncrementSteps(); var item = list[i]; context.SetValue(Alias ?? _cachedTemplate.Name, item); // Set helper variables forloop.Index = i + 1; forloop.Index0 = i; forloop.RIndex = length - i - 1; forloop.RIndex0 = length - i; forloop.First = i == 0; forloop.Last = i == length - 1; await _cachedTemplate.Template.RenderAsync(writer, encoder, context); // Restore the forloop property after every statement in case it replaced it, // for instance if it contains a nested for loop context.SetValue("forloop", forloop); } } finally { context.LocalScope.Delete("forloop"); } } else { // no with, for or assignments, e.g. {% include 'products' %} await _cachedTemplate.Template.RenderAsync(writer, encoder, context); } } finally { context.ReleaseScope(); } return(Completion.Normal); }