コード例 #1
0
 public IEnumerable <HarvestShapeHit> HarvestShape(HarvestShapeInfo info) =>
 !info.SubPath.StartsWith(SubPath, StringComparison.OrdinalIgnoreCase)
         ? Enumerable.Empty <HarvestShapeHit>()
         : new[]
 {
     new HarvestShapeHit
     {
         ShapeType = "VueComponent-" + info.FileName
                     .Replace("--", "__", StringComparison.OrdinalIgnoreCase)
                     .Replace("-", "__", StringComparison.OrdinalIgnoreCase)
                     .Replace(".", "_", StringComparison.OrdinalIgnoreCase)
                     .ToUpperInvariant(),
     },
 };
コード例 #2
0
        public IEnumerable <HarvestShapeHit> HarvestShape(HarvestShapeInfo info)
        {
            if (!info.SubPath.StartsWith(SubPath))
            {
                return(Enumerable.Empty <HarvestShapeHit>());
            }

            return(new[]
            {
                new HarvestShapeHit
                {
                    ShapeType = "VueComponent-" +
                                info.FileName.Replace("--", "__").Replace("-", "__").Replace('.', '_').ToLowerInvariant()
                }
            });
        }
コード例 #3
0
        public void Discover(ShapeTableBuilder builder)
        {
            Logger.Information("Start discovering shapes");

            // Getting enabled themes
            var harvesterInfos         = _harvesters.Select(harvester => new { harvester, subPaths = harvester.SubPaths() });
            var availableFeatures      = _featureManager.GetEnabledFeatures();
            var activeThemes           = availableFeatures.Where(FeatureIsTheme);
            var activeThemesExtensions = Once(activeThemes);

            // Getting folders in Alternates folder (The folder name should be the name of one Theme)
            var appDataPath           = @"~/App_Data/Sites";
            var tenantName            = _shellSettings.Name;
            var alternatesFolderName  = "Alternates";
            var alternateFolderPath   = Path.Combine(appDataPath, tenantName, alternatesFolderName).Replace(Path.DirectorySeparatorChar, '/');
            var alternateThemeFolders = _virtualPathProvider.ListDirectories(alternateFolderPath).Select(Path.GetDirectoryName).ToReadOnlyCollection();
            // Cycling folders
            var hits = _parallelCacheContext.RunInParallel(alternateThemeFolders, folderFullPath => {
                Logger.Information("Start discovering candidate views filenames");
                var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => {
                    //check if the folder name match with an enabled theme
                    //otherwise it returns a null object
                    var extensionDescriptor = activeThemesExtensions.SingleOrDefault(x => x.Id.Equals(new DirectoryInfo(folderFullPath).Name, System.StringComparison.OrdinalIgnoreCase));
                    if (extensionDescriptor != null)
                    {
                        var basePath    = Path.Combine(appDataPath, tenantName, alternatesFolderName, extensionDescriptor.Id).Replace(Path.DirectorySeparatorChar, '/');
                        var monitorPath = Path.Combine(appDataPath, tenantName, alternatesFolderName).Replace(Path.DirectorySeparatorChar, '/');
                        var virtualPath = Path.Combine(basePath, subPath).Replace(Path.DirectorySeparatorChar, '/');
                        IList <string> fileNames;
                        if (!_virtualPathProvider.DirectoryExists(virtualPath))
                        {
                            fileNames = new List <string>();
                        }
                        else
                        {
                            fileNames = _cacheManager.Get(virtualPath, true, ctx => {
                                if (!DisableMonitoring)
                                {
                                    Logger.Debug("Monitoring virtual path \"{0}\"", virtualPath);
                                    ctx.Monitor(_virtualPathMonitor.WhenPathChanges(virtualPath));
                                }

                                return(_virtualPathProvider.ListFiles(virtualPath).Select(Path.GetFileName).ToReadOnlyCollection());
                            });
                        }
                        return(new { harvesterInfo.harvester, basePath, subPath, virtualPath, fileNames, extensionDescriptor });
                    }
                    return(null);
                }))
                                   .Where(context => context != null) //remove null objects cause the inspected folder belongs to a disabled theme
                                   .ToList();

                Logger.Information("Done discovering candidate views filenames");
                var fileContexts = pathContexts.SelectMany(pathContext => _shapeTemplateViewEngines.SelectMany(ve => {
                    var fileNames = ve.DetectTemplateFileNames(pathContext.fileNames);
                    return(fileNames.Select(
                               fileName => new {
                        fileName = Path.GetFileNameWithoutExtension(fileName),
                        fileVirtualPath = Path.Combine(pathContext.virtualPath, fileName).Replace(Path.DirectorySeparatorChar, '/'),
                        pathContext
                    }));
                }));

                var shapeContexts = fileContexts.SelectMany(fileContext => {
                    var extensionDescriptor = fileContext.pathContext.extensionDescriptor;
                    var harvestShapeInfo    = new HarvestShapeInfo {
                        SubPath             = fileContext.pathContext.subPath,
                        FileName            = fileContext.fileName,
                        TemplateVirtualPath = fileContext.fileVirtualPath,
                    };
                    var harvestShapeHits = fileContext.pathContext.harvester.HarvestShape(harvestShapeInfo);
                    return(harvestShapeHits.Select(harvestShapeHit => new { harvestShapeInfo, harvestShapeHit, fileContext, extensionDescriptor }));
                });

                return(shapeContexts.Select(shapeContext => new { shapeContext }).ToList());
            }).SelectMany(hits2 => hits2);

            foreach (var iter in hits)
            {
                // templates are always associated with the namesake feature of module or theme
                var hit = iter;
                var featureDescriptors = iter.shapeContext.extensionDescriptor.Features.Where(fd => fd.Id == hit.shapeContext.extensionDescriptor.Id);
                foreach (var featureDescriptor in featureDescriptors)
                {
                    Logger.Debug("Binding {0} as shape [{1}] for feature {2}",
                                 hit.shapeContext.harvestShapeInfo.TemplateVirtualPath,
                                 iter.shapeContext.harvestShapeHit.ShapeType,
                                 featureDescriptor.Id);
                    // set priority higher than theme
                    var newfeatureDescriptor = new FeatureDescriptor {
                        Id              = featureDescriptor.Id,
                        Category        = featureDescriptor.Category,
                        Description     = featureDescriptor.Description,
                        Extension       = featureDescriptor.Extension,
                        LifecycleStatus = featureDescriptor.LifecycleStatus,
                        Name            = featureDescriptor.Name,
                        Priority        = featureDescriptor.Priority + 100,
                    };
                    builder.Describe(iter.shapeContext.harvestShapeHit.ShapeType)
                    .From(new Feature {
                        Descriptor = newfeatureDescriptor
                    })
                    .BoundAs(
                        hit.shapeContext.harvestShapeInfo.TemplateVirtualPath,
                        shapeDescriptor => displayContext => Render(shapeDescriptor, displayContext, hit.shapeContext.harvestShapeInfo, hit.shapeContext.harvestShapeHit));
                }
            }
            Logger.Information("Done discovering shapes");
        }
コード例 #4
0
        private IHtmlString Render(ShapeDescriptor shapeDescriptor, DisplayContext displayContext, HarvestShapeInfo harvestShapeInfo, HarvestShapeHit harvestShapeHit)
        {
            Logger.Information("Rendering template file '{0}'", harvestShapeInfo.TemplateVirtualPath);
            IHtmlString result;

            if (displayContext.ViewContext.View != null)
            {
                var htmlHelper = new HtmlHelper(displayContext.ViewContext, displayContext.ViewDataContainer);
                result = htmlHelper.Partial(harvestShapeInfo.TemplateVirtualPath, displayContext.Value);
            }
            else
            {
                // If the View is null, it means that the shape is being executed from a non-view origin / where no ViewContext was established by the view engine, but manually.
                // Manually creating a ViewContext works when working with Shape methods, but not when the shape is implemented as a Razor view template.
                // Horrible, but it will have to do for now.
                result = RenderRazorViewToString(harvestShapeInfo.TemplateVirtualPath, displayContext);
            }

            Logger.Information("Done rendering template file '{0}'", harvestShapeInfo.TemplateVirtualPath);
            return(result);
        }