Sort BlogEngine.net Page List by Title

Here is a code snippet to sort Blogengine.net page list.
You want to modify the following C# file: BlogEngine\BlogEngine.NET\AppCode\Controls\PageList.cs
LINQ used to sort the pages and changed the Foreach loop to use the LINQ query.
private static HtmlGenericControl BindPages()
{
    var ul = new HtmlGenericControl("ul") { ID = "pagelist" };
    ul.Attributes.Add("class", "pagelist");

    //Sort pages
    var MyPages = BlogEngine.Core.Page.Pages.AsEnumerable()
        .OrderBy(x=> x.Title);
     
    //foreach (var page in BlogEngine.Core.Page.Pages.Where(page => page.ShowInList && page.IsVisibleToPublic ))
    foreach (var page in MyPages.Where(page => page.ShowInList && page.IsVisibleToPublic))
    {
        var li = new HtmlGenericControl("li");
        var href = page.RelativeLink;
        if (BlogSettings.Instance.RemoveExtensionsFromUrls && !string.IsNullOrEmpty(BlogConfig.FileExtension))
            href = href.Replace(BlogConfig.FileExtension, "");
        
        var anc = new HtmlAnchor { HRef = href, InnerHtml = page.Title, Title = page.Description };

        li.Controls.Add(anc);                
        ul.Controls.Add(li);
    }
    
    return ul;
}

Sort BlogEngine.net Link List by Title

Here is a code snippet to sort Blogengine.net link list.

You want to modify the following C# file: BlogEngine\BlogEngine.NET\Custom\Widgets\LinkList\widget.ascx.cs

Listed below is the original code from the method:  LoadWidget()
//-----------------
//Orginal code
//-----------------              
foreach (XmlNode node in links)
{
    var a = new HtmlAnchor();

    if (node.Attributes != null)
    {
        if (node.Attributes["url"] != null)
        {
            a.HRef = node.Attributes["url"].InnerText;
        }

        if (node.Attributes["title"] != null)
        {
            a.InnerText = node.Attributes["title"].InnerText;
        }

        if (node.Attributes["newwindow"] != null &&
            node.Attributes["newwindow"].InnerText.Equals("true", StringComparison.OrdinalIgnoreCase))
        {
            a.Target = "_blank";
        }
    }

    var li = new HtmlGenericControl("li");
    li.Controls.Add(a);
    this.ulLinks.Controls.Add(li);
}

Replace the code above with the following: 

The updated code starts at...
//--------------------------------------------------
//1. Put links in a table, the sort and process
//--------------------------------------------------
public override void LoadWidget()
{
    var settings = this.GetSettings();
    var doc = new XmlDocument();

    if (settings["content"] != null)
    {
        doc.InnerXml = settings["content"];
    }

    var links = doc.SelectNodes("//link");

    if (links == null)
    {
        return;
    }

    if (links.Count == 0)
    {
        this.ulLinks.Visible = false;
    }
    else
    {
        //--------------------------------------------------
        //1. Put links in a table, the sort and process
        //--------------------------------------------------
        DataTable DtLinks = new System.Data.DataTable();
        DtLinks.Columns.Add("URL", typeof(String));
        DtLinks.Columns.Add("Title", typeof(String));
        DtLinks.Columns.Add("Target", typeof(String));

        //--------------------------------------------------
        //2. Add to table
        //--------------------------------------------------
        DataRow dr = DtLinks.NewRow();

        foreach (XmlNode node in links)
        {
            if (node.Attributes != null)
            {
                //Create Row and Default Values
                dr = DtLinks.NewRow();
                dr["URL"] = string.Empty;
                dr["Title"] = string.Empty;
                dr["Target"] = string.Empty;

                if (node.Attributes["url"] != null)
                {
                    dr["URL"] = node.Attributes["url"].InnerText.ToString();
                }

                if (node.Attributes["title"] != null)
                {
                    dr["Title"] = node.Attributes["title"].InnerText.ToString();
                }

                if (node.Attributes["newwindow"] != null &&
                    node.Attributes["newwindow"].InnerText.Equals("true", StringComparison.OrdinalIgnoreCase))
                {
                    dr["Target"] = "_blank";
                }

                DtLinks.Rows.Add(dr);
            }                    
        }                

       DtLinks.AcceptChanges();

       //--------------------------------------------------
       // 3. Loop through table and add to list item.
       //--------------------------------------------------
       DataView View = DtLinks.DefaultView;
       View.Sort = "Title";

       foreach (DataRowView row in View)
       {
           var a = new HtmlAnchor();
           a.HRef = row["URL"].ToString();
           a.InnerText = row["Title"].ToString();

           if (row["Target"].ToString() != string.Empty) a.Target = row["Target"].ToString();

           var li = new HtmlGenericControl("li");
           li.Controls.Add(a);
           this.ulLinks.Controls.Add(li);
       }            
    }
}

Show Progress Message / Call ASP.NET Button Click from JavaScript

I have a batch process that runs on a background thread on an ASP.NET site. When that batch process runs I did not want the users to access specific features of the site. If you want to read more about running batch jobs from a website using ASP.NET and IIS read this post.

In order to do that I added a Boolean flag to the server cache for 10 minutes. When the users access a specific feature of the site it will check if the flag in the cache is set. If so the end user will be taken to a page that shows a “Batch Running” message (shown below using jQuery).   The “Batch Running” page will post back to the server every minute checking if the cache item exists. Once the cache item is gone the batch process page will redirect the user back to the feature that was offline.
if (CTX.Cache["BatchRunning"] == null) Response.Redirect("~/default.aspx")

The Javascript below clicks a button every minute to post back the page
var Timer = setInterval(function () { ClickButton() }, 60000);
function ClickButton() {
    document.getElementById("BtnPost").click();
}
The ZIP file below contains a HTML page and an ASPX page with the code discussed in this post.
BatchProcessingMessage.zip (3.3KB)