import std.file; import std.stdio; import std.string; import std.datetime.date; import std.experimental.logger; import dyaml; import page; import vibe.d; /** * Represents an article on the blog */ class Article : Page { private string m_author; private string m_title; private string m_slug; private DateTime m_firstPublished; private string m_excerpt; /** * Time that the file was last updated */ private DateTime m_updated; /** * Loads an article from a file. */ this(string file) { this.m_headerShift = 1; super(file); // Find the first header and mark everything up to that as if (m_excerpt is null) { // an excerpt, used in search results. const long seperatorIndex = indexOf(m_contentSource, "---\n"); this.m_excerpt = this.m_contentSource[seperatorIndex + 4..$]; long firstHeaderIndex = indexOf(this.m_excerpt, '#'); if (firstHeaderIndex >= 0) { this.m_excerpt = this.m_excerpt[0..firstHeaderIndex]; } } } /** * Loads the metadata specific to Articles. */ @safe override protected void loadHeader(Node headerNode) { super.loadHeader(headerNode); if (headerNode.containsKey("author")) { this.m_author = headerNode["author"].as!string; } else { this.m_author = ""; } if ("excerpt" in headerNode) { this.m_excerpt = headerNode["excerpt"].as!string; } if ("firstPublished" in headerNode) { try { this.m_firstPublished = cast(DateTime) headerNode["firstPublished"].as!SysTime; } catch(DateTimeException e) { warningf("%s: invalid date format", this.m_slug); } } else { this.m_firstPublished= DateTime.fromSimpleString("1970-Jan-01 00:00:00"); } if ("updated" in headerNode) { try { this.m_updated = cast(DateTime) headerNode["updated"].as!SysTime(); } catch(DateTimeException e) { warningf("%s: invalid date format", this.m_slug); } } else { this.m_updated = this.m_firstPublished; } } @property string excerpt() { return m_excerpt; } @property string author() { return m_author; } @property DateTime firstPublished() { return m_firstPublished; } @property DateTime updated() { return m_updated; } }