Here is a freebee for the DNN developers out there. The sitemap.aspx file included with DNN 05.00.00 didn't work with google. It would return a invalid format error so I set out to fix that and also add the ability to render blog posts into the sitemap.
It is a pretty simple task to modify the sitemap.aspx file to render blog posts so I increased the degree of difficulty by converting the entire control to C#. (I am not a big VB fan so I convert when reworking a control)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SiteMap.aspx.cs" Inherits="Default2" %>
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using DotNetNuke.Modules.Blog.Business;
public partial class Default2 : DotNetNuke.Framework.PageBase
{
private string SITEMAP_CHANGEFREQ = "daily";
private string SITEMAP_PRIORITY = "0.5";
private int SITEMAP_MAXURLS = 50000;
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
}
protected override void Render(HtmlTextWriter writer)
{
BuildSiteMap(PortalSettings.PortalId, writer);
}
protected void BuildSiteMap(int portalid, HtmlTextWriter textwriter)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = System.Text.Encoding.UTF8;
settings.OmitXmlDeclaration = false;
XmlWriter writer = XmlWriter.Create(textwriter, settings);
// build header
writer.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xsi", "schemaLocation", null, "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");
// add urls
int intURLs = 0;
DotNetNuke.Entities.Tabs.TabController TabController = new DotNetNuke.Entities.Tabs.TabController();
foreach(DotNetNuke.Entities.Tabs.TabInfo tab in TabController.GetTabsByPortal(PortalSettings.PortalId).Values)
{
if(!tab.IsDeleted && !tab.DisableLink && tab.IsVisible && tab.TabType == DotNetNuke.Entities.Tabs.TabType.Normal && (tab.StartDate == null || tab.StartDate < DateTime.Now) && (tab.EndDate == null || tab.EndDate == DateTime.MinValue || tab.EndDate > DateTime.Now))
{
if(DotNetNuke.Security.PortalSecurity.IsInRoles(tab.AuthorizedRoles))
{
if(intURLs < SITEMAP_MAXURLS)
{
intURLs++;
BuildURL(writer, tab.FullUrl);
}
}
}
}
if (true) //writer blog entries to the sitemap
{
EntryController econtroller = new EntryController();
ArrayList blogentries = econtroller.ListAllEntriesByPortal(PortalSettings.PortalId, false, false);
foreach (EntryInfo info in blogentries)
{
if (intURLs < SITEMAP_MAXURLS)
{
intURLs++;
BuildURL(writer, info.PermaLink);
}
}
}
writer.WriteEndElement();
writer.Close();
}
private void BuildURL(XmlWriter writer, string URL)
{
if (URL.ToLower().IndexOf(Request.Url.Host.ToLower()) == -1 && !URL.ToLower().StartsWith("http://")) //this is a hack in case you run this on a local computer.
{
URL = DotNetNuke.Common.Globals.AddHTTP(Request.Url.Host) + URL;
}
writer.WriteStartElement("url");
writer.WriteElementString("loc", URL);
writer.WriteElementString("lastmod", DateTime.Now.ToString("yyyy-MM-dd"));
writer.WriteElementString("changefreq", SITEMAP_CHANGEFREQ);
writer.WriteElementString("priority", SITEMAP_PRIORITY);
writer.WriteEndElement();
}
}