Exemple #1
0
        public async Task <PageRoutingInfo> ExecuteAsync(GetPageRoutingInfoByPathQuery query, IExecutionContext executionContext)
        {
            // Deal with malformed query
            if (!string.IsNullOrWhiteSpace(query.Path) && !Uri.IsWellFormedUriString(query.Path, UriKind.Relative))
            {
                return(null);
            }

            var path      = _pathHelper.StandardisePath(query.Path);
            var allRoutes = await _queryExecutor.GetAllAsync <PageRoute>(executionContext);

            // Rather than starts with, do a regex replacement here with the path
            // E.g. /styuff/{slug} is not matching /styff/winterlude
            var pageRoutes = allRoutes
                             .Where(r => r.FullPath.Equals(path) || (r.PageType == PageType.CustomEntityDetails && IsCustomRoutingMatch(path, r.FullPath)))
                             .Where(r => query.IncludeUnpublished || r.IsPublished)
                             .Where(r => r.Locale == null || MatchesLocale(r.Locale, query.LocaleId))
                             .OrderByDescending(r => r.FullPath.Equals(path))
                             .ThenByDescending(r => MatchesLocale(r.Locale, query.LocaleId))
                             .ToList();

            PageRoutingInfo result = null;

            // Exact match
            if (pageRoutes.Any() && pageRoutes[0].PageType != PageType.CustomEntityDetails)
            {
                result = ToRoutingInfo(pageRoutes[0]);
            }
            else
            {
                var allRules = _queryExecutor.GetAll <ICustomEntityRoutingRule>(executionContext);
                // I'm only anticipating a single rule to match at the moment, but eventually there might be multiple rules to match e.g. categories page
                foreach (var pageRoute in pageRoutes)
                {
                    // Find a routing rule, matching higher priorities first
                    var rule = allRules
                               .Where(r => r.MatchesRule(query.Path, pageRoute))
                               .OrderBy(r => r.Priority)
                               .ThenBy(r => r.RouteFormat.Length)
                               .FirstOrDefault();

                    if (rule != null)
                    {
                        var customEntityRouteQuery = rule.ExtractRoutingQuery(query.Path, pageRoute);
                        var customEntityRoute      = await _queryExecutor.ExecuteAsync(customEntityRouteQuery, executionContext);

                        if (customEntityRoute != null && (query.IncludeUnpublished || customEntityRoute.Versions.HasPublishedVersion()))
                        {
                            return(ToRoutingInfo(pageRoute, customEntityRoute, rule));
                        }
                    }
                }
            }

            return(result);
        }
Exemple #2
0
        public async Task <PageRoute> ExecuteAsync(GetNotFoundPageRouteByPathQuery query, IExecutionContext executionContext)
        {
            if (!string.IsNullOrWhiteSpace(query.Path) && !Uri.IsWellFormedUriString(query.Path, UriKind.Relative))
            {
                return(null);
            }

            var path = _pathHelper.StandardisePath(query.Path);

            var allRoutes = (await _queryExecutor
                             .GetAllAsync <PageRoute>())
                            .Where(r => r.IsPublished || query.IncludeUnpublished)
                            .Where(r => r.PageType == PageType.NotFound);

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

            PageRoute notFoundRoute = null;

            // Work backwards through the path to find a 404 page
            while (notFoundRoute == null)
            {
                var pathToTest = string.Join("/", paths);
                if (string.IsNullOrEmpty(pathToTest))
                {
                    pathToTest = "/";
                }

                // Prefer the specified locale, but fall back to a non-specific locale page
                notFoundRoute = allRoutes
                                .Where(r => r.IsInDirectory(pathToTest) && r.Locale == null || MatchesLocale(r.Locale, query.LocaleId))
                                .OrderByDescending(r => MatchesLocale(r.Locale, query.LocaleId))
                                .FirstOrDefault();

                // After we've checked the root directory, break and return null
                if (paths.Count <= 0)
                {
                    break;
                }

                // Move backwards down the path
                paths.Remove(paths.Last());
            }

            return(notFoundRoute);
        }