public void BuildEntityModel(ref EntityModel entityModel, IComponentPresentation cp, Localization localization) { using (new Tracer(entityModel, cp, localization)) { IFieldSet contextExpressionsFieldSet; if (cp.ExtensionData == null || !cp.ExtensionData.TryGetValue(Constants.ContextExpressionsKey, out contextExpressionsFieldSet)) { // No Context Expressions found; nothing to do. return; } ContextExpressionConditions conditions = new ContextExpressionConditions(); IField includeField; if (contextExpressionsFieldSet.TryGetValue("Include", out includeField)) { conditions.Include = includeField.Values.ToArray(); } IField excludeField; if (contextExpressionsFieldSet.TryGetValue("Exclude", out excludeField)) { conditions.Exclude = excludeField.Values.ToArray(); } entityModel.SetExtensionData(Constants.ContextExpressionsKey, conditions); } }
/// <summary> /// Determines whether a given Entity Model should be included based on the conditions specified on the Entity Model and the context. /// </summary> /// <param name="entity">The Entity Model to be evaluated.</param> /// <param name="localization">The context Localization</param> /// <returns><c>true</c> if the Entity should be included.</returns> public bool IncludeEntity(EntityModel entity, Localization localization) { using (new Tracer(entity)) { object ceExtensionData; if (entity.ExtensionData == null || !entity.ExtensionData.TryGetValue(Constants.ContextExpressionsKey, out ceExtensionData)) { // No Context Expressions defined for Entity: just include it. return true; } ContextExpressionConditions ceConditions = (ContextExpressionConditions) ceExtensionData; IDictionary<string, object> contextClaims = GetCachedContextClaims(localization); if (!EvaluateContextExpressionClaims(ceConditions.Include, true, contextClaims)) { Log.Debug("Include Context Expression conditions are not satisfied; suppressing Entity [{0}].", entity); return false; } if (!EvaluateContextExpressionClaims(ceConditions.Exclude, false, contextClaims)) { Log.Debug("Exclude Context Expression conditions are not satisfied; suppressing Entity [{0}].", entity); return false; } Log.Debug("All resolved Context Expression conditions are satisfied; keeping Entity [{0}].", entity); return true; } }
public virtual ActionResult Navigation(EntityModel entity, string navType, int containerSize = 0) { SetupViewData(entity, containerSize); INavigationProvider navigationProvider = SiteConfiguration.NavigationProvider; string requestUrlPath = Request.Url.LocalPath; Localization localization = WebRequestContext.Localization; NavigationLinks model; switch (navType) { case "Top": model = navigationProvider.GetTopNavigationLinks(requestUrlPath, localization); break; case "Left": model = navigationProvider.GetContextNavigationLinks(requestUrlPath, localization); break; case "Breadcrumb": model = navigationProvider.GetBreadcrumbNavigationLinks(requestUrlPath, localization); break; default: throw new DxaException("Unexpected navType: " + navType); } EntityModel sourceModel = (EnrichModel(entity) as EntityModel) ?? entity; model.XpmMetadata = sourceModel.XpmMetadata; model.XpmPropertyMetadata = sourceModel.XpmPropertyMetadata; return View(sourceModel.MvcData.ViewName, model); }
public virtual void BuildEntityModel(ref EntityModel entityModel, IComponentPresentation cp, Localization localization) { using (new Tracer(entityModel, cp, localization)) { MvcData mvcData = GetMvcData(cp); Type modelType = ModelTypeRegistry.GetViewModelType(mvcData); // NOTE: not using ModelBuilderPipeline here, but directly calling our own implementation. BuildEntityModel(ref entityModel, cp.Component, modelType, localization); entityModel.XpmMetadata.Add("ComponentTemplateID", cp.ComponentTemplate.Id); entityModel.XpmMetadata.Add("ComponentTemplateModified", cp.ComponentTemplate.RevisionDate.ToString("yyyy-MM-ddTHH:mm:ss")); entityModel.XpmMetadata.Add("IsRepositoryPublished", cp.IsDynamic ? "true" : "false"); entityModel.MvcData = mvcData; // add html classes to model from metadata // TODO: move to CreateViewModel so it can be merged with the same code for a Page/PageTemplate IComponentTemplate template = cp.ComponentTemplate; if (template.MetadataFields != null && template.MetadataFields.ContainsKey("htmlClasses")) { // strip illegal characters to ensure valid html in the view (allow spaces for multiple classes) entityModel.HtmlClasses = template.MetadataFields["htmlClasses"].Value.StripIllegalCharacters(@"[^\w\-\ ]"); } if (cp.IsDynamic) { // update Entity Identifier to that of a DCP entityModel.Id = GetDxaIdentifierFromTcmUri(cp.Component.Id, cp.ComponentTemplate.Id); } } }
protected virtual List<SyndicationItem> GetFeedItemsFromEntity(EntityModel entity) { List<SyndicationItem> items = new List<SyndicationItem>(); IEnumerable<Teaser> entityItems = GetEntityItems(entity); foreach(Teaser item in entityItems) { items.Add(GetSyndicationItemFromTeaser(item)); } return items; }
private IEnumerable<Teaser> GetEntityItems(EntityModel entity) { List<Teaser> res = new List<Teaser>(); //1. Check if entity is a teaser, if add it if (entity is Teaser) { res.Add((Teaser)entity); } else { //2. Second check if entity type is (semantically) a list, and if so, get its list items List<Teaser> items = GetTeaserListFromSemantics(entity); if (items != null) { res = items; } else { //3. Last resort, try to find some suitable properties using reflection Teaser teaser = new Teaser(); foreach (PropertyInfo pi in entity.GetType().GetProperties()) { switch (pi.Name) { case "Headline": case "Name": teaser.Headline = pi.GetValue(entity) as String; break; case "Date": DateTime? date = pi.GetValue(entity) as DateTime?; if (date != null) teaser.Date = date; break; case "Description": teaser.Text = pi.GetValue(entity) as String; break; case "Link": teaser.Link = pi.GetValue(entity) as Link; break; case "Url": string url = pi.GetValue(entity) as String; if (url != null) teaser.Link = new Link { Url = url }; break; } } if (teaser.Headline != null || teaser.Text != null || teaser.Link != null) { res.Add(teaser); } } } return res; }
public virtual ActionResult Entity(EntityModel entity, int containerSize = 0) { SetupViewData(entity, containerSize); ViewModel model = EnrichModel(entity); if (model is RedirectModel) { // Force a redirect (ASP.NET MVC doesn't allow child actions to redirect using RedirectResult) Response.StatusCode = (int) HttpStatusCode.Redirect; Response.RedirectLocation = ((RedirectModel) model).RedirectUrl; Response.End(); return null; } return View(model.MvcData.ViewName, model); }
public virtual void BuildEntityModel(ref EntityModel entityModel, IComponent component, Type baseModelType, Localization localization) { using (new Tracer(entityModel, component, baseModelType, localization)) { string[] schemaTcmUriParts = component.Schema.Id.Split('-'); SemanticSchema semanticSchema = SemanticMapping.GetSchema(schemaTcmUriParts[1], localization); // The semantic mapping may resolve to a more specific model type than specified by the View Model itself (e.g. Image instead of just MediaItem for Teaser.Media) Type modelType = semanticSchema.GetModelTypeFromSemanticMapping(baseModelType); MappingData mappingData = new MappingData { SemanticSchema = semanticSchema, EntityNames = semanticSchema.GetEntityNames(), TargetEntitiesByPrefix = GetEntityDataFromType(modelType), Content = component.Fields, Meta = component.MetadataFields, TargetType = modelType, SourceEntity = component, Localization = localization }; entityModel = (EntityModel)CreateViewModel(mappingData); entityModel.Id = GetDxaIdentifierFromTcmUri(component.Id); entityModel.XpmMetadata = GetXpmMetadata(component); if (entityModel is MediaItem && component.Multimedia != null && component.Multimedia.Url != null) { MediaItem mediaItem = (MediaItem)entityModel; mediaItem.Url = component.Multimedia.Url; mediaItem.FileName = component.Multimedia.FileName; mediaItem.FileSize = component.Multimedia.Size; mediaItem.MimeType = component.Multimedia.MimeType; } if (entityModel is Link) { Link link = (Link)entityModel; if (String.IsNullOrEmpty(link.Url)) { link.Url = SiteConfiguration.LinkResolver.ResolveLink(component.Id); } } } }
public void BuildEntityModel(ref EntityModel entityModel, IComponentPresentation cp, Localization localization) { // No post-processing of Entity Models needed }
/// <summary> /// Generates semantic markup (HTML/RDFa attributes) for a given property of a given Entity Model. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance on which the extension method operates.</param> /// <param name="entity">The Entity Model.</param> /// <param name="propertyName">The name of the property.</param> /// <param name="index">The index of the property value (for multi-value properties).</param> /// <returns>The semantic markup (HTML/RDFa attributes).</returns> public static MvcHtmlString DxaPropertyMarkup(this HtmlHelper htmlHelper, EntityModel entity, string propertyName, int index = 0) { return Markup.RenderPropertyAttributes(entity, propertyName, index); }
/// <summary> /// Generates semantic markup (HTML/RDFa attributes) for a given Entity Model. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance on which the extension method operates.</param> /// <param name="entity">The Entity Model to generate semantic markup for.</param> /// <returns>The HTML/RDFa attributes for the Entity. These should be included in an HTML start tag.</returns> public static MvcHtmlString DxaEntityMarkup(this HtmlHelper htmlHelper, EntityModel entity) { return Markup.RenderEntityAttributes(entity); }
/// <summary> /// Renders a given Entity Model. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance on which the extension method operates.</param> /// <param name="entity">The Entity to render.</param> /// <param name="containerSize">The size (in grid column units) of the containing element.</param> /// <returns>The rendered HTML or an empty string if <paramref name="entity"/> is <c>null</c>.</returns> public static MvcHtmlString DxaEntity(this HtmlHelper htmlHelper, EntityModel entity, int containerSize = 0) { if (entity == null) { return MvcHtmlString.Empty; } if (containerSize == 0) { containerSize = SiteConfiguration.MediaHelper.GridSize; } MvcData mvcData = entity.MvcData; using (new Tracer(htmlHelper, entity, containerSize, mvcData)) { string actionName = mvcData.ActionName ?? SiteConfiguration.GetEntityAction(); string controllerName = mvcData.ControllerName ?? SiteConfiguration.GetEntityController(); string controllerAreaName = mvcData.ControllerAreaName ?? SiteConfiguration.GetDefaultModuleName(); RouteValueDictionary parameters = new RouteValueDictionary(); int parentContainerSize = htmlHelper.ViewBag.ContainerSize; if (parentContainerSize == 0) { parentContainerSize = SiteConfiguration.MediaHelper.GridSize; } parameters["containerSize"] = (containerSize * parentContainerSize) / SiteConfiguration.MediaHelper.GridSize; parameters["entity"] = entity; parameters["area"] = controllerAreaName; if (mvcData.RouteValues != null) { foreach (string key in mvcData.RouteValues.Keys) { parameters[key] = mvcData.RouteValues[key]; } } MvcHtmlString result = htmlHelper.Action(actionName, controllerName, parameters); // If the Entity is being rendered inside a Region (typical), we don't have to transform the XPM markup attributes here; it will be done in DxaRegion. if (!(htmlHelper.ViewData.Model is RegionModel) && WebRequestContext.IsPreview) { result = new MvcHtmlString(Markup.TransformXpmMarkupAttributes(result.ToString())); } return result; } }
public bool IncludeEntity(EntityModel entity, Localization localization) { _evaluatedEntities.Add(entity); return !ExcludeEntityIds.Contains(entity.Id); }
public virtual ActionResult Entity(EntityModel entity, int containerSize = 0) { SetupViewData(entity, containerSize); EntityModel model = (EnrichModel(entity) as EntityModel) ?? entity; return View(model.MvcData.ViewName, model); }
/// <summary> /// Renders a given Entity Model. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance on which the extension method operates.</param> /// <param name="entity">The Entity to render.</param> /// <param name="viewName">The (qualified) name of the View used to render the entity. This overrides the View set in <see cref="EntityModel.MvcData"/>.</param> /// <param name="containerSize">The size (in grid column units) of the containing element.</param> /// <returns>The rendered HTML or an empty string if <paramref name="entity"/> is <c>null</c>.</returns> public static MvcHtmlString DxaEntity(this HtmlHelper htmlHelper, EntityModel entity, string viewName, int containerSize = 0) { MvcData mvcDataOverride = new MvcData(viewName); entity.MvcData.AreaName = mvcDataOverride.AreaName; entity.MvcData.ViewName = mvcDataOverride.ViewName; return htmlHelper.DxaEntity(entity, containerSize); }
public ActionResult List(EntityModel entity, int containerSize = 0) { // The List action is effectively just an alias for the general Entity action (we keep it for backward compatibility). return Entity(entity, containerSize); }
public void BuildEntityModel(ref EntityModel entityModel, IComponent component, Type baseModelType, Localization localization) { // No post-processing of Entity Models needed }
/// <summary> /// Renders a given Entity Model. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance on which the extension method operates.</param> /// <param name="entity">The Entity to render.</param> /// <param name="viewName">The (qualified) name of the View used to render the entity. This overrides the View set in <see cref="EntityModel.MvcData"/>.</param> /// <param name="containerSize">The size (in grid column units) of the containing element.</param> /// <returns>The rendered HTML or an empty string if <paramref name="entity"/> is <c>null</c>.</returns> public static MvcHtmlString DxaEntity(this HtmlHelper htmlHelper, EntityModel entity, string viewName, int containerSize = 0) { MvcData mvcDataOverride = new MvcData(viewName); MvcData orginalMvcData = entity.MvcData; MvcData tempMvcData = new MvcData(orginalMvcData) { AreaName = mvcDataOverride.AreaName, ViewName = mvcDataOverride.ViewName }; try { entity.MvcData = tempMvcData; return htmlHelper.DxaEntity(entity, containerSize); } finally { entity.MvcData = orginalMvcData; } }
/// <summary> /// Maps Form data (for an HTTP POST request) to properies of a given Entity Model and performs basic validation. /// </summary> /// <param name="model">The Entity Model to map the form data to.</param> /// <returns><c>true</c> if there is any form data to be mapped.</returns> protected bool MapRequestFormData(EntityModel model) { if (Request.HttpMethod != "POST") { return false; } // CSRF protection: If the anti CSRF cookie is present, a matching token must be in the form data too. const string antiCsrfToken = "__RequestVerificationToken"; if (Request.Cookies[antiCsrfToken] != null) { AntiForgery.Validate(); } Type modelType = model.GetType(); foreach (string formField in Request.Form) { if (formField == antiCsrfToken) { // This is not a form field, but the anti CSRF token (already validated above). continue; } PropertyInfo modelProperty = modelType.GetProperty(formField); if (modelProperty == null) { Log.Debug("Model [{0}] has no property for form field '{1}'", model, formField); continue; } string formFieldValue = Request.Form[formField]; ValidationAttribute validationAttr = modelProperty.GetCustomAttribute<ValidationAttribute>(); if (validationAttr != null) { try { validationAttr.Validate(formFieldValue, formField); } catch (ValidationException ex) { string validationMessage = ResolveValidationMessage(ex.Message, model); Log.Debug("Validation of property '{0}' failed: {1}", formField, validationMessage); ModelState.AddModelError(formField, validationMessage); continue; } } try { if (modelProperty.PropertyType == typeof (bool)) { // The @Html.CheckBoxFor method includes a hidden field with the original checkbox state, resulting in two boolean values (comma separated) formFieldValue = formFieldValue.Split(',')[0]; } modelProperty.SetValue(model, Convert.ChangeType(formFieldValue, modelProperty.PropertyType)); } catch (Exception ex) { Log.Debug("Failed to set Model [{0}] property '{1}' to value obtained from form data: '{2}'. {3}", model, formField, formFieldValue, ex.Message); ModelState.AddModelError(formField, ex.Message); } } return true; }
public void BuildEntityModel(ref EntityModel entityModel, IComponent component, Type baseModelType, Localization localization) { // Nothing to do here }
private List<Teaser> GetTeaserListFromSemantics(EntityModel entity) { Type type = entity.GetType(); bool isList = false; foreach (object attr in type.GetCustomAttributes(true)) { if (attr is SemanticEntityAttribute) { SemanticEntityAttribute semantics = (SemanticEntityAttribute)attr; isList = semantics.Vocab == ViewModel.SchemaOrgVocabulary && semantics.EntityName == "ItemList"; if (isList) { break; } } } if (isList) { foreach(PropertyInfo pi in type.GetProperties()) { if (pi.PropertyType == typeof(List<Teaser>)) { return pi.GetValue(entity) as List<Teaser>; } } } return null; }