/// <summary> /// Returns an array with all the distinct tags available in the files of the specified folder ordered by tag name (ascending). /// Includes only .md or .mdh files /// Excludes files with a name starting with "_", with the name "index" or "default". /// By default includes only the files directly inside the folder, not in subfolders /// /// Syntax: TagsFromFolder folderName topFolderOnly(true*/false or 1/0) /// /// Examples: /// TagsFromFolder folderName /// TagsFromFolder folderName false /// </summary> /// <param name="currentFile"></param> /// <param name="parameters"></param> /// <returns>An array of strings with tag names in files, that can be used in Liquid tags</MIISFile></returns> object IFMSource.GetValue(MIISFile currentFile, params string[] parameters) { //Expects these parameters (* indicates the default value): //- Folder path relative to the current file or to the root of the site //- Top folder files only (true*/false, could be 1*/0) //Check if there's a folder specified if (parameters.Length == 0) { throw new Exception("Folder not specified!!"); } string folderPath = FilesEnumeratorHelper.GetFolderAbsPathFromName(parameters[0]); //Include top folder only or all subfolders (second parameter) bool topOnly = true; try { string sTopOnly = parameters[1].ToLowerInvariant(); topOnly = topOnly = FilesEnumeratorHelper.IsTruthy(sTopOnly); //If the second parameter is "false" or "0", then use topOnly files } catch { } //Third parameter: include default files (index, default) bool includeDefFiles = false; try { string sincludeDefFiles = parameters[2].ToLowerInvariant(); includeDefFiles = FilesEnumeratorHelper.IsTruthy(sincludeDefFiles); } catch { } string cacheKey = folderPath + "_tags" + "_" + topOnly + "_" + includeDefFiles; //Check if tags are already cached var tags = HttpRuntime.Cache[cacheKey]; if (tags == null) //Get tags from disk { //Get al files in the folder (and subfolders if indicated), without specific ordering (we don't need it and it'll save some processing time) IEnumerable <MarkdownFile> allFiles = FilesEnumeratorHelper.GetAllFilesFromFolder(folderPath, topOnly); //Filter only those that are published var publishedFilesProxies = FilesEnumeratorHelper.OnlyPublished(allFiles); //Get all the tags in the published files (if any) HashSet <string> hTags = new HashSet <string>(); foreach (MIISFile mf in publishedFilesProxies) { hTags.UnionWith(mf.Tags); } //Get the number of files in each tag tags = from t in hTags select new { name = t, count = (from f in publishedFilesProxies where f.Tags.Contains <string>(t) select f).Count() }; //FILE CACHING FilesEnumeratorHelper.AddFileCacheDependencies(currentFile, folderPath, allFiles, topOnly); //Add tags to cache depending on the folder and the time until the next published file FilesEnumeratorHelper.AddFileListToCache(folderPath, cacheKey, FilesEnumeratorHelper.NumSecondsToNextFilePubDate(allFiles), tags, topOnly); } return(tags); }
//Ugly method to have in one place all the code common to various FM Sources that are in this assembly //DRY, you know ;-) internal static IEnumerable <MIISFile> GetFilesFromParameters(MIISFile currentFile, params string[] parameters) { //Expects these parameters (* indicates the default value): //- Folder path relative to the current file or to the root of the site //- Top folder files only (true*/false, could be 1*/0) //First parameter: folder to process //Check if there's a folder specified if (parameters.Length == 0) { throw new Exception("Folder not specified!!"); } string folderPath = FilesEnumeratorHelper.GetFolderAbsPathFromName(parameters[0]); //Second parameter: include files in subfolders //Include top folder only or all subfolders bool topOnly = true; try { string sTopOnly = parameters[1].ToLowerInvariant(); topOnly = FilesEnumeratorHelper.IsTruthy(sTopOnly); //If the second parameter is "false" or "0", then use topOnly files } catch { } //Third parameter: include default files (index, default) bool includeDefFiles = false; try { string sincludeDefFiles = parameters[2].ToLowerInvariant(); includeDefFiles = FilesEnumeratorHelper.IsTruthy(sincludeDefFiles); } catch { } //Get al files in the folder (and subfolders if indicated), ordered by date desc IEnumerable <MarkdownFile> allFiles = FilesEnumeratorHelper.GetAllFilesFromFolder(folderPath, topOnly, includeDefFiles); //File caching dependencies FilesEnumeratorHelper.AddFileCacheDependencies(currentFile, folderPath, allFiles, topOnly); //Filter only those that are published IEnumerable <MIISFile> publishedFilesProxies = FilesEnumeratorHelper.OnlyPublished(allFiles); int numPublishedFiles = publishedFilesProxies.Count(); //Filter by tag or category from QueryString params NameValueCollection qs = HttpContext.Current.Request.QueryString; if (!string.IsNullOrWhiteSpace(qs["tag"])) //More specific, takes precedence { string tag = qs["tag"].ToLowerInvariant(); publishedFilesProxies = from file in publishedFilesProxies where file.Tags.Contains <string>(tag) select file; } else if (!string.IsNullOrWhiteSpace(qs["categ"])) { string categ = qs["categ"].ToLowerInvariant(); publishedFilesProxies = from file in publishedFilesProxies where file.Categories.Contains <string>(categ) select file; } return(publishedFilesProxies); }