public Site(SiteConfig config, IEnumerable<DataFile> data, IEnumerable<DocumentFile> documents, IEnumerable<StaticFile> files, LayoutFileCollection layouts, Site parent = null) { this.DefaultLayoutForExtension = new Dictionary<string, string>(config.DefaultLayoutForExtension); this.IgnoreFiles = config.IgnoreFiles; this.SitePath = config.SitePath; this.Author = config.Author; this.LiveReloadScript = config.LiveReloadScript; this.DocumentsPath = config.DocumentsPath; this.FilesPath = config.FilesPath; this.LayoutsPath = config.LayoutsPath; this.OutputPath = config.OutputPath; this.Parent = parent; this.TimeZone = config.TimeZone; this.Url = config.Url.EnsureEndsWith("/"); this.RootUrl = config.RootUrl.EnsureEndsWith("/"); var allDocuments = documents.ToList(); this.Data = data.ToList(); this.Partials = allDocuments.Where(d => d.Partial).ToList(); this.Documents = allDocuments.Where(d => !d.Partial).ToList(); this.Files = files.ToList(); this.Layouts = new LayoutFileCollection(layouts); this.Metadata = config.Metadata; }
public void CanDoQueryableNumeric() { var config = new SiteConfig() { RootUrl = String.Empty, Url = "http://www.example.com" }; var meta1 = new MetadataCollection(); meta1.Add("number", 1); var meta2 = new MetadataCollection(); meta2.Add("number", 20); var meta3 = new MetadataCollection(); meta3.Add("number", 3); var documents = new[] { new DocumentFile("1.html.md", Path.GetFullPath("documents"), "documents", "1", "1", String.Empty, null, meta1, null), new DocumentFile("20.html.md", Path.GetFullPath("documents"), "documents", "20", "20", String.Empty, null, meta2, null), new DocumentFile("3.html.md", Path.GetFullPath("documents"), "documents", "3", "3", String.Empty, null, meta3, null), }; var site = new Site(config, Enumerable.Empty<DataFile>(), documents, Enumerable.Empty<StaticFile>(), Enumerable.Empty<LayoutFile>()); var query = @"query documents where number gt 1 ascending number"; var p = QueryProcessor.Parse(site, query); var q = p.Results.ToList(); Assert.Equal(3, q[0].Number); Assert.Equal(20, q[1].Number); }
public void CanParseQuery() { var config = new SiteConfig() { RootUrl = String.Empty, Url = "http://www.example.com" }; var documents = new[] { new DocumentFile("bar.html.md", Path.GetFullPath("documents"), "documents", "documents", "bar", "bar", null, new MetadataCollection(), null), new DocumentFile("foo.html.md", Path.GetFullPath("documents"), "documents", "documents", "foo", "foo", null, new MetadataCollection(), null), }; var site = new Site(config, Enumerable.Empty<DataFile>(), documents, Enumerable.Empty<StaticFile>(), Enumerable.Empty<LayoutFile>()); var query = @"query documents every 10 where sourcerelativepath startswith ""documents\posts\"" descending date formaturl ""posts/page/{0}"""; var result = QueryProcessor.Parse(site, query); Assert.Equal(2, result.Source.Count()); Assert.Equal(10, result.PageEvery); Assert.Equal(WhereOperator.StartsWith, result.Where.Operator); Assert.Equal("sourcerelativepath", result.Where.Property); Assert.Equal(@"documents\posts\", result.Where.Value); Assert.Equal(OrderOperator.Descending, result.Order.Operator); Assert.Equal("date", result.Order.Property); Assert.Equal(@"posts/page/{0}", result.FormatUrl); var q = result.Results.ToList(); Assert.Empty(q); }
public void CanRenderDocument() { var tinySiteAssembly = typeof(RazorRenderer).Assembly; var basePath = Path.GetFullPath(@"data\RenderDocumentsCommand\"); var outputPath = Path.Combine(Path.GetTempPath(), @"tinysite\"); var loadLayouts = new LoadLayoutsCommand(Path.Combine(basePath, @"layouts\"), null, null); var layouts = loadLayouts.Execute(); var collection = new LayoutFileCollection(layouts); var loadDocuments = new LoadDocumentsCommand(); loadDocuments.Author = new Author(); loadDocuments.DocumentsPath = Path.Combine(basePath, @"documents\"); loadDocuments.Layouts = collection; loadDocuments.OutputRootPath = outputPath; loadDocuments.RenderedExtensions = new[] { "md", "cshtml" }; loadDocuments.RootUrl = "http://www.example.com/"; loadDocuments.ApplicationUrl = "/app/sub"; var documents = loadDocuments.Execute().OrderBy(d => d.Name).ToList(); var config = new SiteConfig() { OutputPath = outputPath, Url = "http://example.com", RootUrl = String.Empty, }; var site = new Site(config, Enumerable.Empty<DataFile>(), documents, Enumerable.Empty<StaticFile>(), collection); var engines = RenderingEngine.Load(tinySiteAssembly); Statistics.Current = new Statistics(); var command = new RenderDocumentsCommand(engines, site); command.Execute(); var description = "This is the summary of the document with a link to example.com."; var content = "<p>This is the summary of the document with a link to <a href=\"http://example.com\">example.com</a>.</p>\n<p>This is additional content in the document.</p>"; var summary = "<p>This is the summary of the document with a link to <a href=\"http://example.com\">example.com</a>.</p>"; var title = "test"; Assert.Equal(0, command.RenderedData); Assert.Equal(3, command.RenderedDocuments); Assert.Equal(String.Empty, documents[0].RenderedContent.Trim()); Assert.Equal("This is the summary of the document with a link to [example.com](http://example.com).\n\nThis is additional content in the document.", documents[2].SourceContent.Replace("\r\n", "\n")); Assert.Equal(content, documents[2].Content); Assert.Equal(description, documents[2].Description); Assert.Equal(summary, documents[2].Summary); Assert.Equal(title, documents[2].Metadata.Get<string>("title")); Assert.Equal( $"<title>{title}</title>\n" + $"<description>{description}</description>\n" + $"<summary>{summary}</summary>\n" + $"<content>{content}</content>", documents[2].RenderedContent.Replace("\r\n", "\n")); }
public RunWatchCommand(SiteConfig config, IEnumerable<LastRunDocument> lastRunState, IDictionary<string, RenderingEngine> engines) { this.Config = config; this.Engines = engines; this.LastRunState = lastRunState; this.Paths = new HashSet<string>(StringComparer.OrdinalIgnoreCase); this.Waits = new EventWaitHandle[] { new ManualResetEvent(false), new AutoResetEvent(false), }; }
public void CanDoQueryableMultipleWhere() { var config = new SiteConfig() { RootUrl = String.Empty, Url = "http://www.example.com" }; var meta1 = new MetadataCollection { { "number", 1 }, { "canonical", null } }; var meta2 = new MetadataCollection { { "number", 20 }, { "canonical", "true" } }; var meta3 = new MetadataCollection { { "number", 3 }, { "canonical", null } }; var documents = new[] { new DocumentFile("1.html.md", Path.GetFullPath("documents"), "documents", "1", "1", String.Empty, null, meta1, null), new DocumentFile("20.html.md", Path.GetFullPath("documents"), "documents", "20", "20", String.Empty, null, meta2, null), new DocumentFile("3.html.md", Path.GetFullPath("documents"), "documents", "3", "3", String.Empty, null, meta3, null), }; var site = new Site(config, Enumerable.Empty<DataFile>(), documents, Enumerable.Empty<StaticFile>(), Enumerable.Empty<LayoutFile>()); var query = @"query documents where number gt 1 where canonical equals null ascending number"; var p = QueryProcessor.Parse(site, query); var q = p.Results.ToList(); Assert.Single(q); Assert.Equal(3, q[0].Number); }
public void CanReadDynamicRenderingData() { var sitePath = @"C:\site\"; var documentsPath = sitePath + @"documents\"; var layoutsPath = sitePath + @"layouts\"; var outputPath = sitePath + @"build\"; var document = new DocumentFile(documentsPath + "foo.html.md", documentsPath, outputPath + "foo.html", outputPath, String.Empty, String.Empty, null, null, null); var layout = new LayoutFile(layoutsPath + "default.cshtml", layoutsPath, String.Empty, null, null); var config = new SiteConfig() { OutputPath = outputPath, Url = "http://example.com", RootUrl = String.Empty, }; var site = new Site(config, Enumerable.Empty<DataFile>(), new[] { document }, Enumerable.Empty<StaticFile>(), new LayoutFileCollection(new[] { layout })); dynamic data = new DynamicRenderDocument(document, layout, site); Assert.Equal(outputPath, data.Site.OutputPath); Assert.Single(data.Site.Documents); foreach (var d in data.Site.Documents) { Assert.Equal(outputPath + "foo.html", d.OutputPath); } }
public void CanDoQueryable() { var config = new SiteConfig() { RootUrl = String.Empty, Url = "http://www.example.com" }; var documents = new[] { new DocumentFile("bar.html.md", Path.GetFullPath("documents"), "documents", "documents", "bar", "bar", null, new MetadataCollection(), null), new DocumentFile("foo.html.md", Path.GetFullPath("documents"), "documents", "documents", "foo", "foo", null, new MetadataCollection(), null), }; var site = new Site(config, Enumerable.Empty<DataFile>(), documents, Enumerable.Empty<StaticFile>(), Enumerable.Empty<LayoutFile>()); var query = @"query documents where outputpath startswith ""doc"" descending url"; var p = QueryProcessor.Parse(site, query); var q = p.Results.ToList(); Assert.Equal("foo/foo", q[0].Url); Assert.Equal("bar/bar", q[1].Url); }
public async Task<SiteConfig> ExecuteAsync() { var root = Path.GetFullPath(Path.GetDirectoryName(this.ConfigPath)); var settings = new JsonSerializerSettings(); settings.Converters.Add(new JsonTimeZoneConverter()); string json; using (var reader = new StreamReader(this.ConfigPath)) { json = await reader.ReadToEndAsync(); } var config = new SiteConfig(); config.Parent = this.Parent; var ignoreFiles = new string[0]; var subsites = new string[0]; //var config = JsonConvert.DeserializeObject<SiteConfig>(json, settings); foreach (var token in JObject.Parse(json)) { var key = token.Key.ToLowerInvariant(); var value = token.Value; switch (key) { case "author": config.Author = value.ToObject<Author>(); break; case "output": case "outputpath": config.OutputPath = Path.Combine(root, (string)value).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar).EnsureBackslashTerminated(); break; case "url": config.Url = (string)value; break; case "rooturl": config.RootUrl = (string)value; break; case "subsites": subsites = value.Values<string>().ToArray(); break; case "additionalmetadata": config.AdditionalMetadataForFiles = this.ParseAdditionalMetadata(value).ToList(); break; case "defaultlayoutforextension": this.AssignDefaultLayouts(config, value); break; case "ignorefiles": config.IgnoreFiles = this.ParseIgnoreFiles(value.Values<string>()).ToArray(); break; default: config.Metadata.Add(key, value); break; } } config.SitePath = root; config.DataPath = Path.Combine(root, "data\\"); config.DocumentsPath = Path.Combine(root, "documents\\"); config.FilesPath = Path.Combine(root, "files\\"); config.LayoutsPath = Path.Combine(root, "layouts\\"); config.OutputPath = config.OutputPath ?? Path.Combine(root, "build\\"); config.Url = config.Url.EnsureStartsWith("/"); config.RootUrl = config.RootUrl ?? "http://localhost/"; // If override output path was provided use that. config.OutputPath = String.IsNullOrEmpty(this.OutputPath) ? Path.GetFullPath(config.OutputPath) : Path.GetFullPath(this.OutputPath); var subsiteLoadTasks = new List<Task<SiteConfig>>(subsites.Length); foreach (var subsite in subsites) { var command = new LoadSiteConfigCommand(); command.Parent = config; command.ConfigPath = Path.Combine(root, subsite); var task = command.ExecuteAsync(); subsiteLoadTasks.Add(task); } config.SubsiteConfigs = await Task.WhenAll(subsiteLoadTasks); return this.SiteConfig = config; }
private void AssignDefaultLayouts(SiteConfig config, JToken token) { var layoutDefaults = token as JObject; if (layoutDefaults == null) { config.DefaultLayoutForExtension.Add("*", (string)token); } else { foreach (var layoutDefault in layoutDefaults) { config.DefaultLayoutForExtension.Add(layoutDefault.Key, (string)layoutDefault.Value); } } }
public Site(SiteConfig config, IEnumerable<DataFile> data, IEnumerable<DocumentFile> documents, IEnumerable<StaticFile> files, IEnumerable<LayoutFile> layouts, Site parent = null) : this(config, data, documents, files, new LayoutFileCollection(layouts), parent) { }
private Site LoadSite(SiteConfig config, IEnumerable<LastRunDocument> lastRunState, IEnumerable<string> renderedExtensions) { Site site; using (var capture = Statistics.Current.Start(StatisticTiming.LoadedSite)) { // Load layouts. LayoutFileCollection layouts; { var load = new LoadLayoutsCommand(config.LayoutsPath, config.AdditionalMetadataForFiles, config.IgnoreFiles); var loaded = load.Execute(); layouts = new LayoutFileCollection(loaded); } // Load data files. IEnumerable<DataFile> data; { var load = new LoadDataFilesCommand(config.DataPath, config.AdditionalMetadataForFiles, config.IgnoreFiles); data = load.Execute(); } // Load documents. IEnumerable<DocumentFile> documents; { var load = new LoadDocumentsCommand(); load.Author = config.Author; load.OutputRootPath = config.OutputPath; load.Layouts = layouts; load.RenderedExtensions = renderedExtensions; load.DefaultLayoutForExtension = config.DefaultLayoutForExtension; load.DocumentsPath = config.DocumentsPath; load.RootUrl = config.RootUrl; load.ApplicationUrl = config.Url; load.AdditionalMetadataForFiles = config.AdditionalMetadataForFiles; load.IgnoreFiles = config.IgnoreFiles; documents = load.Execute(); } // Load files. IEnumerable<StaticFile> files; { var load = new LoadFilesCommand(); load.OutputPath = config.OutputPath; load.FilesPath = config.FilesPath; load.RootUrl = config.RootUrl; load.Url = config.Url; files = load.Execute(); } // Calculate unmodified state. { var unmodified = new SetUnmodifiedCommand(config.SitePath, documents, files, this.InitialLastRunState); unmodified.Execute(); } site = new Site(config, data, documents, files, layouts); } Statistics.Current.SiteFiles = site.Documents.Count + site.Files.Count + site.Layouts.Count; return site; }
public RunRenderCommand(SiteConfig config, IEnumerable<LastRunDocument> lastRunState, IDictionary<string, RenderingEngine> engines) { this.Config = config; this.Engines = engines; this.InitialLastRunState = lastRunState; }
public RunServeCommand(SiteConfig config, int port) { this.Config = config; this.Port = port; }