import std.file; import std.stdio; import std.string; import std.datetime.date; import std.experimental.logger; import dyaml; import vibe.d; import page; import utils; /** * 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 uint seperatorIndex = cast(uint) indexOf(m_contentSource, "---\n"); this.m_excerpt = this.m_contentSource[seperatorIndex + 4..$]; const uint firstHeaderIndex = cast(uint) 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); this.m_author = headerNode.getOr!string("author", ""); this.m_excerpt = headerNode.getOr!string("excerpt", null); SysTime firstPublished; firstPublished = headerNode.getOr!SysTime("firstPublished", SysTime(DateTime.fromSimpleString("0001-Jan-01 00:00:00"))); this.m_firstPublished = cast(DateTime) firstPublished; this.m_updated = cast(DateTime) headerNode.getOr!SysTime("updated", 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; } @property bool isModified() { return m_firstPublished != m_updated; } }