//public static PageContext FromDictionary(SiteContext siteContext, IDictionary<string, object> metadata, string outputPath, string defaultOutputPath) //{ // var context = new PageContext(siteContext, TODO) // { // OutputPath = // metadata.ContainsKey("permalink") // ? Path.Combine(outputPath, metadata["permalink"].ToString().ToRelativeFile()) // : defaultOutputPath // }; // if (metadata.ContainsKey("title")) // { // context.Title = metadata["title"].ToString(); // } // context.Bag = metadata; // return context; //} public static PageContext FromPage(SiteContext siteContext, Page page, string outputPath, string defaultOutputPath) { var context = new PageContext(siteContext, page); if (page.Bag.ContainsKey("permalink")) { context.OutputPath = Path.Combine(outputPath, page.Url.ToRelativeFile()); } else { context.OutputPath = defaultOutputPath; page.Bag.Add("permalink", page.File); } if (context.OutputPath.EndsWith("\\")) { context.OutputPath = Path.Combine(context.OutputPath, "index.html"); } page.OutputFile = context.OutputPath; if (page.Bag.ContainsKey("title")) { context.Title = page.Bag["title"].ToString(); } if (string.IsNullOrEmpty(context.Title)) context.Title = siteContext.Title; context.Content = page.Content; context.Bag = page.Bag; context.Bag.Add("id", page.Id); context.Bag.Add("url", page.Url); return context; }
public void EvaluateLink_url_is_well_formatted(string filePath, string expectedUrl) { var siteContext = new SiteContext { OutputFolder = @"C:\TestSite\_site" }; var page = new Page { Filepath = filePath }; Assert.Equal(expectedUrl, LinkHelper.EvaluateLink(siteContext, page)); }
#pragma warning restore 0649 public SiteContext BuildContext(string path) { if (!Path.IsPathRooted(path)) path = Path.Combine(Environment.CurrentDirectory, path); var config = new Dictionary<string, object>(); if (File.Exists(Path.Combine(path, "_config.yml"))) config = (Dictionary<string, object>)File.ReadAllText(Path.Combine(path, "_config.yml")).YamlHeader(true); if (!config.ContainsKey("permalink")) config.Add("permalink", "/:year/:month/:day/:title.html"); var context = new SiteContext { SourceFolder = path, OutputFolder = Path.Combine(path, "_site"), Posts = new List<Page>(), Pages = new List<Page>(), }; BuildPosts(config, context); foreach (var file in fileSystem.Directory.GetFiles(context.SourceFolder, "*.*", SearchOption.AllDirectories)) { var relativePath = MapToOutputPath(context, file); if (relativePath.StartsWith("_")) continue; if (relativePath.StartsWith(".")) continue; var postFirstLine = SafeReadLine(file); if (postFirstLine == null || !postFirstLine.StartsWith("---")) { context.Pages.Add(new NonProcessedPage { File = file, Filepath = Path.Combine(context.OutputFolder, file) }); continue; } var contents = SafeReadContents(file); var header = contents.YamlHeader(); var page = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", // should this be the Site title? Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : DateTime.Now, Content = Markdown.Transform(contents.ExcludeHeader()), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; context.Pages.Add(page); } return context; }
public void EvaluatePermalink_url_is_well_formatted(string permalink, string expectedUrl, string categories) { var page = new Page { Categories = categories == null ? Enumerable.Empty<string>() : categories.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries), Date = new DateTime(2015, 03, 09), File = @"C:\temp\2015-03-09-foobar-baz.md" }; Assert.Equal(expectedUrl, LinkHelper.EvaluatePermalink(permalink, page)); }
// http://jekyllrb.com/docs/permalinks/ public string EvaluatePermalink(string permalink, Page page) { if (BuiltInPermalinks.ContainsKey(permalink)) { permalink = BuiltInPermalinks[permalink]; } if (!permalink.EndsWith("/") && string.IsNullOrEmpty(Path.GetExtension(permalink))) { permalink += "/"; } permalink = permalink.Replace(":categories", string.Join("/", page.Categories.ToArray())); permalink = permalink.Replace(":dashcategories", string.Join("-", page.Categories.ToArray())); permalink = permalink.Replace(":year", page.Date.Year.ToString(CultureInfo.InvariantCulture)); permalink = permalink.Replace(":month", page.Date.ToString("MM")); permalink = permalink.Replace(":day", page.Date.ToString("dd")); permalink = permalink.Replace(":title", GetTitle(page.File)); permalink = permalink.Replace(":y_day", page.Date.DayOfYear.ToString("000")); permalink = permalink.Replace(":short_year", page.Date.ToString("yy")); permalink = permalink.Replace(":i_month", page.Date.Month.ToString()); permalink = permalink.Replace(":i_day", page.Date.Day.ToString()); if (permalink.Contains(":category")) { var matches = CategoryRegex.Matches(permalink); if (matches != null && matches.Count > 0) { foreach (Match match in matches) { var replacementValue = string.Empty; int categoryIndex; if (match.Success) { if (int.TryParse(match.Groups[1].Value, out categoryIndex) && categoryIndex > 0) { replacementValue = page.Categories.Skip(categoryIndex - 1).FirstOrDefault(); } else if (page.Categories.Any()) { replacementValue = page.Categories.First(); } } permalink = permalink.Replace(match.Value, replacementValue); } } } permalink = SlashesRegex.Replace(permalink, "/"); return permalink; }
private void ProcessFile(string outputDirectory, Page page, Page previous, Page next, string relativePath = "") { if (string.IsNullOrWhiteSpace(relativePath)) relativePath = MapToOutputPath(page.File); page.OutputFile = Path.Combine(outputDirectory, relativePath); var directory = Path.GetDirectoryName(page.OutputFile); if (!FileSystem.Directory.Exists(directory)) FileSystem.Directory.CreateDirectory(directory); var extension = Path.GetExtension(page.File); if (extension.IsImageFormat()) { FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (page is NonProcessedPage) { FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (extension.IsMarkdownFile() || extension.IsRazorFile()) page.OutputFile = page.OutputFile.Replace(extension, ".html"); var pageContext = PageContext.FromPage(Context, page, outputDirectory, page.OutputFile); pageContext.Previous = previous; pageContext.Next = next; var metadata = page.Bag; while (metadata.ContainsKey("layout")) { if ((string)metadata["layout"] == "nil" || metadata["layout"] == null) break; var path = Path.Combine(Context.SourceFolder, "_layouts", metadata["layout"] + LayoutExtension); if (!FileSystem.File.Exists(path)) break; metadata = ProcessTemplate(pageContext, path); } pageContext.Content = RenderTemplate(pageContext.Content, pageContext); FileSystem.File.WriteAllText(pageContext.OutputPath, pageContext.Content); }
private void WriteRedirectFile(SiteContext siteContext, Page post, IEnumerable<string> sourceUrls) { var targetUrl = post.Url; var content = String.Format(Templates.Redirect, targetUrl); foreach (var sourceUrl in sourceUrls) { try { var directory = _fileSystem.Path.Combine(siteContext.OutputFolder, sourceUrl.TrimStart('/').Replace('/', _fileSystem.Path.DirectorySeparatorChar)); if (!_fileSystem.Directory.Exists(directory)) { _fileSystem.Directory.CreateDirectory(directory); } _fileSystem.File.WriteAllText(_fileSystem.Path.Combine(directory, "index.html"), content); } catch (Exception ex) { Console.WriteLine("Generating redirect for {0} at {1} failed:{2}{3}", post.Id, sourceUrl, Environment.NewLine, ex); } } }
public void Process(SiteContext siteContext) { context = siteContext; context.Posts = new List<Page>(); var outputDirectory = Path.Combine(context.Folder, "_site"); Tracing.Debug(string.Format("generating the site contents at {0}", outputDirectory)); FileSystem.Directory.CreateDirectory(outputDirectory); IDictionary<string, string> posts = new Dictionary<string, string>(); var postsFolder = Path.Combine(context.Folder, "_posts"); if (FileSystem.Directory.Exists(postsFolder)) { foreach (var file in FileSystem.Directory.GetFiles(postsFolder, "*.*", SearchOption.AllDirectories)) { var relativePath = GetPathWithTimestamp(outputDirectory, file); posts.Add(file, relativePath); // TODO: more parsing of data var contents = FileSystem.File.ReadAllText(file); var header = contents.YamlHeader(); var post = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = Markdown.Transform(contents.ExcludeHeader()) }; context.Posts.Add(post); } context.Posts = context.Posts.OrderByDescending(p => p.Date).ToList(); foreach (var p in posts) { ProcessFile(outputDirectory, p.Key, p.Value); } } foreach (var file in FileSystem.Directory.GetFiles(context.Folder, "*.*", SearchOption.AllDirectories)) { var relativePath = MapToOutputPath(file); if (relativePath.StartsWith("_")) continue; if (relativePath.StartsWith(".")) continue; ProcessFile(outputDirectory, file, relativePath); } }
public void config_permalink_sets_relative_file_output_path() { var context = new SiteContext(); context.Config = new Dictionary<string, object>(); context.Config.Add("permalink", "/blog/:year/:month/:day/:title.html"); var page = new Page() { Url = "/blog/2010/08/21/title-of-my-post.html" }; var outputPath = "c:\\temp"; var defaultOutputPath = "c:\\default"; var pageContext = PageContext.FromPage(context, page, outputPath, defaultOutputPath); Assert.Equal("c:\\temp\\blog\\2010\\08\\21\\title-of-my-post.html", pageContext.OutputPath); }
public string EvaluateLink(SiteContext context, Page page) { var directory = Path.GetDirectoryName(page.Filepath); var relativePath = directory.Replace(context.OutputFolder, string.Empty); var fileExtension = Path.GetExtension(page.Filepath); if (HtmlExtensions.Contains(fileExtension, StringComparer.InvariantCultureIgnoreCase)) { fileExtension = ".html"; } var link = relativePath.Replace('\\', '/').TrimStart('/') + "/" + GetPageTitle(page.Filepath) + fileExtension; if (!link.StartsWith("/")) { link = "/" + link; } return link; }
private void BuildPages(Dictionary<string, object> config, SiteContext context) { foreach (var file in fileSystem.Directory.GetFiles(context.SourceFolder, "*.*", SearchOption.AllDirectories)) { var relativePath = MapToOutputPath(context, file); if (relativePath.StartsWith("_")) continue; if (relativePath.StartsWith(".")) continue; var postFirstLine = SafeReadLine(file); if (postFirstLine == null || !postFirstLine.StartsWith("---")) { context.Pages.Add(new NonProcessedPage { File = file, Filepath = Path.Combine(context.OutputFolder, file) }); continue; } var contents = SafeReadContents(file); var header = contents.YamlHeader(); var page = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", // should this be the Site title? Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = RenderContent(file, contents, header), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; if (header.ContainsKey("permalink")) { page.Url = EvaluatePagePermalink(header["permalink"].ToString(), page); } context.Pages.Add(page); } }
public void no_permalink_sets_default_output_path_and_page_bag_permalink() { var context = new SiteContext(); context.Config = new Dictionary<string, object>(); var file = "title-of-my-post.html"; var page = new Page() { File = file }; page.Bag = new Dictionary<string, object>(); var outputPath = "c:\\temp"; var defaultOutputPath = "c:\\default\\title-of-my-post.html"; var pageContext = PageContext.FromPage(context, page, outputPath, defaultOutputPath); Assert.Equal("c:\\default\\title-of-my-post.html", pageContext.OutputPath); Assert.Equal(file, page.Bag["permalink"]); }
public static PageContext FromPage(Page page, string outputPath, string defaultOutputPath) { var context = new PageContext(); if (page.Bag.ContainsKey("permalink")) { context.OutputPath = Path.Combine(outputPath, page.Url.ToRelativeFile()); } else { context.OutputPath = defaultOutputPath; page.Bag.Add("permalink", page.File); } if (page.Bag.ContainsKey("title")) { context.Title = page.Bag["title"].ToString(); } context.Content = page.Content; context.Bag = page.Bag; context.Bag.Add("id", page.Id); context.Bag.Add("url", page.Url); return context; }
private Page CreatePage(SiteContext context, IDictionary<string, object> config, string file, bool isPost) { try { if (pageCache.ContainsKey(file)) return pageCache[file]; var contents = SafeReadContents(file); var header = contents.YamlHeader(); if (header.ContainsKey("published") && header["published"].ToString().ToLower() == "false") { return null; } var page = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = RenderContent(file, contents, header), Filepath = isPost ? GetPathWithTimestamp(context.OutputFolder, file) : GetFilePathForPage(context, file), File = file, Bag = header, }; if (header.ContainsKey("permalink")) page.Url = EvaluatePermalink(header["permalink"].ToString(), page); else if (isPost && config.ContainsKey("permalink")) page.Url = EvaluatePermalink(config["permalink"].ToString(), page); else page.Url = EvaluateLink(context, page); // The GetDirectoryPage method is reentrant, we need a cache to stop a stack overflow :) pageCache.Add(file, page); page.DirectoryPages = GetDirectoryPages(context, config, Path.GetDirectoryName(file), isPost).ToList(); if (isPost) { if (header.ContainsKey("categories")) page.Categories = header["categories"] as IEnumerable<string>; if (header.ContainsKey("tags")) page.Tags = header["tags"] as IEnumerable<string>; } return page; } catch (Exception e) { Tracing.Info(String.Format("Failed to build post from File: {0}", file)); Tracing.Info(e.Message); Tracing.Debug(e.ToString()); } return null; }
private void ProcessFile(string outputDirectory, Page page, Page previous, Page next, string relativePath = "") { if (string.IsNullOrWhiteSpace(relativePath)) relativePath = MapToOutputPath(page.File); page.OutputFile = Path.Combine(outputDirectory, relativePath); var extension = Path.GetExtension(page.File); if (extension.IsImageFormat()) { CreateOutputDirectory(page.OutputFile); FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (page is NonProcessedPage) { CreateOutputDirectory(page.OutputFile); FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (extension.IsMarkdownFile() || extension.IsRazorFile()) page.OutputFile = page.OutputFile.Replace(extension, ".html"); var pageContext = PageContext.FromPage(Context, page, outputDirectory, page.OutputFile); //pageContext.Content = markdown.Transform(pageContext.Content); pageContext.Previous = previous; pageContext.Next = next; var pageContexts = new List<PageContext> {pageContext}; object paginateObj; if (page.Bag.TryGetValue("paginate", out paginateObj)) { var paginate = Convert.ToInt32(paginateObj); var totalPages = (int)Math.Ceiling(Context.Posts.Count / Convert.ToDouble(paginateObj)); var paginator = new Paginator(Context, totalPages, paginate, 1); pageContext.Paginator = paginator; var paginateLink = "/page/:page/index.html"; if (page.Bag.ContainsKey("paginate_link")) paginateLink = Convert.ToString(page.Bag["paginate_link"]); var prevLink = page.Url; for (var i = 2; i <= totalPages; i++) { var newPaginator = new Paginator(Context, totalPages, paginate, i) {PreviousPageUrl = prevLink}; var link = paginateLink.Replace(":page", Convert.ToString(i)); paginator.NextPageUrl = link; paginator = newPaginator; prevLink = link; var path = Path.Combine(outputDirectory, link.ToRelativeFile()); pageContexts.Add(new PageContext(pageContext) {Paginator = newPaginator, OutputPath = path}); } } foreach (var context in pageContexts) { var metadata = page.Bag; while (metadata.ContainsKey("layout")) { var layout = metadata["layout"]; if ((string) layout == "nil" || layout == null) break; var path = Path.Combine(Context.SourceFolder, "_layouts", layout + LayoutExtension); if (!FileSystem.File.Exists(path)) break; try { metadata = ProcessTemplate(context, path); } catch (Exception ex) { throw new PageProcessingException( string.Format("Failed to process layout {0} for {1}, see inner exception for more details", layout, context.OutputPath), ex); } } try { context.Content = RenderTemplate(context.Content, context); } catch (Exception ex) { throw new PageProcessingException( string.Format("Failed to process {0}, see inner exception for more details", context.OutputPath), ex); } CreateOutputDirectory(context.OutputPath); FileSystem.File.WriteAllText(context.OutputPath, context.Content); } }
private List<string> ResolveCategories(SiteContext context, IDictionary<string, object> header, Page page) { var categories = new List<string>(); if (!IsOnlyFrontmatterCategories(context)) { var postPath = page.File.Replace(context.SourceFolder, string.Empty); string rawCategories = postPath.Replace(fileSystem.Path.GetFileName(page.File), string.Empty).Replace("_posts", string.Empty); categories.AddRange(rawCategories.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries)); } if (header.ContainsKey("categories") && header["categories"] is IEnumerable<string>) { categories.AddRange((IEnumerable<string>)header["categories"]); } else if (header.ContainsKey("category")) { categories.Add((string)header["category"]); } return categories; }
private Page CreatePage(SiteContext context, IConfiguration config, string file, bool isPost) { try { if (pageCache.ContainsKey(file)) return pageCache[file]; var content = SafeReadContents(file); var relativePath = MapToOutputPath(context, file); var scopedDefaults = context.Config.Defaults.ForScope(relativePath); var header = scopedDefaults.Merge(content.YamlHeader()); if (header.ContainsKey("published") && header["published"].ToString().ToLower() == "false") { return null; } var page = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(fileSystem), Content = content, Filepath = isPost ? GetPathWithTimestamp(context.OutputFolder, file) : GetFilePathForPage(context, file), File = file, Bag = header, }; // resolve categories and tags if (isPost) { page.Categories = ResolveCategories(context, header, page); if (header.ContainsKey("tags")) page.Tags = header["tags"] as IEnumerable<string>; } // resolve permalink if (header.ContainsKey("permalink")) { page.Url = linkHelper.EvaluatePermalink(header["permalink"].ToString(), page); } else if (isPost && config.ContainsKey("permalink")) { page.Url = linkHelper.EvaluatePermalink(config["permalink"].ToString(), page); } else { page.Url = linkHelper.EvaluateLink(context, page); } // resolve id page.Id = page.Url.Replace(".html", string.Empty).Replace("index", string.Empty); // always write date back to Bag as DateTime page.Bag["date"] = page.Date; // The GetDirectoryPage method is reentrant, we need a cache to stop a stack overflow :) pageCache.Add(file, page); page.DirectoryPages = GetDirectoryPages(context, config, Path.GetDirectoryName(file), isPost).ToList(); return page; } catch (Exception e) { Tracing.Info(String.Format("Failed to build post from File: {0}", file)); Tracing.Info(e.Message); Tracing.Debug(e.ToString()); } return null; }
private static void AddCategory(Dictionary<string, List<Page>> categories, string categoryName, Page post) { if (categories.ContainsKey(categoryName)) { categories[categoryName].Add(post); } else { categories.Add(categoryName, new List<Page> { post }); } }
private string EvaluateLink(SiteContext context, Page page) { var directory = Path.GetDirectoryName(page.Filepath); var relativePath = directory.Replace(context.OutputFolder, string.Empty); var fileExtension = Path.GetExtension(page.Filepath); var htmlExtensions = new[] {".markdown", ".mdown", ".mkdn", ".mkd", ".md", ".textile"}; if (htmlExtensions.Contains(fileExtension, StringComparer.InvariantCultureIgnoreCase)) fileExtension = ".html"; var link = relativePath.Replace('\\', '/').TrimStart('/') + "/" + GetPageTitle(page.Filepath) + fileExtension; if (!link.StartsWith("/")) link = "/" + link; return link; }
private void ProcessFile(string outputDirectory, Page page, Page previous, Page next, bool skipFileOnError, string relativePath = "") { if (string.IsNullOrWhiteSpace(relativePath)) relativePath = MapToOutputPath(page.File); page.OutputFile = Path.Combine(outputDirectory, relativePath); var extension = Path.GetExtension(page.File); if (extension.IsImageFormat()) { CreateOutputDirectory(page.OutputFile); CopyFileIfSourceNewer(page.File, page.OutputFile, true); return; } if (page is NonProcessedPage) { CreateOutputDirectory(page.OutputFile); CopyFileIfSourceNewer(page.File, page.OutputFile, true); return; } if (extension.IsMarkdownFile() || extension.IsRazorFile()) page.OutputFile = page.OutputFile.Replace(extension, ".html"); var pageContext = PageContext.FromPage(Context, page, outputDirectory, page.OutputFile); pageContext.Previous = previous; pageContext.Next = next; var pageContexts = new List<PageContext> { pageContext }; object paginateObj; if (page.Bag.TryGetValue("paginate", out paginateObj)) { var paginate = Convert.ToInt32(paginateObj); var totalPages = (int)Math.Ceiling(Context.Posts.Count / Convert.ToDouble(paginateObj)); var paginator = new Paginator(Context, totalPages, paginate, 1); pageContext.Paginator = paginator; var paginateLink = "/page/:page/index.html"; if (page.Bag.ContainsKey("paginate_link")) paginateLink = Convert.ToString(page.Bag["paginate_link"]); var prevLink = page.Url; for (var i = 2; i <= totalPages; i++) { var newPaginator = new Paginator(Context, totalPages, paginate, i) { PreviousPageUrl = prevLink }; var link = paginateLink.Replace(":page", Convert.ToString(i)); paginator.NextPageUrl = link; paginator = newPaginator; prevLink = link; var path = Path.Combine(outputDirectory, link.ToRelativeFile()); if (path.EndsWith(FileSystem.Path.DirectorySeparatorChar.ToString())) { path = Path.Combine(path, "index.html"); } var context = new PageContext(pageContext) { Paginator = newPaginator, OutputPath = path }; context.Bag["url"] = link; pageContexts.Add(context); } } foreach (var context in pageContexts) { var metadata = page.Bag; var failed = false; var excerptSeparator = context.Bag.ContainsKey("excerpt_separator") ? context.Bag["excerpt_separator"].ToString() : Context.ExcerptSeparator; try { context.Bag["excerpt"] = GetContentExcerpt(RenderTemplate(context.Content, context), excerptSeparator); } catch (Exception ex) { if (!skipFileOnError) { var message = string.Format("Failed to process {0}, see inner exception for more details", context.OutputPath); throw new PageProcessingException(message, ex); } Console.WriteLine(@"Failed to process {0}, see inner exception for more details", context.OutputPath); continue; } while (metadata.ContainsKey("layout")) { var layout = metadata["layout"]; if ((string)layout == "nil" || layout == null) break; var path = FindLayoutPath(layout.ToString()); if (path == null) break; try { metadata = ProcessTemplate(context, path); } catch (Exception ex) { if (!skipFileOnError) { var message = string.Format("Failed to process layout {0} for {1}, see inner exception for more details", layout, context.OutputPath); throw new PageProcessingException(message, ex); } Console.WriteLine(@"Failed to process layout {0} for {1} because '{2}'. Skipping file", layout, context.OutputPath, ex.Message); failed = true; break; } } if (failed) continue; try { context.Content = RenderTemplate(context.Content, context); } catch (Exception ex) { if (!skipFileOnError) { var message = string.Format("Failed to process {0}, see inner exception for more details", context.OutputPath); throw new PageProcessingException(message, ex); } Console.WriteLine(@"Failed to process {0}, see inner exception for more details", context.OutputPath); continue; } CreateOutputDirectory(context.OutputPath); FileSystem.File.WriteAllText(context.OutputPath, context.Content); } }
private Hash ToHash(Page page) { var p = Hash.FromDictionary(page.Bag); p.Add("Content", page.Content); return p; }
public PageContext(SiteContext context, Page page) { Site = context; Page = page; }
public SiteContext BuildContext(string path) { var config = new Dictionary<string, object>(); if (File.Exists(Path.Combine(path, "_config.yml"))) config = (Dictionary<string, object>)File.ReadAllText(Path.Combine(path, "_config.yml")).YamlHeader(true); if (!config.ContainsKey("permalink")) config.Add("permalink", "/:year/:month/:day/:title.html"); var context = new SiteContext { SourceFolder = path, OutputFolder = Path.Combine(path, "_site"), Posts = new List<Page>(), Pages = new List<Page>(), }; var postsFolder = Path.Combine(context.SourceFolder, "_posts"); if (fileSystem.Directory.Exists(postsFolder)) { foreach (var file in fileSystem.Directory.GetFiles(postsFolder, "*.*", SearchOption.AllDirectories)) { var contents = fileSystem.File.ReadAllText(file); var header = contents.YamlHeader(); var post = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", // should this be the Site title? Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = Markdown.Transform(contents.ExcludeHeader()), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; if (header.ContainsKey("permalink")) post.Url = EvaluatePermalink(header["permalink"].ToString(), post); else if (config.ContainsKey("permalink")) post.Url = EvaluatePermalink(config["permalink"].ToString(), post); if (string.IsNullOrEmpty(post.Url)) { Tracing.Info("whaaa"); } context.Posts.Add(post); } context.Posts = context.Posts.OrderByDescending(p => p.Date).ToList(); } foreach (var file in fileSystem.Directory.GetFiles(context.SourceFolder, "*.*", SearchOption.AllDirectories)) { var relativePath = MapToOutputPath(context, file); if (relativePath.StartsWith("_")) continue; if (relativePath.StartsWith(".")) continue; using (var reader = new StreamReader(file)) { var x = reader.ReadLine(); if (x == null || !x.StartsWith("---")) { context.Pages.Add(new NonProcessedPage { File = file, Filepath = Path.Combine(context.OutputFolder, file) }); continue; } } var contents = fileSystem.File.ReadAllText(file); var header = contents.YamlHeader(); var page = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", // should this be the Site title? Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : DateTime.Now, Content = Markdown.Transform(contents.ExcludeHeader()), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; context.Pages.Add(page); } return context; }
private void ProcessFile(string outputDirectory, Page page, Page previous, Page next, string relativePath = "") { if (string.IsNullOrWhiteSpace(relativePath)) relativePath = MapToOutputPath(page.File); page.OutputFile = Path.Combine(outputDirectory, relativePath); var extension = Path.GetExtension(page.File); if (extension.IsImageFormat()) { CreateOutputDirectory(page.OutputFile); FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (page is NonProcessedPage) { CreateOutputDirectory(page.OutputFile); FileSystem.File.Copy(page.File, page.OutputFile, true); return; } if (extension.IsMarkdownFile() || extension.IsRazorFile()) page.OutputFile = page.OutputFile.Replace(extension, ".html"); var pageContext = PageContext.FromPage(Context, page, outputDirectory, page.OutputFile); //pageContext.Content = markdown.Transform(pageContext.Content); pageContext.Previous = previous; pageContext.Next = next; var metadata = page.Bag; while (metadata.ContainsKey("layout")) { var layout = metadata["layout"]; if ((string)layout == "nil" || layout == null) break; var path = Path.Combine(Context.SourceFolder, "_layouts", layout + LayoutExtension); if (!FileSystem.File.Exists(path)) break; try { metadata = ProcessTemplate(pageContext, path); } catch (Exception ex) { throw new PageProcessingException(string.Format("Failed to process layout {0} for {1}, see inner exception for more details", layout, pageContext.OutputPath), ex); } } try { pageContext.Content = RenderTemplate(pageContext.Content, pageContext); } catch (Exception ex) { throw new PageProcessingException(string.Format("Failed to process {0}, see inner exception for more details", pageContext.OutputPath), ex); } CreateOutputDirectory(pageContext.OutputPath); FileSystem.File.WriteAllText(pageContext.OutputPath, pageContext.Content); }
private string EvaluateLink(SiteContext context, Page page) { var directory = Path.GetDirectoryName(page.Filepath); var relativePath = directory.Replace(context.OutputFolder, string.Empty); var link = relativePath.Replace('\\', '/').TrimStart('/') + "/" + GetPageTitle(page.Filepath) + ".html"; if (!link.StartsWith("/")) link = "/" + link; return link; }
// https://github.com/mojombo/jekyll/wiki/permalinks private string EvaluatePermalink(string permalink, Page page) { permalink = permalink.Replace(":year", page.Date.Year.ToString(CultureInfo.InvariantCulture)); permalink = permalink.Replace(":month", page.Date.ToString("MM")); permalink = permalink.Replace(":day", page.Date.ToString("dd")); permalink = permalink.Replace(":title", GetTitle(page.File)); return permalink; }
private void BuildPost(Dictionary<string, object> config, SiteContext context, string file) { try { var contents = SafeReadContents(file); var header = contents.YamlHeader(); var post = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = RenderContent(file, contents, header), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; if (header.ContainsKey("permalink")) post.Url = EvaluatePermalink(header["permalink"].ToString(), post); else if (config.ContainsKey("permalink")) post.Url = EvaluatePermalink(config["permalink"].ToString(), post); if (string.IsNullOrEmpty(post.Url)) { Tracing.Info("whaaa"); } context.Posts.Add(post); } catch (Exception e) { Tracing.Info(String.Format("Failed to build post from File: {0}", file)); Tracing.Info(e.Message); Tracing.Debug(e.ToString()); } }
public PostDrop(Page page) { this.page = page; }
private void BuildPosts(Dictionary<string, object> config, SiteContext context) { var postsFolder = Path.Combine(context.SourceFolder, "_posts"); if (fileSystem.Directory.Exists(postsFolder)) { foreach (var file in fileSystem.Directory.GetFiles(postsFolder, "*.*", SearchOption.AllDirectories)) { var contents = SafeReadContents(file); var header = contents.YamlHeader(); var post = new Page { Title = header.ContainsKey("title") ? header["title"].ToString() : "this is a post", // NOTE: should this be the Site title? Date = header.ContainsKey("date") ? DateTime.Parse(header["date"].ToString()) : file.Datestamp(), Content = Markdown.Transform(contents.ExcludeHeader()), Filepath = GetPathWithTimestamp(context.OutputFolder, file), File = file, Bag = header, }; if (header.ContainsKey("permalink")) post.Url = EvaluatePermalink(header["permalink"].ToString(), post); else if (config.ContainsKey("permalink")) post.Url = EvaluatePermalink(config["permalink"].ToString(), post); if (string.IsNullOrEmpty(post.Url)) { Tracing.Info("whaaa"); } context.Posts.Add(post); } context.Posts = context.Posts.OrderByDescending(p => p.Date).ToList(); } }