/// <summary> /// Returns a paginator for the files in the specified folder, ordered by descending date by default. /// 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: PaginatorFor folderName topFolderOnly(true*/false or 1/0) sortDirection (desc*/asc) /// /// Examples: /// PaginatorFor folderName /// PaginatorFor folderName false /// PaginatorFor folderName true asc /// /// It can automatically detect the tag or categ params to filter by tag or category if available /// </summary> /// <param name="currentFile"></param> /// <param name="parameters"></param> /// <returns>A List of file information objects that can be used in Liquid tags</MIISFile></returns> object IFMSource.GetValue(MIISFile currentFile, params string[] parameters) { //Get all published files with the current parameters var currentFiles = FilesFromFolderParamSrc.GetFilesFromParameters(currentFile, parameters); //Get current page from QS NameValueCollection qs = HttpContext.Current.Request.QueryString; int page = 1; if (!string.IsNullOrWhiteSpace(qs["page"])) { _ = int.TryParse(qs["page"], out page); } //Get current specified page size (10 by default, in the constructor) int PageSize = 0; var valPageSize = currentFile["paginate"]; if (valPageSize != null) { _ = int.TryParse(valPageSize.ToString(), out PageSize); } //Define the paginator object return(new Paginator(currentFiles, page, PageSize)); }
object IFMSource.GetValue(MIISFile currentFile, params string[] srcParams) { int min = 0, max = 100; //Parse paramenters if (srcParams.Length == 1) { max = int.Parse(srcParams[0]); } if (srcParams.Length == 2) { min = int.Parse(srcParams[0]); max = int.Parse(srcParams[1]); } if (min > max) //Swap them { var t = max; max = min; min = t; } Random rnd = new Random(); //Force the file to be cached for 10 seconds //currentFile.SetMaxCacheValidity(10); //Force the file to not do any caching despite of the Caching parameter currentFile.DisableCache(); return(rnd.Next(min, max)); }
/// <summary> /// Returns a file proxy to access the data of the specified file to be used in a content /// Very useful for loading a specific file when we know it's name /// </summary> /// <param name="currentFile"></param> /// <param name="parameters"></param> /// <returns>A MIISFile object to be used in a file content with liquid tags</returns> object IFMSource.GetValue(MIISFile currentFile, params string[] parameters) { if (parameters.Length == 0) { throw new Exception("Data file not specified!!"); } string filePath = FilesEnumeratorHelper.GetFolderAbsPathFromName(parameters[0]); if (!File.Exists(filePath)) { throw new Exception($"The file {filePath} does not exist!!"); } //Add cache dependency on the loaded file currentFile.AddFileDependency(filePath); //Return the file data proxy return(new MIISFile(new MarkdownFile(filePath))); }
/// <summary> /// Adds cache dependencies for the source file depending on the current files being processed /// </summary> /// <param name="currentFile"></param> /// <param name="folderPath"></param> /// <param name="allFiles"></param> /// <param name="topOnly">If only the top folder is being watched</param> public static void AddFileCacheDependencies(MIISFile currentFile, string folderPath, IEnumerable <MarkdownFile> allFiles, bool topOnly) { if (topOnly) { //Establish the processed folder as a caching dependency for the current file this FM souce is working on currentFile.AddFileDependency(folderPath); } else { //Add an special FolderTreeCacheDependency to watch all the subfolders currentFile.AddFileDependency(new FolderTreeCacheDependency(folderPath)); } //If any of the files has a (publishing) date later than now, then add the first one as a cache dependency to refresh the listings at that point double maxDateSecs = NumSecondsToNextFilePubDate(allFiles); if (maxDateSecs > 0) { currentFile.SetCachingTimeOut(maxDateSecs); } }
/// <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); }
/// <summary> /// Returns the files in the specified folder ordered by descending date by default. /// 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: FilesFromFolder folderName topFolderOnly(true*/false or 1/0) sortDirection (desc*/asc) /// /// Examples: /// FilesFromFolder folderName /// FilesFromFolder folderName false /// FilesFromFolder folderName true asc /// /// It can automatically detect the tag or categ params to filter by tag or category if available /// </summary> /// <param name="currentFile"></param> /// <param name="parameters"></param> /// <returns>A List of file information objects that can be used in Liquid tags</MIISFile></returns> object IFMSource.GetValue(MIISFile currentFile, params string[] parameters) { //Get all published files with the current parameters return(GetFilesFromParameters(currentFile, parameters).ToList <MIISFile>()); }