示例#1
0
        public PathData Find(string path, IStartPage root, ITargetingFilter targetingFilter, IHeadUrlResolver urlResolver)
        {
            path = urlResolver.SanitizeUrl(path);

            var tokens = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            if (tokens.Length == 0)
            {
                return(new PathData(root, path));
            }

            IAbstractItem stopItem      = root;
            IAbstractItem node          = root;
            string        remainingPath = path;
            int           index         = 0;

            foreach (var token in tokens)
            {
                if (StopCondition != null && StopCondition(node))
                {
                    break;
                }
                node = node.GetChildPageByAlias(token, targetingFilter);
                if (node == null)
                {
                    break;
                }
                index++;
                stopItem      = node;
                remainingPath = $"/{string.Join("/", tokens.Select((x, i) => i < index ? (string)null : x).Where(x => x != null))}";
            }

            return(new PathData(stopItem, remainingPath));
        }
        public BreadcrumbsViewModel(IAbstractItem currentPage, string additionalBreadcrumb)
        {
            var result = new List <BreadcrumbsItemViewModel>();

            if (additionalBreadcrumb != null)
            {
                result.Add(new BreadcrumbsItemViewModel {
                    Title = additionalBreadcrumb
                });
            }
            if (currentPage != null)
            {
                while (!(currentPage is IStartPage))
                {
                    if (currentPage.IsPage)
                    {
                        result.Add(new BreadcrumbsItemViewModel {
                            Title = currentPage.Title, Url = currentPage.GetUrl()
                        });
                    }
                    currentPage = currentPage.Parent;
                }
                if (result.Any())
                {
                    result.First().IsActive = true;
                    result.First().Url      = null;
                }
                result.Reverse();
            }
            Items = result;
        }
示例#3
0
 private void AddItemRecursive(IAbstractItem item)
 {
     _items[item.Id] = item;
     foreach (var child in item.GetChildren())
     {
         AddItemRecursive(child);
     }
 }
        public Task InvokeAsync(ViewComponentContext context)
        {
            IAbstractItem currentItem = context.ViewContext.HttpContext.GetCurrentRenderingWidgetContext()?.CurrentWidget;

            context.Arguments["currentItem"] = currentItem ?? throw new InvalidOperationException("Current item is null");

            return(_inner.InvokeAsync(context));
        }
示例#5
0
        public AbstractItemStorage(IAbstractItem root)
        {
            Root = root;
            AddItemRecursive(root);

            foreach (var startPage in Root.GetChildren().OfType <IStartPage>())
            {
                var dns = startPage.GetDNSBindings();
                Array.ForEach(dns, x => _startPageByDnsPatternMappings[x] = startPage);
            }
        }
 public override bool Match(IAbstractItem item)
 {
     foreach (var filter in filters)
     {
         if (!filter.Match(item))
         {
             return(false);
         }
     }
     return(true);
 }
        public string Map(IAbstractItem widget)
        {
            var name = widget.GetType().Name;

            switch (name)
            {
            case "TextPart": return(name);

            default:
                break;
            }

            return(null);
        }
        /// <summary>
        /// Запуск алгоритма
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public IReadOnlyList <TreeNode <IAbstractItem, V> > Run(IAbstractItem root)
        {
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }
            if (Depth <= 0)
            {
                throw new ArgumentException("The value of depth should be greater than 0.", nameof(Depth));
            }

            return(ProcessRecursive(root, Depth, 0)
                   .OrderBy(x => x.Item.SortOrder)
                   .ToList());
        }
示例#9
0
        public string Map(IAbstractItem widget)
        {
            var requestedType = widget.GetType();

            //будем искать компонент, помеченный типом переданного виджета или, если не найдём, то базовым для переданной страницы типом
            while (requestedType != typeof(object))
            {
                if (_componentMap.ContainsKey(requestedType))
                {
                    var componentName = _componentMap[requestedType].Name;
                    return(componentName.EndsWith("ViewComponent") ? componentName.Substring(0, componentName.Length - "ViewComponent".Length) : componentName);
                }
                requestedType = requestedType.BaseType;
            }
            return(null);
        }
示例#10
0
        public string Map(IAbstractItem page)
        {
            var name = page.GetType().Name;

            switch (name)
            {
            case "StartPage": return(name);

            case "TextPage": return(name);

            default:
                break;
            }

            return(null);
        }
示例#11
0
        /// <summary>
        /// Поиск элементов по условию. Применяется рекурсивный поиск по поддереву начальной страницы
        /// </summary>
        /// <param name="startPage">начальная страница для поиска</param>
        /// <param name="matchCriteria">условие поиска</param>
        /// <param name="depth">максимальная глубина поиска</param>
        /// <returns></returns>
        public IAbstractItem Find(IAbstractItem startPage,
                                  Func <IAbstractItem, bool> matchCriteria,
                                  int depth = 5)
        {
            var filter = TargetingFilterAccessor.Get() ?? new NullFilter();

            var alg = new RecursiveVisitorAlgorithm <object>((_, __) => null, filter, new DelegateFilter(matchCriteria))
            {
                IsFlatteringMode = true,
                Depth            = depth
            };

            var result = alg.Run(startPage).Select(x => x.Item);

            return(result.FirstOrDefault());
        }
示例#12
0
        public string Map(IAbstractItem page)
        {
            var requestedType = page.GetType();

            //будем искать контроллер, помеченный типом переданной страницы или, если не найдём, то базовым для переданной страницы типом
            while (requestedType != typeof(object))
            {
                if (_contollerMap.ContainsKey(requestedType))
                {
                    var contollerName = _contollerMap[requestedType].Name;
                    return(contollerName.EndsWith("Controller") ? contollerName.Substring(0, contollerName.Length - "Controller".Length) : contollerName);
                }
                requestedType = requestedType.BaseType;
            }
            return(null);
        }
 /// <summary>
 /// Определяем, что abstractItem принадлежит стартовой странице startPage
 /// </summary>
 private bool IsStartPageContainAbstractItem(IStartPage startPage, IAbstractItem abstractItem)
 {
     if (startPage == null || abstractItem == null)
     {
         return(false);
     }
     while (abstractItem.Parent != null)
     {
         if (abstractItem.Id == startPage.Id)
         {
             return(true);
         }
         abstractItem = abstractItem.Parent;
     }
     return(false);
 }
示例#14
0
        public override bool Match(IAbstractItem item)
        {
            if (item.IsPage)
            {
                return(false);
            }

            IAbstractWidget widget = item as IAbstractWidget;

            if (widget == null)
            {
                return(false);
            }

            if (!string.Equals(widget.ZoneName, _zone))
            {
                return(false);
            }

            if ((widget.AllowedUrlPatterns == null || widget.AllowedUrlPatterns.Length == 0) &&
                (widget.DeniedUrlPatterns == null || widget.DeniedUrlPatterns.Length == 0))
            {
                return(true);
            }

            if (widget.DeniedUrlPatterns != null && widget.DeniedUrlPatterns.Any())
            {
                var deniedMatcher = new WildcardMatcher(WildcardMatchingOption.FullMatch,
                                                        widget.DeniedUrlPatterns.Select(p => p.Trim('/')));
                if (deniedMatcher.Match(_url).Any())
                {
                    return(false);
                }
            }

            if (widget.AllowedUrlPatterns != null && widget.AllowedUrlPatterns.Any())
            {
                var allowedMatcher = new WildcardMatcher(WildcardMatchingOption.FullMatch,
                                                         widget.AllowedUrlPatterns.Select(p => p.Trim('/')));
                return(allowedMatcher.Match(_url).Any());
            }

            return(true);
        }
示例#15
0
        public override bool Match(IAbstractItem item)
        {
            var ctxVal = _ctx.GetTargetingValue(TargetingKeys.Culture);

            if (ctxVal == null || !(ctxVal is string))
            {
                return(true);
            }

            var val = item.GetTargetingValue(TargetingKeys.Culture);

            if (val == null || !(val is string))
            {
                return(true);
            }

            var ctxStrVal = ctxVal as string;
            var stringVal = val as string;

            return(String.IsNullOrWhiteSpace(stringVal) ? true : stringVal.Equals(ctxStrVal, StringComparison.InvariantCultureIgnoreCase));
        }
        protected IEnumerable <TreeNode <IAbstractItem, V> > ProcessRecursive(IAbstractItem item, int maxDepth, int currentDepth)
        {
            if (currentDepth <= maxDepth)
            {
                foreach (var child in item.GetChildren(_filter))
                {
                    var ch = TreeNode <IAbstractItem, V>
                             .CreateNode(child, _factory(child, currentDepth));

                    var isMatch = _matchFilter.Match(child);

                    if (IsFlatteringMode)
                    {
                        if (!IsReverseOrder && isMatch)
                        {
                            yield return(ch);
                        }

                        foreach (var subChild in ProcessRecursive(child, maxDepth, currentDepth + 1)
                                 .OrderBy(x => x.Item.SortOrder))
                        {
                            yield return(subChild);
                        }

                        if (IsReverseOrder && isMatch)
                        {
                            yield return(ch);
                        }
                    }
                    else
                    {
                        yield return(ch.AppendRange(
                                         ProcessRecursive(ch.Item, maxDepth, currentDepth + 1)
                                         .OrderBy(x => x.Item.SortOrder)
                                         .ToArray()));
                    }
                }
            }
        }
示例#17
0
        public override bool Match(IAbstractItem item)
        {
            var ctxVal = _ctx.GetTargetingValue(TargetingKeys.Region);

            if (ctxVal == null || !(ctxVal is int[]))
            {
                return(true);
            }

            var val = item.GetTargetingValue(TargetingKeys.Region);

            if (val == null || !(val is int[]))
            {
                return(true);
            }

            var regions           = val as int[];
            var currentRegionKeys = ctxVal as int[];

            //если у страницы нет регионов, значит подходит всем
            //если есть, значит должно быть пересечение хотя бы по одному
            return(!regions.Any() ? true : regions.Intersect(currentRegionKeys).Any());
        }
示例#18
0
        private static void VisitNodes(StringBuilder sb, IAbstractItem node, ITargetingFilter filter, ITargetingUrlTransformator urlTransformator)
        {
            if (node.IsPage)
            {
                sb.Append($"<li> <a href = {node.GetUrl(urlTransformator)}> {node.Title} </a></li>");
            }
            else
            {
                sb.Append($"<li> {node.Title} </li>");
            }

            var children = node.GetChildren(filter);

            if (children.Any())
            {
                sb.Append("<ul>");
                foreach (var item in children)
                {
                    VisitNodes(sb, item, filter, urlTransformator);
                }
                sb.Append("</ul>");
            }
        }
示例#19
0
 public override bool Match(IAbstractItem item)
 {
     return(true);
 }
示例#20
0
 public string Map(IAbstractItem widget)
 {
     //считаем, что компонент должен называться также как тип виджета
     return(widget.GetType().Name);
 }
示例#21
0
 public TAbstractItem Find <TAbstractItem>(IAbstractItem startPage, Func <TAbstractItem, bool> matchCriteria, int depth = 5) where TAbstractItem : IAbstractItem
 {
     return((TAbstractItem)Find(startPage, ai => ai is TAbstractItem && matchCriteria((TAbstractItem)ai), depth));
 }
示例#22
0
 public string Map(IAbstractItem page)
 {
     //считаем, что конроллер должен называться также как тип страницы
     return(page.GetType().Name);
 }
示例#23
0
 public override bool Match(IAbstractItem item)
 {
     return(item.IsPage && (item is IAbstractPage && (item as IAbstractPage).IsVisible));
 }
示例#24
0
 public abstract bool Match(IAbstractItem item);
示例#25
0
        public static async Task <IHtmlContent> WidgetZone(this IViewComponentHelper helper, IHtmlHelper html,
                                                           string zoneName, IDictionary <string, object> arguments = null)
        {
            IEnumerable <IAbstractItem> widgets = null;

            if (ZoneIsGlobal(zoneName))
            {
                //зона глобальная - значит нужны дочерние виджеты стартовой страницы
                var startPage = html.ViewContext.HttpContext.GetStartPage();
                if (startPage != null)
                {
                    widgets = startPage.GetChildren(GetFilter(html, zoneName));
                }
            }
            else
            {
                //элемент структуры сайта внутри которого мы пытаемся отрендерить зону
                IAbstractItem renderingContainer = null;

                var renderingContext = html.ViewContext.HttpContext.GetCurrentRenderingWidgetContext();
                if (renderingContext != null)
                {
                    //рендеримся внутри виджета
                    renderingContainer = renderingContext.CurrentWidget;
                }
                else
                {
                    //рендеримся на странице
                    renderingContainer = html.ViewContext.GetCurrentItem();
                }

                if (renderingContainer != null)
                {
                    if (ZoneIsRecursive(zoneName))
                    {
                        //зона рекурсивная, значит будем искать виджеты с этой зоной не только у текущего элементы, но и у всех родителей
                        var allParents = new List <IAbstractItem>();
                        var current    = renderingContainer;
                        while (current.Parent != null)
                        {
                            allParents.Add(current);
                            current = current.Parent;
                        }

                        widgets = allParents.SelectMany(x => x.GetChildren(GetFilter(html, zoneName)));
                    }
                    else
                    {
                        //ищем виджеты с зоной у текущего элемента
                        widgets = renderingContainer.GetChildren(GetFilter(html, zoneName));
                    }
                }
            }

            var builder = new HtmlContentBuilder();

            var onScreenContext  = ((IOnScreenContextProvider)html.ViewContext.HttpContext.RequestServices.GetService(typeof(IOnScreenContextProvider)))?.GetContext();
            var isWidgetEditMode = onScreenContext != null?onScreenContext.HasFeature(OnScreenFeatures.Widgets) : false;

            RenderOnScreenModeZoneWrapperStart(isWidgetEditMode, zoneName, builder);
            if (widgets != null)
            {
                var mapper = ((IComponentMapper)html.ViewContext.HttpContext.RequestServices.GetService(typeof(IComponentMapper)));

                foreach (var widget in widgets.OfType <IAbstractWidget>().OrderBy(x => x.SortOrder))
                {
                    var name = mapper.Map(widget);
                    var renderFullWidgetInfo = isWidgetEditMode && !WidgetShouldBeSkipped(onScreenContext, widget);

                    RenderOnScreenModeWidgetWrapperStart(renderFullWidgetInfo, builder, widget);
                    var renderingStack = html.ViewContext.HttpContext.PushWidgetToRenderingStack(new WidgetRenderingContext {
                        CurrentWidget = widget, ShouldUseCustomInvoker = true
                    });
                    try
                    {
                        var result = await helper.InvokeAsync(name, arguments);

                        builder.AppendHtml(result);
                    }
                    finally
                    {
                        renderingStack.Pop();

                        RenderOnScreenModeWidgetWrapperEnd(renderFullWidgetInfo, builder, widget);
                    }
                }
            }
            RenderOnScreenModeZoneWrapperEnd(isWidgetEditMode, zoneName, builder);
            return(builder);
        }
示例#26
0
 public override bool Match(IAbstractItem item)
 {
     return(_isPositiveMatch(item));
 }
示例#27
0
 public void CreateScope(IAbstractItem item)
 {
     _stack.Push(item);
 }
示例#28
0
 private static void RenderOnScreenModeWidgetWrapperStart(bool renderFullInfo, IHtmlContentBuilder builder, IAbstractItem widget)
 {
     if (renderFullInfo)
     {
         builder.AppendHtml($"<!--start widget {widget.Id} {{ alias='{widget.Alias}' title='{widget.Title.Replace("'", "").Replace("}", "").Replace("{", "")}' type='{widget.GetMetadata(OnScreenWidgetMetadataKeys.Type)}' published='{widget.GetMetadata(OnScreenWidgetMetadataKeys.Published)?.ToString()?.ToLower()}' order='{widget.SortOrder}' }}-->");
     }
     else
     {
         builder.AppendHtml($"<!--start widget-->");
     }
 }
示例#29
0
 private static void RenderOnScreenModeWidgetWrapperEnd(bool renderWidgetId, IHtmlContentBuilder builder, IAbstractItem widget)
 {
     if (renderWidgetId)
     {
         builder.AppendHtml($"<!--end widget {widget.Id}-->");
     }
     else
     {
         builder.AppendHtml($"<!--end widget-->");
     }
 }
示例#30
0
 public PathData(IAbstractItem abstractItem, string remainingUrl)
 {
     this.abstractItem = abstractItem;
     this.remainingUrl = remainingUrl;
 }