PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/App_Code/Controls/CategoryList.cs

#
C# | 269 lines | 165 code | 49 blank | 55 comment | 14 complexity | 755b5bcc06fb84dcdca5c3c2b91f3442 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <summary>
  3. // Builds a category list.
  4. // </summary>
  5. // --------------------------------------------------------------------------------------------------------------------
  6. namespace App_Code.Controls
  7. {
  8. using System;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Web;
  13. using System.Web.UI;
  14. using System.Web.UI.HtmlControls;
  15. using BlogEngine.Core;
  16. /// <summary>
  17. /// Builds a category list.
  18. /// </summary>
  19. public class CategoryList : Control
  20. {
  21. #region Constants and Fields
  22. /// <summary>
  23. /// The html string.
  24. /// </summary>
  25. private static Dictionary<Guid, string> blogsHtml = new Dictionary<Guid, string>();
  26. /// <summary>
  27. /// The show rss icon.
  28. /// </summary>
  29. private static Dictionary<Guid, bool> blogsShowRssIcon = new Dictionary<Guid, bool>();
  30. /// <summary>
  31. /// The show post count.
  32. /// </summary>
  33. private bool showPostCount;
  34. #endregion
  35. #region Constructors and Destructors
  36. /// <summary>
  37. /// Initializes static members of the <see cref = "CategoryList" /> class.
  38. /// </summary>
  39. static CategoryList()
  40. {
  41. Post.Saved += (sender, args) => blogsHtml.Remove(Blog.CurrentInstance.Id);
  42. Category.Saved += (sender, args) => blogsHtml.Remove(Blog.CurrentInstance.Id);
  43. }
  44. #endregion
  45. #region Properties
  46. /// <summary>
  47. /// Gets or sets a value indicating whether ShowPostCount.
  48. /// </summary>
  49. public bool ShowPostCount
  50. {
  51. get
  52. {
  53. return this.showPostCount;
  54. }
  55. set
  56. {
  57. if (this.showPostCount == value)
  58. {
  59. return;
  60. }
  61. this.showPostCount = value;
  62. blogsHtml.Remove(Blog.CurrentInstance.Id);
  63. }
  64. }
  65. /// <summary>
  66. /// Gets or sets a value indicating whether or not to show feed icons next to the category links.
  67. /// </summary>
  68. public bool ShowRssIcon
  69. {
  70. get
  71. {
  72. Guid blogId = Blog.CurrentInstance.Id;
  73. if (!blogsShowRssIcon.ContainsKey(blogId))
  74. blogsShowRssIcon[blogId] = true;
  75. return blogsShowRssIcon[blogId];
  76. }
  77. set
  78. {
  79. if (ShowRssIcon == value)
  80. {
  81. return;
  82. }
  83. blogsShowRssIcon[Blog.CurrentInstance.Id] = value;
  84. blogsHtml.Remove(Blog.CurrentInstance.Id);
  85. }
  86. }
  87. /// <summary>
  88. /// Gets Html.
  89. /// </summary>
  90. private string Html
  91. {
  92. get
  93. {
  94. Guid blogId = Blog.CurrentInstance.Id;
  95. if (!blogsHtml.ContainsKey(blogId))
  96. {
  97. var ul = this.BindCategories();
  98. using (var sw = new StringWriter())
  99. {
  100. using (var hw = new HtmlTextWriter(sw))
  101. {
  102. ul.RenderControl(hw);
  103. blogsHtml[blogId] = sw.ToString();
  104. }
  105. }
  106. }
  107. return blogsHtml[blogId];
  108. }
  109. }
  110. #endregion
  111. #region Public Methods
  112. /// <summary>
  113. /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
  114. /// </summary>
  115. /// <param name="writer">
  116. /// The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.
  117. /// </param>
  118. public override void RenderControl(HtmlTextWriter writer)
  119. {
  120. writer.Write(this.Html);
  121. writer.Write(Environment.NewLine);
  122. }
  123. #endregion
  124. #region Methods
  125. /// <summary>
  126. /// Determines whether the specified category has posts.
  127. /// </summary>
  128. /// <param name="cat">
  129. /// The category.
  130. /// </param>
  131. /// <returns>
  132. /// <c>true</c> if the specified category has posts; otherwise, <c>false</c>.
  133. /// </returns>
  134. private static bool HasPosts(Category cat)
  135. {
  136. return
  137. Post.Posts.Where(post => post.IsVisible).SelectMany(post => post.Categories).Any(
  138. category => category == cat);
  139. }
  140. /// <summary>
  141. /// Sorts the categories.
  142. /// </summary>
  143. /// <returns>
  144. /// The sorted categories.
  145. /// </returns>
  146. private static SortedDictionary<string, Guid> SortCategories()
  147. {
  148. var dic = new SortedDictionary<string, Guid>();
  149. foreach (var cat in Category.Categories.Where(HasPosts))
  150. {
  151. dic.Add(cat.CompleteTitle(), cat.Id);
  152. }
  153. return dic;
  154. }
  155. /// <summary>
  156. /// Binds the categories.
  157. /// </summary>
  158. /// <returns>A category control.</returns>
  159. private HtmlGenericControl BindCategories()
  160. {
  161. var dic = SortCategories();
  162. if (dic.Keys.Count == 0)
  163. {
  164. var none = new HtmlGenericControl("p") { InnerText = "None" };
  165. return none;
  166. }
  167. var ul = new HtmlGenericControl("ul") { ID = "categorylist" };
  168. foreach (var id in dic.Values)
  169. {
  170. // Find full category
  171. var cat = Category.GetCategory(id);
  172. var key = cat.CompleteTitle();
  173. var li = new HtmlGenericControl("li");
  174. int i = cat.CompleteTitle().Count(c => c == '-');
  175. string spaces = string.Empty;
  176. for (int j = 0; j < i; j++)
  177. {
  178. spaces += "&#160;&#160;&#160";
  179. }
  180. if (i > 0)
  181. {
  182. var textArea = new HtmlAnchor();
  183. textArea.InnerHtml = spaces;
  184. li.Controls.Add(textArea);
  185. }
  186. if (this.ShowRssIcon)
  187. {
  188. var img = new HtmlImage
  189. {
  190. Src = string.Format("{0}pics/rssButton.png", Utils.RelativeWebRoot),
  191. Alt =
  192. string.Format(
  193. "{0} feed for {1}", BlogSettings.Instance.SyndicationFormat.ToUpperInvariant(), key)
  194. };
  195. img.Attributes["class"] = "rssButton";
  196. var feedAnchor = new HtmlAnchor { HRef = cat.FeedRelativeLink };
  197. feedAnchor.Attributes["rel"] = "nofollow";
  198. feedAnchor.Controls.Add(img);
  199. li.Controls.Add(feedAnchor);
  200. }
  201. var posts = Post.GetPostsByCategory(dic[key]).FindAll(p => p.IsVisible).Count;
  202. var postCount = string.Format(" ({0})", posts);
  203. if (!this.ShowPostCount)
  204. {
  205. postCount = null;
  206. }
  207. var anc = new HtmlAnchor
  208. {
  209. HRef = cat.RelativeLink,
  210. InnerHtml = HttpUtility.HtmlEncode(cat.Title) + postCount,
  211. Title = string.Format("Categorie: {0}", key)
  212. };
  213. li.Controls.Add(anc);
  214. ul.Controls.Add(li);
  215. }
  216. return ul;
  217. }
  218. #endregion
  219. }
  220. }