public override void Render(Context context, TextWriter result) { var template = context[this._templateName].ToNullOrString(); if (template == null) { template = this._templateName; } context.Registers["layout"] = template; }
public override string PrepareTemplateContents(string content, Context context, string templateName) { var templatePage = new TemplatePage(content); templatePage.Body = templatePage.Body.Replace("{{ content }}", string.Format("{{% block {0}_content -%}}{{% endblock -%}}", templateName)); WrapWithTemplate(templatePage); return templatePage.Body; }
public void Render(Context context, TextWriter result) { object output = RenderInternal(context); if (output is ILiquidizable) output = null; if (output != null) { var transformer = Template.GetValueTypeTransformer(output.GetType()); if(transformer != null) output = transformer(output); //treating Strings as IEnumerable, and was joining Chars in loop string outputString = output as string; if (outputString != null) {} else if (output is IEnumerable) #if NET35 outputString = string.Join(string.Empty, ((IEnumerable)output).Cast<object>().Select(o => o.ToString()).ToArray()); #else outputString = string.Join(string.Empty, ((IEnumerable)output).Cast<object>()); #endif else if (output is bool) outputString = output.ToString().ToLower(); else outputString = output.ToString(); result.Write(outputString); }
public static Strainer Create(Context context) { Strainer strainer = new Strainer(context); foreach (var keyValue in Filters) strainer.Extend(keyValue.Value); return strainer; }
protected RequireSettings IncludeResource(string resourceType, string resourcePath, Context context) { var workContext = context.GetWorkContext(); var resourceManager = workContext.Resolve<IResourceManager>(); var pathResolver = workContext.Resolve<ITemplateItemProvidedPathResolver>(); var renderingContext = context.GetTemplateRenderingContext(); // If a template file is being rendered then resources paths can be used as usual from themes; if a // template item is rendered then relative virtual paths should be handled the same way (those reference // flat files). if (renderingContext.TemplateType == Models.TemplateType.TemplateFile || (resourcePath.StartsWith("~") && pathResolver.IsRealVirtualPath(resourcePath))) { var resourceRegister = new ResourceRegister( new DummyWebPage { VirtualPath = renderingContext.TemplatePath }, resourceManager, resourceType); return resourceRegister.Include(resourcePath); } else { if (!resourcePath.StartsWith("//") && !resourcePath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !resourcePath.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { resourcePath = pathResolver.GenerateUrlFromPath(resourcePath); } return resourceManager.Include(resourceType, resourcePath, resourcePath); } }
public override void Render(Context context, TextWriter result) { if (string.IsNullOrEmpty(_classNameParameter)) return; dynamic shape = context["Model"]; shape.Classes.Add(_classNameParameter.EvaluateAsStringProducingParameter(context)); }
public override void CompileTemplate(string templatePath) { var name = GetTemplateName(templatePath); var context = new Context(); var contents = Template.FileSystem.ReadTemplateFile(context, name); templatesByName[name] = Template.Parse(contents); }
/// <summary> /// 描画内容 /// </summary> /// <param name="context"></param> /// <param name="result"></param> public override void Render(Context context, TextWriter result) { // 获取所在区域,没有区域时抛例外 if (context[Area.CurrentAreaIdKey] == null) { throw new FormatException("widget must use inside area"); } // 获取模块名称和参数 var markup = this.Markup.Trim(); string widgetPath = null; string widgetArgs = null; var index = markup.IndexOf(' '); if (index > 0) { widgetPath = markup.Substring(0, index); widgetArgs = markup.Substring(index + 1); } else { widgetPath = markup; } // 添加div的开头 result.Write($"<div class='diy_widget' path='{widgetPath}' args='{widgetArgs}' >"); // 描画模块的内容 var scope = widgetArgs == null ? new Hash() : Hash.FromDictionary( JsonConvert.DeserializeObject<IDictionary<string, object>>(widgetArgs)); context.Stack(scope, () => { var includeTag = new Include(); var htmlPath = widgetPath + DiyWidgetInfo.HtmlExtension; includeTag.Initialize("include", htmlPath, null); includeTag.Render(context, result); }); // 添加div的末尾 result.Write("</div>"); }
public override void Render(DotLiquid.Context context, TextWriter result) { NavigationMenuItemDrop navigationMenuItemDrop = (NavigationMenuItemDrop)null; if (!this.contextProperty.IsBlank()) { object obj = context[this.contextProperty]; if (obj is int) { this.variantKeyFromMarkup = (int)obj; } else if (obj is NavigationMenuItemDrop) { navigationMenuItemDrop = obj as NavigationMenuItemDrop; } } if (navigationMenuItemDrop == null) { AbstractPage page = DependencyLocator.Current.GetInstance <IContentHelper>().GetPageByVariantKey(this.variantKeyFromMarkup, false).Page; navigationMenuItemDrop = !(page is ICatalogNavigationPage) ? this.CreateContentNavigationLink(DependencyLocator.Current.GetInstance <IContentHelper>(), page, this.viewNameFromMarkup, 0) : this.CreateCatalogNavigationLink(((ICatalogNavigationPage)page).CategoryNavRoot, this.viewNameFromMarkup, 0); } string str = DependencyLocator.Current.GetInstance <IContentItemTemplateRenderer>().RenderNavigationMenu(navigationMenuItemDrop); result.Write(str); }
public override void Render(Context context, TextWriter result) { var formName = (context[_formName] ?? _formName).ToString(); string actionUrl; if (_formsMap.TryGetValue(formName, out actionUrl)) { var themeEngine = (ShopifyLiquidThemeEngine)Template.FileSystem; var qs = HttpUtility.ParseQueryString(themeEngine.WorkContext.RequestUrl.Query); var returnUrl = qs["ReturnUrl"]; var actionAbsoluteUrl = themeEngine.UrlBuilder.ToAppAbsolute(actionUrl, themeEngine.WorkContext.CurrentStore, themeEngine.WorkContext.CurrentLanguage); if (!string.IsNullOrEmpty(returnUrl)) { actionAbsoluteUrl += string.Concat("?ReturnUrl=", HttpUtility.UrlEncode(returnUrl)); } result.WriteLine("<form accept-charset=\"UTF-8\" action=\"{0}\" method=\"post\" id=\"{1}\">", HttpUtility.HtmlAttributeEncode(actionAbsoluteUrl), HttpUtility.HtmlAttributeEncode(formName)); RenderAll(NodeList, context, result); result.WriteLine("</form>"); } else { throw new SyntaxException(string.Concat("Unknow form type ", _formName)); } }
public override void Render(Context context, TextWriter result) { var mutablePagedList = context[_collectionName] as IMutablePagedList; var collection = context[_collectionName] as ICollection; var pagedList = context[_collectionName] as IPagedList; Uri requestUrl; Uri.TryCreate(context["request_url"] as string, UriKind.RelativeOrAbsolute, out requestUrl); var pageNumber = (int)context["current_page"]; if (mutablePagedList != null) { mutablePagedList.Slice(pageNumber, _pageSize > 0 ? _pageSize : 20); pagedList = mutablePagedList; } else if (collection != null) { pagedList = new PagedList<Drop>(collection.OfType<Drop>().AsQueryable(), pageNumber, _pageSize); //TODO: Need find way to replace ICollection instance in liquid context to paged instance //var hash = context.Environments.FirstOrDefault(s => s.ContainsKey(_collectionName)); //hash[_collectionName] = pagedList; } if (pagedList != null) { var paginate = new Paginate(pagedList); context["paginate"] = paginate; for (int i = 1; i <= pagedList.PageCount; i++) { paginate.Parts.Add(new Part { IsLink = i != pagedList.PageNumber, Title = i.ToString(), Url = requestUrl != null ? requestUrl.SetQueryParameter("page", i.ToString()).ToString() : i.ToString() }); } RenderAll(NodeList, context, result); } }
public void Render(Context context, TextWriter result) { object output = RenderInternal(context); if (output is ILiquidizable) output = null; if (output != null) { // see if this context has a ValueTypeTranformer for the type var transformer = context.GetValueTypeTransformer(output.GetType()); if (transformer == null) { // if the context doesn't have a ValueTypeTranformer for the type, get the global one (if there is one) transformer = Template.GetValueTypeTransformer(output.GetType()); } if(transformer != null) output = transformer(output); string outputString; if (output is IEnumerable) #if NET35 outputString = string.Join(string.Empty, ((IEnumerable)output).Cast<object>().Select(o => o.ToString()).ToArray()); #else outputString = string.Join(string.Empty, ((IEnumerable)output).Cast<object>()); #endif else if (output is bool) outputString = output.ToString().ToLower(); else outputString = output.ToString(); result.Write(outputString); }
/// <summary> /// Gets the current person. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private static Person GetCurrentPerson(Context context) { Person currentPerson = null; // First check for a person override value included in lava context if (context.Scopes != null) { foreach (var scopeHash in context.Scopes) { if (scopeHash.ContainsKey("CurrentPerson")) { currentPerson = scopeHash["CurrentPerson"] as Person; } } } if (currentPerson == null) { var httpContext = System.Web.HttpContext.Current; if (httpContext != null && httpContext.Items.Contains("CurrentPerson")) { currentPerson = httpContext.Items["CurrentPerson"] as Person; } } return(currentPerson); }
public static string Display(Context context, dynamic input) { if (input == null || !(input is StaticShape)) return string.Empty; StaticShape shape = input; var wc = context.GetWorkContext(); // Checking if the shape is displayed multiple times. If yes it can be legitimate (although rare) but // can also indicate unwanted recursion, so capping it. if (shape.Shape.DisplayedCount == null) shape.Shape.DisplayedCount = 0; if (shape.Shape.DisplayedCount >= Constants.MaxAllowedShapeDisplayCount) { wc.LogSecurityNotificationWithContext(typeof(DisplayFilter), "Too many displays of the same shape prevented."); return string.Empty; } shape.Shape.DisplayedCount++; if (!context.ShapeIsWithinAllowedRecursionDepth(shape.Metadata.Type)) { wc.LogSecurityNotificationWithContext(typeof(DisplayFilter), "Too many recursive shape displays prevented."); return string.Empty; } context.AddCurrentShapeAsParentToShape((IShape)shape.Shape); return wc.Resolve<IShapeDisplay>().Display(shape.Shape); }
/// <summary> /// Primarily intended for testing. /// </summary> /// <param name="context"></param> /// <returns></returns> internal string Render(Context context) { using (MemoryStreamWriter result = new MemoryStreamWriter()) { Render(context, result); return result.ToString(); } }
/// <summary> /// Primarily intended for testing. /// </summary> /// <param name="context"></param> /// <returns></returns> internal string Render(Context context) { using (TextWriter result = new StringWriter()) { Render(context, result); return result.ToString(); } }
/// <summary> /// Properties the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <param name="propertyKey">The property key.</param> /// <param name="qualifier">The qualifier.</param> /// <returns></returns> public static object Property(DotLiquid.Context context, object input, string propertyKey, string qualifier = "") { if (input != null) { return(input.GetPropertyValue(propertyKey)); } return(string.Empty); }
public static string EvaluateAsStringProducingParameter(this string parameterValue, Context context) { var evaluatedParameter = parameterValue.EvaluateAsParameter(context); if (evaluatedParameter == null) return null; if (evaluatedParameter is string) return (string)evaluatedParameter; return evaluatedParameter.ToString(); }
public override void Render(Context context, TextWriter result) { // It's easier to fake every context and create a HtmlHelper to use the ClassForPage() extension. Note that // we also need to encode the output (and this is done in the ClassForPage() extension method)! context.WriteHtmlHelperOutputToResult( html => html.ClassForPage(GetEvaluatedParameters(context)), result); }
public override void Render(Context context, TextWriter result) { if (string.IsNullOrEmpty(_titleParameter)) return; context .GetWorkContext() .Resolve<IPageTitleBuilder>() .AddTitleParts(_titleParameter.EvaluateAsStringProducingParameter(context)); }
public string ReadTemplateFile(Context context, string templateName) { var include = Path.Combine(this.Root, "snippets", templateName); if (File.Exists(include)) { return File.ReadAllText(include); } return string.Empty; }
public string ReadTemplateFile(Context context, string templateName) { string includePath = Path.Combine(root, templateName); if (File.Exists(includePath)) return File.ReadAllText(includePath); return string.Empty; }
public IHttpActionResult Get(int seriesId) { var rockContext = new RockContext(); var contentItemService = new ContentChannelService(rockContext); var d = new DotLiquid.Context(); ContentChannel contentItem = null; var attrService = new AttributeService(rockContext); var dailyItems = new List<MessageArchiveItem>(); var ids = rockContext.Database.SqlQuery<int>("exec GetMessageArchivesBySeriesId @seriesId", new SqlParameter("seriesId", seriesId)).ToList(); contentItem = contentItemService.Get(11); var items = contentItem.Items.Where(a => ids.Contains(a.Id)).ToList(); foreach (var item in items) { item.LoadAttributes(rockContext); var link = GetVimeoLink(item.GetAttributeValue("VideoId")); var newItem = new MessageArchiveItem(); newItem.Id = item.Id; // newItem.Content = item.Content; newItem.Content = DotLiquid.StandardFilters.StripHtml(item.Content).Replace("\n\n", "\r\n\r\n"); newItem.Date = DateTime.Parse(item.GetAttributeValue("Date")).ToShortDateString(); newItem.Speaker = item.GetAttributeValue("Speaker"); newItem.SpeakerTitle = item.GetAttributeValue("SpeakerTitle"); newItem.Title = item.Title; newItem.VimeoLink = link; var notesAttr = item.Attributes["MessageNotes"]; var binaryFile = new BinaryFileService(new RockContext()).Get(notesAttr.Id); if (binaryFile != null) newItem.Notes = binaryFile.Url; var talkAttr = item.Attributes["TalkItOver"]; binaryFile = new BinaryFileService(new RockContext()).Get(talkAttr.Id); if (binaryFile != null) newItem.TalkItOver = binaryFile.Url; dailyItems.Add(newItem); } return Ok(dailyItems.AsQueryable()); }
public string ReadTemplateFile(DotLiquid.Context context, string templateName) { var include = Path.Combine(Root, "Includes", templateName); if (File.Exists(include)) { return(File.ReadAllText(include)); } return(string.Empty); }
/// <summary> /// 添加html到变量中,不重复添加 /// </summary> public override void Render(Context context, TextWriter result) { var css = context[Key] as string ?? ""; var html = string.Format( "<link href='{0}' rel='stylesheet' type='text/css' />\r\n", HttpUtility.HtmlAttributeEncode(Markup.Trim())); if (!css.Contains(html)) { css += html; context[Key] = css; } }
public override void Render(Context context, TextWriter result) { if (string.IsNullOrEmpty(_shapeType)) return; var wc = HttpContext.Current.GetWorkContext(); if (wc == null) return; result.Write(wc.Resolve<IShapeDisplay>().Display(wc.Resolve<IShapeFactory>().Create(_shapeType, Arguments.From(_arguments)))); }
/// <summary> /// 添加html到变量中,不重复添加 /// </summary> public override void Render(Context context, TextWriter result) { var js = context[Key] as string ?? ""; var html = string.Format( "<script src='{0}' type='text/javascript'></script>\r\n", HttpUtility.HtmlAttributeEncode(Markup.Trim())); if (!js.Contains(html)) { js += html; context[Key] = js; } }
public override void Render(Context context, TextWriter result) { var template = (context[this._templateName] ?? String.Empty).ToString(); if (String.IsNullOrEmpty(template)) { template = this._templateName; } context.Registers["layout"] = template; }
public static string Display(Context context, dynamic input) { if (input == null || !(input is StaticShape)) return string.Empty; StaticShape shape = input; var wc = HttpContext.Current.GetWorkContext(); if (wc == null) return string.Empty; return wc.Resolve<IShapeDisplay>().Display(shape.Shape); }
public string ReadTemplateFile(Context context, string templateName) { var templatePath = (string)context[templateName]; var resolver = context.Registers[Guid] as IResourceResolver; var resource = resolver.GetResource("~/" + templatePath + ".liquid"); using (var stream = resource.Open()) using (var reader = new StreamReader(stream)) return reader.ReadToEnd(); }
public override void Render(Context context, System.IO.TextWriter result) { result.Write("<blockquote>"); result.Write("<p>"); base.Render(context, result); result.Write("</p>"); result.Write(this.htmlAuthor); result.Write("</blockquote>"); }
public override void Render(Context context, TextWriter result) { try { base.Render(context, result); } catch (BreakInterrupt) { } catch (ContinueInterrupt) { } }
/// <summary> /// Gets the rock context. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private static RockContext GetRockContext(DotLiquid.Context context) { if (context.Registers.ContainsKey("rock_context")) { return(context.Registers["rock_context"] as RockContext); } else { var rockContext = new RockContext(); context.Registers.Add("rock_context", rockContext); return(rockContext); } }
public override void Render(Context context, TextWriter result) { var template = Templates.GetCached(_templatePath); var parameters = new Hash(); foreach (var assignment in _assignmentMap) { parameters.Add(assignment.Key, context[assignment.Value]); } result.Write(template.Render(parameters)); }
public string ReadTemplateFile(Context context, string templateName) { switch (templateName) { case "MasterTemplate": return CustomTemplates.MasterTemplate; case "PartialTemplate": return CustomTemplates.PartialTemplate; case "ChildTemplate": return CustomTemplates.ChildTemplate; default: throw new Exception("Template Not Found"); } }
public string ReadTemplateFile(DL.Context context, string templateName) { lock (Lock) { if (string.IsNullOrEmpty(templateName)) { throw new ArgumentNullException(nameof(templateName), "Template name must be set."); } var len = templateName.Length; templateName = templateName[0] == '"' ? templateName.Substring(1) : templateName; templateName = templateName[len - 1] == '"' ? templateName.Substring(0, len - 1) : templateName; return(_includes.ContainsKey(templateName) ? _includes[templateName] : "The key not found"); } }
public static ITracer GetTracer(this DotLiquid.Context context, Guid?sessionId = null) { sessionId = sessionId ?? Guid.NewGuid(); // get the tracer from context or create a new one via callback or use a default console tracer ITracer tracer = (context [TracerContextKey] as ITracer) ?? Tracer.GetCreateTracer?.Invoke(sessionId.Value) ?? new ConsoleTracer(sessionId.Value); if (context [TracerContextKey] != tracer) { context [TracerContextKey_SessionId] = sessionId.ToString(); context [TracerContextKey] = tracer; } return(tracer); }
public override void Render(DotLiquid.Context context, TextWriter result) { var pageContext = (PageContext.Current as PageContext); var contentController = pageContext.GetType().GetProperty("Controller", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(pageContext) as Controller; ViewContext viewContext = new ViewContext(contentController.ControllerContext, (IView) new FakeView(), contentController.ViewData, contentController.TempData, TextWriter.Null); ViewRenderer viewRenderer = new ViewRenderer((ControllerContext)viewContext); HtmlHelper htmlHelper = new HtmlHelper(viewContext, (IViewDataContainer) new ViewPage()); IContentHelper contentHelper = DependencyLocator.Current.GetInstance <IContentHelper>(); int parentVariantKey = contentHelper.GetPage("Home", false).Page.VariantKey.Value; BrasselerCatalogNavigationPage catalogNavItem = (BrasselerCatalogNavigationPage)contentHelper.GetChildPages <AbstractPage>(contentHelper.GetPage <HomePage>() .Page.ContentKey) .Where(o => !o.ExcludeFromNavigation && o.ContentKey.Equals(contentHelper.GetPage <BrasselerCatalogNavigationPage>().Page.ContentKey)) .FirstOrDefault(); MyAccountPage myAccountNavItem = (MyAccountPage)contentHelper.GetChildPages <AbstractPage>(contentHelper.GetPage <HomePage>().Page.ContentKey).Where(o => !o.ExcludeFromNavigation && o.ContentKey.Equals(contentHelper.GetPage <MyAccountPage>().Page.ContentKey)).FirstOrDefault(); result.Write("<ul>"); if (catalogNavItem != null) { string catalogThemedPartialPath = htmlHelper.GetThemedPartialPath(string.Format("{0}{1}.cshtml", (object)catalogNavItem.NavigationViewDirectory, (object)this.ViewName)); result.Write(viewRenderer.RenderPartialView(catalogThemedPartialPath, (object)catalogNavItem)); } if (myAccountNavItem != null) { if (!((SiteContext.Current.UserProfileDto != null) && (SiteContext.Current.BillTo.CustomerNumber.Length >= 1 && (SiteContext.Current.BillTo.CustomerNumber.Substring(1) == customSetting.Brasseler_GuestCustomerNumber)))) { string myAccountThemedPartialPath = htmlHelper.GetThemedPartialPath(string.Format("{0}{1}.cshtml", (object)myAccountNavItem.NavigationViewDirectory, (object)this.ViewName)); result.Write(viewRenderer.RenderPartialView(myAccountThemedPartialPath, (object)myAccountNavItem)); } } if (SiteContext.Current.UserProfileDto != null) { result.Write("<li style='float:right'> <a class='cms-linklist-linkitem' href='/QuickOrder'>[% translate 'Quick Order' %]</a></li>"); } result.Write("</ul>"); }
/// <summary> /// Loads a Group record from the database from it's Identifier. /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <returns></returns> public static Rock.Model.Group GroupById(DotLiquid.Context context, object input) { if (input == null) { return(null); } int groupId = -1; if (!Int32.TryParse(input.ToString(), out groupId)) { return(null); } var rockContext = new RockContext(); return(new GroupService(rockContext).Get(groupId)); }
/// <summary> /// Loads a Group Member record from the database from it's GUID. /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <returns></returns> public static Rock.Model.GroupMember GroupMemberByGuid(DotLiquid.Context context, object input) { if (input == null) { return(null); } Guid?groupMemberGuid = input.ToString().AsGuidOrNull(); if (groupMemberGuid.HasValue) { var rockContext = new RockContext(); return(new GroupMemberService(rockContext).Get(groupMemberGuid.Value)); } else { return(null); } }
public override void Render(DL.Context _context, System.IO.TextWriter _result) { if (null != m_Template) { try { var _renderParams = DL.RenderParameters.FromContext(_context); _result.Write(m_Template.Render(_renderParams)); } catch (Exception _err) { Log.E(_err); _result.Write("(error)"); } } else if (null != m_Content) { _result.Write(m_Content); } else { _result.Write("(null)"); } }
/// <summary> /// DotLiquid Attribute Filter /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <param name="attributeKey">The attribute key.</param> /// <param name="qualifier">The qualifier.</param> /// <returns></returns> public static object Attribute(DotLiquid.Context context, object input, string attributeKey, string qualifier = "") { if (input == null || attributeKey == null) { return(string.Empty); } // Try to get RockContext from the dotLiquid context var rockContext = GetRockContext(context); AttributeCache attribute = null; string rawValue = string.Empty; // If Input is "Global" then look for a global attribute with key if (input.ToString().Equals("Global", StringComparison.OrdinalIgnoreCase)) { var globalAttributeCache = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext); attribute = globalAttributeCache.Attributes .FirstOrDefault(a => a.Key.Equals(attributeKey, StringComparison.OrdinalIgnoreCase)); if (attribute != null) { // Get the value string theValue = globalAttributeCache.GetValue(attributeKey); // Global attributes may reference other global attributes, so try to resolve this value again rawValue = theValue.ResolveMergeFields(new Dictionary <string, object>()); } } // If input is an object that has attributes, find it's attribute value else if (input is IHasAttributes) { var item = (IHasAttributes)input; if (item.Attributes == null) { item.LoadAttributes(rockContext); } if (item.Attributes.ContainsKey(attributeKey)) { attribute = item.Attributes[attributeKey]; rawValue = item.AttributeValues[attributeKey].Value; } } // If valid attribute and value were found if (attribute != null && !string.IsNullOrWhiteSpace(rawValue)) { Person currentPerson = null; // First check for a person override value included in lava context if (context.Scopes != null) { foreach (var scopeHash in context.Scopes) { if (scopeHash.ContainsKey("CurrentPerson")) { currentPerson = scopeHash["CurrentPerson"] as Person; } } } if (currentPerson == null) { var httpContext = System.Web.HttpContext.Current; if (httpContext != null && httpContext.Items.Contains("CurrentPerson")) { currentPerson = httpContext.Items["CurrentPerson"] as Person; } } if (attribute.IsAuthorized(Authorization.VIEW, currentPerson)) { // Check qualifier for 'Raw' if present, just return the raw unformatted value if (qualifier.Equals("RawValue", StringComparison.OrdinalIgnoreCase)) { return(rawValue); } // Check qualifier for 'Url' and if present and attribute's field type is a ILinkableFieldType, then return the formatted url value var field = attribute.FieldType.Field; if (qualifier.Equals("Url", StringComparison.OrdinalIgnoreCase) && field is Rock.Field.ILinkableFieldType) { return(((Rock.Field.ILinkableFieldType)field).UrlLink(rawValue, attribute.QualifierValues)); } // If qualifier was specified, and the attribute field type is an IEntityFieldType, try to find a property on the entity if (!string.IsNullOrWhiteSpace(qualifier) && field is Rock.Field.IEntityFieldType) { IEntity entity = ((Rock.Field.IEntityFieldType)field).GetEntity(rawValue); if (entity != null) { if (qualifier.Equals("object", StringComparison.OrdinalIgnoreCase)) { return(entity); } else { return(entity.GetPropertyValue(qualifier).ToStringSafe()); } } } // Otherwise return the formatted value return(field.FormatValue(null, rawValue, attribute.QualifierValues, false)); } } return(string.Empty); }
/// <summary> /// Addresses the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <param name="addressType">Type of the address.</param> /// <param name="qualifier">The qualifier.</param> /// <returns></returns> public static string Address(DotLiquid.Context context, object input, string addressType, string qualifier = "") { if (input != null && input is Person) { var person = (Person)input; Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid(); var location = new GroupMemberService(GetRockContext(context)) .Queryable("GroupLocations.Location") .Where(m => m.PersonId == person.Id && m.Group.GroupType.Guid == familyGuid) .SelectMany(m => m.Group.GroupLocations) .Where(gl => gl.GroupLocationTypeValue.Value == addressType) .Select(gl => gl.Location) .FirstOrDefault(); if (location != null) { if (qualifier == "") { return(location.GetFullStreetAddress()); } else { var matches = Regex.Matches(qualifier, @"\[\[([^\]]+)\]\]"); foreach (var match in matches) { string propertyKey = match.ToString().Replace("[", ""); propertyKey = propertyKey.ToString().Replace("]", ""); propertyKey = propertyKey.ToString().Replace(" ", ""); switch (propertyKey) { case "Street1": qualifier = qualifier.Replace(match.ToString(), location.Street1); break; case "Street2": qualifier = qualifier.Replace(match.ToString(), location.Street2); break; case "City": qualifier = qualifier.Replace(match.ToString(), location.City); break; case "State": qualifier = qualifier.Replace(match.ToString(), location.State); break; case "PostalCode": case "Zip": qualifier = qualifier.Replace(match.ToString(), location.PostalCode); break; case "Country": qualifier = qualifier.Replace(match.ToString(), location.Country); break; case "GeoPoint": if (location.GeoPoint != null) { qualifier = qualifier.Replace(match.ToString(), string.Format("{0},{1}", location.GeoPoint.Latitude.ToString(), location.GeoPoint.Longitude.ToString())); } else { qualifier = qualifier.Replace(match.ToString(), ""); } break; case "Latitude": if (location.GeoPoint != null) { qualifier = qualifier.Replace(match.ToString(), location.GeoPoint.Latitude.ToString()); } else { qualifier = qualifier.Replace(match.ToString(), ""); } break; case "Longitude": if (location.GeoPoint != null) { qualifier = qualifier.Replace(match.ToString(), location.GeoPoint.Longitude.ToString()); } else { qualifier = qualifier.Replace(match.ToString(), ""); } break; case "FormattedAddress": qualifier = qualifier.Replace(match.ToString(), location.FormattedAddress); break; case "FormattedHtmlAddress": qualifier = qualifier.Replace(match.ToString(), location.FormattedHtmlAddress); break; default: qualifier = qualifier.Replace(match.ToString(), ""); break; } } return(qualifier); } } } return(string.Empty); }
/// <summary> /// Parses the markup. /// </summary> /// <param name="markup">The markup.</param> /// <param name="context">The context.</param> /// <returns></returns> private Dictionary <string, string> ParseMarkup(string markup, Context context) { // first run lava across the inputted markup var internalMergeFields = new Dictionary <string, object>(); // get variables defined in the lava source foreach (var scope in context.Scopes) { foreach (var item in scope) { internalMergeFields.AddOrReplace(item.Key, item.Value); } } // get merge fields loaded by the block or container if (context.Environments.Count > 0) { foreach (var item in context.Environments[0]) { internalMergeFields.AddOrReplace(item.Key, item.Value); } } var resolvedMarkup = markup.ResolveMergeFields(internalMergeFields); var parms = new Dictionary <string, string>(); parms.Add("iterator", string.Format("{0}Items", _entityName)); parms.Add("securityenabled", "true"); var markupItems = Regex.Matches(resolvedMarkup, @"(\S*?:'[^']+')") .Cast <Match>() .Select(m => m.Value) .ToList(); if (markupItems.Count == 0) { throw new Exception("No parameters were found in your command. The syntax for a parameter is parmName:'' (note that you must use single quotes)."); } foreach (var item in markupItems) { var itemParts = item.ToString().Split(new char[] { ':' }, 2); if (itemParts.Length > 1) { parms.AddOrReplace(itemParts[0].Trim().ToLower(), itemParts[1].Trim().Substring(1, itemParts[1].Length - 2)); } } // override any dynamic parameters List <string> dynamicFilters = new List <string>(); // will be used to process dynamic filters if (parms.ContainsKey("dynamicparameters")) { var dynamicParms = parms["dynamicparameters"]; var dynamicParmList = dynamicParms.Split(',') .Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x)) .ToList(); foreach (var dynamicParm in dynamicParmList) { if (HttpContext.Current.Request[dynamicParm] != null) { var dynamicParmValue = HttpContext.Current.Request[dynamicParm].ToString(); switch (dynamicParm) { case "id": case "limit": case "offset": case "dataview": case "expression": case "sort": case "iterator": case "checksecurity": case "includedeceased": case "securityenabled": { parms.AddOrReplace(dynamicParm, dynamicParmValue); break; } default: { dynamicFilters.Add(dynamicParm); break; } } } } parms.AddOrReplace("dynamicparameters", string.Join(",", dynamicFilters)); } return(parms); }
/// <summary> /// Renders the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="result">The result.</param> /// <exception cref="System.Exception">Your Lava command must contain at least one valid filter. If you configured a filter it's possible that the property or attribute you provided does not exist.</exception> public override void Render(Context context, TextWriter result) { // first ensure that entity commands are allowed in the context if (!this.IsAuthorized(context)) { result.Write(string.Format(RockLavaBlockBase.NotAuthorizedMessage, this.Name)); base.Render(context, result); return; } bool hasFilter = false; var modelName = string.Empty; // get a service for the entity based off it's friendly name if (_entityName == "business") { modelName = "Rock.Model.Person"; } else { modelName = "Rock.Model." + _entityName; } // Check first to see if this is a core model. use the createIfNotFound = false option var entityTypeCache = EntityTypeCache.Get(modelName, false); if (entityTypeCache == null) { var entityTypes = EntityTypeCache.All(); // If not, look for first plug-in model that has same friendly name entityTypeCache = entityTypes .Where(e => e.IsEntity && !e.Name.StartsWith("Rock.Model") && e.FriendlyName != null && e.FriendlyName.RemoveSpaces().ToLower() == _entityName) .OrderBy(e => e.Id) .FirstOrDefault(); // If still null check to see if this was a duplicate class and full class name was used as entity name if (entityTypeCache == null) { modelName = _entityName.Replace('_', '.'); entityTypeCache = entityTypes.Where(e => String.Equals(e.Name, modelName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); } } if (entityTypeCache != null) { Type entityType = entityTypeCache.GetEntityType(); if (entityType != null) { // Get the appropriate database context for this entity type. // Note that this may be different from the standard RockContext if the entity is sourced from a plug-in. var dbContext = Reflection.GetDbContextForEntityType(entityType); // Check if there is a RockContext in the Lava context. If so then use the RockContext passed in. if (dbContext is RockContext) { var lavaContext = context.Registers["RockContext"]; if (lavaContext.IsNotNull()) { dbContext = (DbContext)lavaContext; } } // Disable change-tracking for this data context to improve performance - objects supplied to a Lava context are read-only. dbContext.Configuration.AutoDetectChangesEnabled = false; // Create an instance of the entity's service IService serviceInstance = Reflection.GetServiceForEntityType(entityType, dbContext); ParameterExpression paramExpression = Expression.Parameter(entityType, "x"); Expression queryExpression = null; // the base expression we'll use to build our query from // Parse markup var parms = ParseMarkup(_markup, context); if (parms.Any(p => p.Key == "id")) { string propertyName = "Id"; List <string> selectionParms = new List <string>(); selectionParms.Add(PropertyComparisonConversion("==").ToString()); selectionParms.Add(parms["id"].ToString()); selectionParms.Add(propertyName); var entityProperty = entityType.GetProperty(propertyName); queryExpression = ExpressionHelper.PropertyFilterExpression(selectionParms, paramExpression, propertyName, entityProperty.PropertyType); hasFilter = true; } else { // where clause expression if (parms.Any(p => p.Key == "where")) { queryExpression = ParseWhere(parms["where"], entityType, serviceInstance, paramExpression, entityType, entityTypeCache); if (queryExpression != null) { hasFilter = true; } } // DataView expression if (parms.Any(p => p.Key == "dataview")) { var dataViewId = parms["dataview"].AsIntegerOrNull(); if (dataViewId.HasValue) { var dataViewExpression = GetDataViewExpression(dataViewId.Value, serviceInstance, paramExpression, entityTypeCache); if (queryExpression == null) { queryExpression = dataViewExpression; hasFilter = true; } else { queryExpression = Expression.AndAlso(queryExpression, dataViewExpression); } } } // process dynamic filter expressions (from the query string) if (parms.Any(p => p.Key == "dynamicparameters")) { var dynamicFilters = parms["dynamicparameters"].Split(',') .Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x)) .ToList(); foreach (var dynamicFilter in dynamicFilters) { var dynamicFilterValue = HttpContext.Current.Request[dynamicFilter]; var dynamicFilterExpression = GetDynamicFilterExpression(dynamicFilter, dynamicFilterValue, entityType, serviceInstance, paramExpression); if (dynamicFilterExpression != null) { if (queryExpression == null) { queryExpression = dynamicFilterExpression; hasFilter = true; } else { queryExpression = Expression.AndAlso(queryExpression, dynamicFilterExpression); } } } } } // Make the query from the expression. /* [2020-10-08] DL * "Get" is intentionally used here rather than "GetNoTracking" to allow lazy-loading of navigation properties from the Lava context. * (Refer https://github.com/SparkDevNetwork/Rock/issues/4293) */ MethodInfo getMethod = serviceInstance.GetType().GetMethod("Get", new Type[] { typeof(ParameterExpression), typeof(Expression), typeof(Rock.Web.UI.Controls.SortProperty), typeof(int?) }); if (getMethod != null) { // get a listing of ids and build it into the query expression if (parms.Any(p => p.Key == "ids")) { List <int> value = parms["ids"].ToString().Split(',').Select(int.Parse).ToList(); MemberExpression propertyExpression = Expression.Property(paramExpression, "Id"); ConstantExpression constantExpression = Expression.Constant(value, typeof(List <int>)); Expression containsExpression = Expression.Call(constantExpression, typeof(List <int>).GetMethod("Contains", new Type[] { typeof(int) }), propertyExpression); if (queryExpression != null) { queryExpression = Expression.AndAlso(queryExpression, containsExpression); } else { queryExpression = containsExpression; } hasFilter = true; } var getResult = getMethod.Invoke(serviceInstance, new object[] { paramExpression, queryExpression, null, null }); var queryResult = getResult as IQueryable <IEntity>; // process entity specific filters switch (_entityName) { case "person": { queryResult = PersonFilters((IQueryable <Person>)queryResult, parms); break; } case "business": { queryResult = BusinessFilters((IQueryable <Person>)queryResult, parms); break; } } // if there was a dynamic expression add it now if (parms.Any(p => p.Key == "expression")) { queryResult = queryResult.Where(parms["expression"]); hasFilter = true; } var queryResultExpression = queryResult.Expression; // add sort expressions if (parms.Any(p => p.Key == "sort")) { string orderByMethod = "OrderBy"; foreach (var column in parms["sort"].Split(',').Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList()) { string propertyName; var direction = SortDirection.Ascending; if (column.EndsWith(" desc", StringComparison.OrdinalIgnoreCase)) { direction = SortDirection.Descending; propertyName = column.Left(column.Length - 5); } else { propertyName = column; } string methodName = direction == SortDirection.Descending ? orderByMethod + "Descending" : orderByMethod; if (entityType.GetProperty(propertyName) != null) { // sorting a entity property var memberExpression = Expression.Property(paramExpression, propertyName); LambdaExpression sortSelector = Expression.Lambda(memberExpression, paramExpression); queryResultExpression = Expression.Call(typeof(Queryable), methodName, new Type[] { queryResult.ElementType, sortSelector.ReturnType }, queryResultExpression, sortSelector); } else { // sorting on an attribute // get attribute id int?attributeId = null; foreach (var attribute in AttributeCache.GetByEntityType(entityTypeCache.Id)) { if (attribute.Key == propertyName) { attributeId = attribute.Id; break; } } if (attributeId.HasValue) { // get AttributeValue queryable and parameter if (dbContext is RockContext) { var attributeValues = new AttributeValueService(dbContext as RockContext).Queryable(); ParameterExpression attributeValueParameter = Expression.Parameter(typeof(AttributeValue), "v"); MemberExpression idExpression = Expression.Property(paramExpression, "Id"); var attributeExpression = Attribute.Helper.GetAttributeValueExpression(attributeValues, attributeValueParameter, idExpression, attributeId.Value); LambdaExpression sortSelector = Expression.Lambda(attributeExpression, paramExpression); queryResultExpression = Expression.Call(typeof(Queryable), methodName, new Type[] { queryResult.ElementType, sortSelector.ReturnType }, queryResultExpression, sortSelector); } else { throw new Exception(string.Format("The database context for type {0} does not support RockContext attribute value queries.", entityTypeCache.FriendlyName)); } } } orderByMethod = "ThenBy"; } } // check to ensure we had some form of filter (otherwise we'll return all results in the table) if (!hasFilter) { throw new Exception("Your Lava command must contain at least one valid filter. If you configured a filter it's possible that the property or attribute you provided does not exist."); } // reassemble the queryable with the sort expressions queryResult = queryResult.Provider.CreateQuery(queryResultExpression) as IQueryable <IEntity>; if (parms.GetValueOrNull("count").AsBoolean()) { int countResult = queryResult.Count(); context.Scopes.Last()["count"] = countResult; } else { // Run security check on each result if enabled and entity is not a person (we do not check security on people) if (parms["securityenabled"].AsBoolean() && _entityName != "person") { var items = queryResult.ToList(); var itemsSecured = new List <IEntity>(); Person person = GetCurrentPerson(context); foreach (IEntity item in items) { ISecured itemSecured = item as ISecured; if (itemSecured == null || itemSecured.IsAuthorized(Authorization.VIEW, person)) { itemsSecured.Add(item); /* * 8/13/2020 - JME * It might seem logical to break out of the loop if there is limit parameter provided once the * limit is reached. This though has two issues. * * FIRST * Depending how it was implemented it can have the effect of breaking when an offset is * provided. * {% contentchannelitem where:'ContentChannelId == 1' limit:'3' %} * {% for item in contentchannelitemItems %} * {{ item.Id }} - {{ item.Title }}<br> * {% endfor %} * {% endcontentchannelitem %} * Returns 3 items (correct) * * {% contentchannelitem where:'ContentChannelId == 1' limit:'3' offset:'1' %} * {% for item in contentchannelitemItems %} * {{ item.Id }} - {{ item.Title }}<br> * {% endfor %} * {% endcontentchannelitem %} * Returns only 2 items (incorrect) - because of the offset * * SECOND * If the limit is moved before the security check it's possible that the security checks * will remove items and will therefore not give you the amount of items that you asked for. * * Unfortunately this has to be an inefficent process to ensure pagination works. I will also * add a detailed note to the documentation to encourage people to disable security checks, * especially when used with pagination, in the Lava docs. */ } } queryResult = itemsSecured.AsQueryable(); } // offset if (parms.Any(p => p.Key == "offset")) { queryResult = queryResult.Skip(parms["offset"].AsInteger()); } // limit, default to 1000 if (parms.Any(p => p.Key == "limit")) { queryResult = queryResult.Take(parms["limit"].AsInteger()); } else { queryResult = queryResult.Take(1000); } var resultList = queryResult.ToList(); // if there is only one item to return set an alternative non-array based variable if (resultList.Count == 1) { context.Scopes.Last()[_entityName] = resultList.FirstOrDefault(); } context.Scopes.Last()[parms["iterator"]] = resultList; } } } } else { result.Write(string.Format("Could not find a model for {0}.", _entityName)); base.Render(context, result); } base.Render(context, result); }