private static object LateBindHelperExpression(BindingContext context, string helperName, object[] arguments) { var configuration = context.Configuration; if (configuration.Helpers.TryGetValue(helperName, out var helper)) { using (var write = new PolledStringWriter(configuration.FormatProvider)) { helper(write, context.Value, arguments); return(write.ToString()); } } if (configuration.ReturnHelpers.TryGetValue(helperName, out var returnHelper)) { return(returnHelper(context.Value, arguments)); } var pureHelperName = helperName.Substring(1); foreach (var resolver in configuration.HelperResolvers) { if (resolver.TryResolveReturnHelper(pureHelperName, arguments.FirstOrDefault()?.GetType(), out returnHelper)) { return(returnHelper(context.Value, arguments)); } } throw new HandlebarsRuntimeException($"Template references a helper that is not registered. Could not find helper '{helperName}'"); }
internal Action <TextWriter, object> CompileView(string templatePath, InternalHandlebarsConfiguration configuration) { var fs = _configuration.FileSystem; if (fs == null) { throw new InvalidOperationException("Cannot compile view when configuration.FileSystem is not set"); } var template = fs.GetFileContent(templatePath); if (template == null) { throw new InvalidOperationException("Cannot find template at '" + templatePath + "'"); } IEnumerable <object> tokens; using (var sr = new StringReader(template)) { using (var reader = new ExtendedStringReader(sr)) { tokens = Tokenizer.Tokenize(reader).ToList(); } } var layoutToken = tokens.OfType <LayoutToken>().SingleOrDefault(); var expressionBuilder = new ExpressionBuilder(configuration); var expressions = expressionBuilder.ConvertTokensToExpressions(tokens); var compiledView = FunctionBuilder.Compile(expressions, configuration, templatePath); if (layoutToken == null) { return(compiledView); } var layoutPath = fs.Closest(templatePath, layoutToken.Value + ".hbs"); if (layoutPath == null) { throw new InvalidOperationException("Cannot find layout '" + layoutPath + "' for template '" + templatePath + "'"); } var compiledLayout = CompileView(layoutPath, configuration); return((tw, vm) => { string inner; using (var innerWriter = new PolledStringWriter(configuration.FormatProvider)) { compiledView(innerWriter, vm); inner = innerWriter.ToString(); } compiledLayout(tw, new DynamicViewModel(new[] { new { body = inner }, vm })); }); }