Contains extended information about a Page.
예제 #1
0
        /// <summary>
        /// Sorts pages by title.
        /// </summary>
        /// <param name="pages">The pages.</param>
        /// <param name="reverse"><c>true</c> to sort in reverse order.</param>
        /// <returns>The sorted list, divided in relevant groups (#, A, B, etc.).</returns>
        private static SortedDictionary <SortingGroup, List <ExtendedPageInfo> > SortByTitle(ExtendedPageInfo[] pages, bool reverse)
        {
            ExtendedPageInfo[] temp = new ExtendedPageInfo[pages.Length];
            Array.Copy(pages, temp, pages.Length);
            Array.Sort(temp, delegate(ExtendedPageInfo p1, ExtendedPageInfo p2) {
                string t1 = p1.Title, t2 = p2.Title;
                if (!reverse)
                {
                    return(string.Compare(t1, t2, false, CultureInfo.CurrentCulture));
                }
                else
                {
                    return(string.Compare(t2, t1, false, CultureInfo.CurrentCulture));
                }
            });

            SortedDictionary <char, List <ExtendedPageInfo> > result =
                new SortedDictionary <char, List <ExtendedPageInfo> >(new CharComparer(reverse));

            foreach (ExtendedPageInfo p in temp)
            {
                char first = GetFirstChar(p.Title);
                if (!char.IsLetter(first))
                {
                    if (!result.ContainsKey('#'))
                    {
                        result.Add('#', new List <ExtendedPageInfo>(20));
                    }

                    result['#'].Add(p);
                }
                else
                {
                    if (!result.ContainsKey(first))
                    {
                        result.Add(first, new List <ExtendedPageInfo>(20));
                    }

                    result[first].Add(p);
                }
            }

            SortedDictionary <SortingGroup, List <ExtendedPageInfo> > finalResult =
                new SortedDictionary <SortingGroup, List <ExtendedPageInfo> >(new SortingGroupComparer(reverse));

            foreach (char key in result.Keys)
            {
                finalResult.Add(new SortingGroup(GetLetterNumber(key), key.ToString(), key), result[key]);
            }
            return(finalResult);
        }
예제 #2
0
        /// <summary>
        /// Sorts pages by creation date/time.
        /// </summary>
        /// <param name="pages">The pages.</param>
        /// <param name="reverse"><c>true</c> to sort in reverse order.</param>
        /// <returns>The sorted list, divided in relevant groups.</returns>
        private static SortedDictionary <SortingGroup, List <ExtendedPageInfo> > SortByCreation(ExtendedPageInfo[] pages, bool reverse)
        {
            ExtendedPageInfo[] temp = new ExtendedPageInfo[pages.Length];
            Array.Copy(pages, temp, pages.Length);
            Array.Sort(temp, delegate(ExtendedPageInfo p1, ExtendedPageInfo p2) {
                if (!reverse)
                {
                    return(p1.CreationDateTime.CompareTo(p2.CreationDateTime));
                }
                else
                {
                    return(p2.CreationDateTime.CompareTo(p1.CreationDateTime));
                }
            });

            SortedDictionary <DateTime, List <ExtendedPageInfo> > result =
                new SortedDictionary <DateTime, List <ExtendedPageInfo> >(new DateTimeComparer(reverse));

            Dictionary <DateTime, string> labels = new Dictionary <DateTime, string>();

            foreach (ExtendedPageInfo p in temp)
            {
                string   label;
                DateTime marker = GetMarkerDate(p.CreationDateTime, out label);
                if (!result.ContainsKey(marker))
                {
                    result.Add(marker, new List <ExtendedPageInfo>(20));
                    labels.Add(marker, label);
                }
                result[marker].Add(p);
            }

            SortedDictionary <SortingGroup, List <ExtendedPageInfo> > finalResult =
                new SortedDictionary <SortingGroup, List <ExtendedPageInfo> >(new SortingGroupComparer(reverse));

            foreach (DateTime key in result.Keys)
            {
                finalResult.Add(new SortingGroup(key.DayOfYear + key.Year * 1000, labels[key], key), result[key]);
            }
            return(finalResult);
        }
예제 #3
0
        /// <summary>
        /// Prints the pages.
        /// </summary>
        public void PrintPages()
        {
            StringBuilder sb = new StringBuilder(65536);

            if (currentPages == null)
            {
                currentPages = GetAllPages();
            }

            // Prepare ExtendedPageInfo array
            ExtendedPageInfo[] tempPageList = new ExtendedPageInfo[rangeEnd - rangeBegin + 1];
            PageContent        cnt;

            for (int i = 0; i < tempPageList.Length; i++)
            {
                cnt             = Content.GetPageContent(currentPages[rangeBegin + i], true);
                tempPageList[i] = new ExtendedPageInfo(currentPages[rangeBegin + i], cnt.Title, cnt.LastModified, GetCreator(currentPages[rangeBegin + i]), cnt.User);
            }

            // Prepare for sorting
            bool          reverse = false;
            SortingMethod sortBy  = SortingMethod.Title;

            if (Request["SortBy"] != null)
            {
                try {
                    sortBy = (SortingMethod)Enum.Parse(typeof(SortingMethod), Request["SortBy"], true);
                }
                catch {
                    // Backwards compatibility
                    if (Request["SortBy"].ToLowerInvariant() == "date")
                    {
                        sortBy = SortingMethod.DateTime;
                    }
                }
                if (Request["Reverse"] != null)
                {
                    reverse = true;
                }
            }

            SortedDictionary <SortingGroup, List <ExtendedPageInfo> > sortedPages = PageSortingTools.Sort(tempPageList, sortBy, reverse);

            sb.Append(@"<table id=""PageListTable"" class=""generic"" cellpadding=""0"" cellspacing=""0"">");
            sb.Append("<thead>");
            sb.Append(@"<tr class=""tableheader"">");

            // Page title
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Title",
                              (!reverse && sortBy == SortingMethod.Title ? "&amp;Reverse=1" : ""),
                              (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                              "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByTitle);
            sb.Append(@""">");
            sb.Append(Properties.Messages.PageTitle);
            sb.Append((reverse && sortBy.Equals("title") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("title") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Message count
            sb.Append(@"<th><img src=""Images/Comment.png"" alt=""Comments"" /></th>");

            // Creation date/time
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Creation",
                              (!reverse && sortBy == SortingMethod.Creation ? "&amp;Reverse=1" : ""),
                              (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                              "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByDate);
            sb.Append(@""">");
            sb.Append(Properties.Messages.CreatedOn);
            sb.Append((reverse && sortBy.Equals("creation") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("creation") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Mod. date/time
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=DateTime",
                              (!reverse && sortBy == SortingMethod.DateTime ? "&amp;Reverse=1" : ""),
                              (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                              "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByDate);
            sb.Append(@""">");
            sb.Append(Properties.Messages.ModifiedOn);
            sb.Append((reverse && sortBy.Equals("date") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("date") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Creator
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Creator",
                              (!reverse && sortBy == SortingMethod.Creator ? "&amp;Reverse=1" : ""),
                              (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                              "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByUser);
            sb.Append(@""">");
            sb.Append(Properties.Messages.CreatedBy);
            sb.Append((reverse && sortBy.Equals("creator") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("creator") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Last author
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=User",
                              (!reverse && sortBy == SortingMethod.User ? "&amp;Reverse=1" : ""),
                              (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                              "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByUser);
            sb.Append(@""">");
            sb.Append(Properties.Messages.ModifiedBy);
            sb.Append((reverse && sortBy.Equals("user") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("user") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Categories
            sb.Append("<th>");
            sb.Append(Properties.Messages.Categories);
            sb.Append("</th>");

            sb.Append("</tr>");
            sb.Append("</thead><tbody>");

            foreach (SortingGroup key in sortedPages.Keys)
            {
                List <ExtendedPageInfo> pageList = sortedPages[key];
                for (int i = 0; i < pageList.Count; i++)
                {
                    if (i == 0)
                    {
                        // Add group header
                        sb.Append(@"<tr class=""tablerow"">");
                        if (sortBy == SortingMethod.Title)
                        {
                            sb.AppendFormat("<td colspan=\"7\"><b>{0}</b></td>", key.Label);
                        }
                        else if (sortBy == SortingMethod.Creation)
                        {
                            sb.AppendFormat("<td colspan=\"2\"></td><td colspan=\"5\"><b>{0}</b></td>", key.Label);
                        }
                        else if (sortBy == SortingMethod.DateTime)
                        {
                            sb.AppendFormat("<td colspan=\"3\"></td><td colspan=\"4\"><b>{0}</b></td>", key.Label);
                        }
                        else if (sortBy == SortingMethod.Creator)
                        {
                            sb.AppendFormat("<td colspan=\"4\"></td><td colspan=\"3\"><b>{0}</b></td>", key.Label);
                        }
                        else if (sortBy == SortingMethod.User)
                        {
                            sb.AppendFormat("<td colspan=\"5\"></td><td colspan=\"2\"><b>{0}</b></td>", key.Label);
                        }
                        sb.Append("</tr>");
                    }

                    sb.Append(@"<tr class=""tablerow");
                    if ((i + 1) % 2 == 0)
                    {
                        sb.Append("alternate");
                    }
                    sb.Append(@""">");

                    // Page title
                    sb.Append(@"<td>");
                    sb.Append(@"<a href=""");
                    UrlTools.BuildUrl(sb, Tools.UrlEncode(pageList[i].PageInfo.FullName), Settings.PageExtension);
                    sb.Append(@""">");
                    sb.Append(pageList[i].Title);
                    sb.Append("</a>");
                    sb.Append("</td>");

                    // Message count
                    sb.Append(@"<td>");
                    int msg = pageList[i].MessageCount;
                    if (msg > 0)
                    {
                        sb.Append(@"<a href=""");
                        UrlTools.BuildUrl(sb, Tools.UrlEncode(pageList[i].PageInfo.FullName), Settings.PageExtension, "?Discuss=1");
                        sb.Append(@""" title=""");
                        sb.Append(Properties.Messages.Discuss);
                        sb.Append(@""">");
                        sb.Append(msg.ToString());
                        sb.Append("</a>");
                    }
                    else
                    {
                        sb.Append("&nbsp;");
                    }
                    sb.Append("</td>");

                    // Creation date/time
                    sb.Append(@"<td>");
                    sb.Append(Preferences.AlignWithTimezone(pageList[i].CreationDateTime).ToString(Settings.DateTimeFormat) + "&nbsp;");
                    sb.Append("</td>");

                    // Mod. date/time
                    sb.Append(@"<td>");
                    sb.Append(Preferences.AlignWithTimezone(pageList[i].ModificationDateTime).ToString(Settings.DateTimeFormat) + "&nbsp;");
                    sb.Append("</td>");

                    // Creator
                    sb.Append(@"<td>");
                    sb.Append(Users.UserLink(pageList[i].Creator));
                    sb.Append("</td>");

                    // Last author
                    sb.Append(@"<td>");
                    sb.Append(Users.UserLink(pageList[i].LastAuthor));
                    sb.Append("</td>");

                    // Categories
                    CategoryInfo[] cats = Pages.GetCategoriesForPage(pageList[i].PageInfo);
                    sb.Append(@"<td>");
                    if (cats.Length == 0)
                    {
                        sb.Append(@"<a href=""");
                        UrlTools.BuildUrl(sb, "AllPages.aspx?Cat=-");
                        sb.Append(@""">");
                        sb.Append(Properties.Messages.NC);
                        sb.Append("</a>");
                    }
                    else
                    {
                        for (int k = 0; k < cats.Length; k++)
                        {
                            sb.Append(@"<a href=""");
                            UrlTools.BuildUrl(sb, "AllPages.aspx?Cat=", Tools.UrlEncode(cats[k].FullName));
                            sb.Append(@""">");
                            sb.Append(NameTools.GetLocalName(cats[k].FullName));
                            sb.Append("</a>");
                            if (k != cats.Length - 1)
                            {
                                sb.Append(", ");
                            }
                        }
                    }
                    sb.Append("</td>");

                    sb.Append("</tr>");
                }
            }
            sb.Append("</tbody>");
            sb.Append("</table>");

            Literal lbl = new Literal();

            lbl.Text = sb.ToString();
            pnlPageList.Controls.Clear();
            pnlPageList.Controls.Add(lbl);
        }
예제 #4
0
        /// <summary>
        /// Prints the pages.
        /// </summary>
        public void PrintPages()
        {
            StringBuilder sb = new StringBuilder(65536);

            if(currentPages == null) currentPages = GetAllPages();

            // Prepare ExtendedPageInfo array
            ExtendedPageInfo[] tempPageList = new ExtendedPageInfo[rangeEnd - rangeBegin + 1];
            PageContent cnt;
            for(int i = 0; i < tempPageList.Length; i++) {
                cnt = Content.GetPageContent(currentPages[rangeBegin + i], true);
                tempPageList[i] = new ExtendedPageInfo(currentPages[rangeBegin + i], cnt.Title, cnt.LastModified, GetCreator(currentPages[rangeBegin + i]), cnt.User);
            }

            // Prepare for sorting
            bool reverse = false;
            SortingMethod sortBy = SortingMethod.Title;
            if(Request["SortBy"] != null) {
                try {
                    sortBy = (SortingMethod)Enum.Parse(typeof(SortingMethod), Request["SortBy"], true);
                }
                catch {
                    // Backwards compatibility
                    if(Request["SortBy"].ToLowerInvariant() == "date") sortBy = SortingMethod.DateTime;
                }
                if(Request["Reverse"] != null) reverse = true;
            }

            SortedDictionary<SortingGroup, List<ExtendedPageInfo>> sortedPages = PageSortingTools.Sort(tempPageList, sortBy, reverse);

            sb.Append(@"<table id=""PageListTable"" class=""generic"" cellpadding=""0"" cellspacing=""0"">");
            sb.Append("<thead>");
            sb.Append(@"<tr class=""tableheader"">");

            // Page title
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Title",
                (!reverse && sortBy == SortingMethod.Title ? "&amp;Reverse=1" : ""),
                (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByTitle);
            sb.Append(@""">");
            sb.Append(Properties.Messages.PageTitle);
            sb.Append((reverse && sortBy.Equals("title") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("title") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Message count
            sb.Append(@"<th><img src=""Images/Comment.png"" alt=""Comments"" /></th>");

            // Creation date/time
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Creation",
                (!reverse && sortBy == SortingMethod.Creation ? "&amp;Reverse=1" : ""),
                (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByDate);
            sb.Append(@""">");
            sb.Append(Properties.Messages.CreatedOn);
            sb.Append((reverse && sortBy.Equals("creation") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("creation") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Mod. date/time
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=DateTime",
                (!reverse && sortBy == SortingMethod.DateTime ? "&amp;Reverse=1" : ""),
                (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByDate);
            sb.Append(@""">");
            sb.Append(Properties.Messages.ModifiedOn);
            sb.Append((reverse && sortBy.Equals("date") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("date") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Creator
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=Creator",
                (!reverse && sortBy == SortingMethod.Creator ? "&amp;Reverse=1" : ""),
                (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByUser);
            sb.Append(@""">");
            sb.Append(Properties.Messages.CreatedBy);
            sb.Append((reverse && sortBy.Equals("creator") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("creator") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Last author
            sb.Append(@"<th><a rel=""nofollow"" href=""");
            UrlTools.BuildUrl(sb, "AllPages.aspx?SortBy=User",
                (!reverse && sortBy == SortingMethod.User ? "&amp;Reverse=1" : ""),
                (Request["Cat"] != null ? "&amp;Cat=" + Tools.UrlEncode(Request["Cat"]) : ""),
                "&amp;Page=", selectedPage.ToString());

            sb.Append(@""" title=""");
            sb.Append(Properties.Messages.SortByUser);
            sb.Append(@""">");
            sb.Append(Properties.Messages.ModifiedBy);
            sb.Append((reverse && sortBy.Equals("user") ? " &uarr;" : ""));
            sb.Append((!reverse && sortBy.Equals("user") ? " &darr;" : ""));
            sb.Append("</a></th>");

            // Categories
            sb.Append("<th>");
            sb.Append(Properties.Messages.Categories);
            sb.Append("</th>");

            sb.Append("</tr>");
            sb.Append("</thead><tbody>");

            foreach(SortingGroup key in sortedPages.Keys) {
                List<ExtendedPageInfo> pageList = sortedPages[key];
                for(int i = 0; i < pageList.Count; i++) {
                    if(i == 0) {
                        // Add group header
                        sb.Append(@"<tr class=""tablerow"">");
                        if(sortBy == SortingMethod.Title) {
                            sb.AppendFormat("<td colspan=\"7\"><b>{0}</b></td>", key.Label);
                        }
                        else if(sortBy == SortingMethod.Creation) {
                            sb.AppendFormat("<td colspan=\"2\"></td><td colspan=\"5\"><b>{0}</b></td>", key.Label);
                        }
                        else if(sortBy == SortingMethod.DateTime) {
                            sb.AppendFormat("<td colspan=\"3\"></td><td colspan=\"4\"><b>{0}</b></td>", key.Label);
                        }
                        else if(sortBy == SortingMethod.Creator) {
                            sb.AppendFormat("<td colspan=\"4\"></td><td colspan=\"3\"><b>{0}</b></td>", key.Label);
                        }
                        else if(sortBy == SortingMethod.User) {
                            sb.AppendFormat("<td colspan=\"5\"></td><td colspan=\"2\"><b>{0}</b></td>", key.Label);
                        }
                        sb.Append("</tr>");
                    }

                    sb.Append(@"<tr class=""tablerow");
                    if((i + 1) % 2 == 0) sb.Append("alternate");
                    sb.Append(@""">");

                    // Page title
                    sb.Append(@"<td>");
                    sb.Append(@"<a href=""");
                    UrlTools.BuildUrl(sb, Tools.UrlEncode(pageList[i].PageInfo.FullName), Settings.PageExtension);
                    sb.Append(@""">");
                    sb.Append(pageList[i].Title);
                    sb.Append("</a>");
                    sb.Append("</td>");

                    // Message count
                    sb.Append(@"<td>");
                    int msg = pageList[i].MessageCount;
                    if(msg > 0) {
                        sb.Append(@"<a href=""");
                        UrlTools.BuildUrl(sb, Tools.UrlEncode(pageList[i].PageInfo.FullName), Settings.PageExtension, "?Discuss=1");
                        sb.Append(@""" title=""");
                        sb.Append(Properties.Messages.Discuss);
                        sb.Append(@""">");
                        sb.Append(msg.ToString());
                        sb.Append("</a>");
                    }
                    else sb.Append("&nbsp;");
                    sb.Append("</td>");

                    // Creation date/time
                    sb.Append(@"<td>");
                    sb.Append(Preferences.AlignWithTimezone(pageList[i].CreationDateTime).ToString(Settings.DateTimeFormat) + "&nbsp;");
                    sb.Append("</td>");

                    // Mod. date/time
                    sb.Append(@"<td>");
                    sb.Append(Preferences.AlignWithTimezone(pageList[i].ModificationDateTime).ToString(Settings.DateTimeFormat) + "&nbsp;");
                    sb.Append("</td>");

                    // Creator
                    sb.Append(@"<td>");
                    sb.Append(Users.UserLink(pageList[i].Creator));
                    sb.Append("</td>");

                    // Last author
                    sb.Append(@"<td>");
                    sb.Append(Users.UserLink(pageList[i].LastAuthor));
                    sb.Append("</td>");

                    // Categories
                    CategoryInfo[] cats = Pages.GetCategoriesForPage(pageList[i].PageInfo);
                    sb.Append(@"<td>");
                    if(cats.Length == 0) {
                        sb.Append(@"<a href=""");
                        UrlTools.BuildUrl(sb, "AllPages.aspx?Cat=-");
                        sb.Append(@""">");
                        sb.Append(Properties.Messages.NC);
                        sb.Append("</a>");
                    }
                    else {
                        for(int k = 0; k < cats.Length; k++) {
                            sb.Append(@"<a href=""");
                            UrlTools.BuildUrl(sb, "AllPages.aspx?Cat=", Tools.UrlEncode(cats[k].FullName));
                            sb.Append(@""">");
                            sb.Append(NameTools.GetLocalName(cats[k].FullName));
                            sb.Append("</a>");
                            if(k != cats.Length - 1) sb.Append(", ");
                        }
                    }
                    sb.Append("</td>");

                    sb.Append("</tr>");
                }
            }
            sb.Append("</tbody>");
            sb.Append("</table>");

            Literal lbl = new Literal();
            lbl.Text = sb.ToString();
            pnlPageList.Controls.Clear();
            pnlPageList.Controls.Add(lbl);
        }