My blog engine VOL 2



My first setup of this blog was missing some important features to be a decent blog. Now I've added some of these features - see what and download the code.


The 2 really missing features on this blog was a proper frontpage that lists more than just the titles of new blogpost and an RSS feed of new posts. To solve that I've created a small blog engine as an add-in module that finds new blogposts, publish them using a template, or publish them using a RSS feed. Read the first post about my blog engine.

To accomplish what I needed, I've created a small module (Using Visual Studio 2011 Developer Preview) that finds the 10 most recent blogposts, renders them using a template and publishing a RSS feed.

Sorry: I'm a totally sucker for VB (yet) - the only one here at the Office though, so I guess I will be converted at some point...

First the module finds the 10 most recent pages with content below the navigation item where the module is attached:
'Find pages
Dim posts As Content.PageCollection = GetBlogPosts()
If posts.Count = 0 Then
	Return String.Empty
End If
And GetBlogPosts() - returning top 10 new pages with some content:
Friend Function GetBlogPosts() As Content.PageCollection
	Dim ids As New List(Of Integer)
	Dim startLevel As Integer = Base.ChkInteger(Me.Pageview.Page.Value("PageLevel"))

	For Each p As Frontend.Page In Childs(Me.Pageview.Page)
		If startLevel + 2 = Base.ChkInteger(p.Value("PageLevel")) OrElse startLevel + 3 = Base.ChkInteger(p.Value("PageLevel")) Then
			ids.Add(Base.ChkInteger(p.Value("PageID")))
		End If
	Next
	Dim pc As Content.PageCollection = Content.Page.GetPagesBySql(String.Format("SELECT TOP 10 * FROM [Page] INNER JOIN Paragraph ON PageID = ParagraphPageID WHERE (ParagraphModuleSystemName='' OR ParagraphModuleSystemName Is Null) AND ParagraphShowParagraph = " & Database.SqlBool(True) & " AND PageActive = " & Database.SqlBool(True) & " AND ParagraphSort = 1 AND [PageID] IN ({0}) ORDER BY [PageCreatedDate] DESC", _
				 String.Join(",", Array.ConvertAll(ids.ToArray, Function(id As Integer) id.ToString()))))
	Return pc
End Function
Then loop through the blogposts, generating the template output and the RSS feed:
For Each p As Content.Page In posts

	Dim ShortDesc As String = String.Empty
	Dim text As String = String.Empty
	For Each para In paragraphs
		If para.PageID = p.ID Then
			pt.SetTag("Blog.Post.Heading", para.Header)
			pt.SetTag("Blog.Post.Text", para.Text)
			If Not String.IsNullOrEmpty(para.Text) Then
				text = para.Text
				ShortDesc = SubString(Base.StripHTML(para.Text), 500)
				pt.SetTag("Blog.Post.Resume", ShortDesc)
			Else
				pt.SetTag("Blog.Post.Resume", "")
			End If
			Exit For
		End If
	Next
	If String.IsNullOrEmpty(text) Then
		Continue For
	End If

	Dim p2 As Frontend.Page = Frontend.Page.FindPage(p.ID)
	Dim author As String = Base.ChkString(p2.Value("EditorName"))
	If author.ToLower = "angel" Then
		author = "Nicolai Høeg Pedersen"
	End If
	pt.SetTag("Blog.Post.Title", Base.ChkString(IIf(String.IsNullOrEmpty(p.MetaTitle), p.MenuText, p.MetaTitle)))
	pt.SetTag("Blog.Post.Name", p.MenuText)
	pt.SetTag("Blog.Post.ID", p.ID)
	pt.SetTag("Blog.Post.Author", author)
	pt.SetTag("Blog.Post.Created", p.CreatedDate)
	pt.SetTag("Blog.Post.Updated", p.UpdatedDate)

	Dim friendlyUrl As String = Frontend.SearchEngineFriendlyURLs.getSearchFriendlyUrl(p.ID)
	Dim fullLink As String = "http://" & HttpContext.Current.Request.Url.Host & friendlyUrl
	pt.SetTag("Blog.Post.FullLink", fullLink)


	rssitems.Add(New RssItem With {.author = author, .description = text, .link = fullLink, .pubDate = p.CreatedDate, .title = p.MenuText})
	pt.CommitLoop()
Next
And the template rendering the blog list can be downloaded here

As you can see there is a RssItem object that are filled with data and collected in a collection. This collection of items are published to RSS format using a piece of code from the Dynamicweb RSS module:
Friend Shared Function ToXmlDocument( _
	ByVal items As Generic.List(Of RssItem), _
	ByVal showMax As Integer, _
	ByVal itemDescMax As Integer, _
	ByVal title As String, _
	ByVal link As String, _
	ByVal description As String, _
	ByVal language As String, _
	ByVal copyright As String, _
	ByVal managingEditor As String, _
	ByVal webMaster As String, _
	ByVal pubDate As Date, _
	ByVal lastBuildDate As Date, _
	ByVal generator As String, _
	ByVal docs As String, _
	ByVal image As String, _
	ByVal ttl As String) As XmlDocument

	Dim xmlDoc As XmlDocument = New XmlDocument
	Dim rootNode As XmlElement
	Dim node As XmlElement

	'*****  XML Document
	xmlDoc.PreserveWhitespace = False
	xmlDoc.InsertBefore(xmlDoc.CreateXmlDeclaration("1.0", System.Text.Encoding.UTF8.WebName, String.Empty), xmlDoc.DocumentElement)
	'***** Create the root node
	rootNode = xmlDoc.CreateElement("rss")
	rootNode.SetAttribute("version", "2.0")

	xmlDoc.AppendChild(rootNode)
	node = xmlDoc.CreateElement("channel")
	rootNode.AppendChild(node)
	rootNode = node

	'***** Add child nodes and data
	AppendElement(xmlDoc, rootNode, "title", title, True)
	AppendElement(xmlDoc, rootNode, "link", link, True)
	AppendElement(xmlDoc, rootNode, "description", description, True)
	AppendElement(xmlDoc, rootNode, "language", language, False)
	AppendElement(xmlDoc, rootNode, "copyright", copyright, False)
	AppendElement(xmlDoc, rootNode, "managingEditor", managingEditor, False)
	AppendElement(xmlDoc, rootNode, "webMaster", webMaster, False)
	AppendElement(xmlDoc, rootNode, "pubDate", pubDate.ToUniversalTime.ToString("r"), False)
	AppendElement(xmlDoc, rootNode, "lastBuildDate", lastBuildDate.ToUniversalTime.ToString("r"), False)
	AppendElement(xmlDoc, rootNode, "generator", generator, False)
	AppendElement(xmlDoc, rootNode, "docs", docs, False)
	AppendElement(xmlDoc, rootNode, "ttl", ttl, False)

	node = AppendElement(xmlDoc, rootNode, "image", String.Empty, True)
	AppendElement(xmlDoc, node, "url", image, True)
	AppendElement(xmlDoc, node, "title", generator, True)
	AppendElement(xmlDoc, node, "link", link, True)

	Dim currentDate As DateTime = Now

	Dim n As Integer = 1
	For Each i As RssItem In items

		If n > showMax Then Exit For

		Dim item As XmlElement = xmlDoc.CreateElement("item")
		rootNode.AppendChild(item)

		AppendElement(xmlDoc, item, "title", i.title, True)
		AppendElement(xmlDoc, item, "link", i.link, False)
		AppendElement(xmlDoc, item, "description", SubString(i.description, itemDescMax), False)
		AppendElement(xmlDoc, item, "author", i.author, False)
		AppendElement(xmlDoc, item, "pubDate", i.pubDate.ToUniversalTime.ToString("r"), False)
		If Not String.IsNullOrEmpty(i.guid) Then
			Dim guidNode As XmlElement = xmlDoc.CreateElement("guid")
			guidNode.SetAttribute("isPermaLink", "false")
			guidNode.InnerText = i.guid
			item.AppendChild(guidNode)
		End If
		n = n + 1
	Next

	Return xmlDoc
End Function
So thats the main parts of the code for my blog engine. A lot of things are hardcoded and cannot be configured as it is now.

The result

The result of the publishing can be seen on the frontpage of this blog

It also generates a RSS feed - I've chosen to publish my feed using Feedburner from Google - giving me stats and propably some faster indexing!

You can find my feed here: http://feeds.feedburner.com/Nicolaipedersen - remember to sign up...
If you want to see the raw feed, you can find it here: http://nicolaipedersen.com/blog.aspx?rss=true.

Download

Download my project here:
Dynamicweb.Blogengine
The BlogPost List template (Right click - save as)

What else

One of the other things I needed was a search. That was easy so I just created a search page and enabled the search module.

So - that was my first upgrade of this blog - what would you like of other features on this blog? Please comment.