public async Task <IActionResult> Edit(PostEditViewModel postEditViewModel) { if (ModelState.IsValid) { var slug = BlogUtils.CreateSlug(postEditViewModel.Slug); if (string.IsNullOrEmpty(slug)) { ModelState.AddModelError(ModelStateErrorMsgKey, MsgInvalidSlug); return(View(postEditViewModel)); } var slugIsUnique = await _postRepo.CheckIfSlugIsUnique(slug, postEditViewModel.PostId); if (!slugIsUnique) { ModelState.AddModelError(ModelStateErrorMsgKey, MsgDuplicateSlug); return(View(postEditViewModel)); } postEditViewModel.Slug = slug; var updateResult = await _postRepo.UpdatePost(postEditViewModel); if (updateResult) { return(Redirect(Url.Action("AnyPost", "Blog", new { slug }))); } } ModelState.AddModelError(ModelStateErrorMsgKey, MsgSomethingIsWrong); return(View(postEditViewModel)); }
protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); AgilityComponents.EnsureBaseCSSLoaded(); BlogUtils.EnsureBlogCSSLoaded(); BlogUtils.EnsureBlogJSLoaded(); }
public async Task <IActionResult> AddPost(PostCreateViewModel createPostViewModel) { if (ModelState.IsValid) { var slug = BlogUtils.CreateSlug(createPostViewModel.Slug); if (string.IsNullOrEmpty(slug)) { ModelState.AddModelError(ModelStateErrorMsgKey, MsgInvalidSlug); return(View(createPostViewModel)); } var slugIsUnique = await _postRepo.CheckIfSlugIsUnique(slug); if (!slugIsUnique) { ModelState.AddModelError(ModelStateErrorMsgKey, MsgDuplicateSlug); return(View(createPostViewModel)); } createPostViewModel.Slug = slug; var user = await GetLoggedInUser(); var result = await _postRepo.AddPost(createPostViewModel, user); if (result) { return(Redirect(Url.Action("AnyPost", "Blog", new { slug }))); } } ModelState.AddModelError(ModelStateErrorMsgKey, MsgSomethingIsWrong); return(View(createPostViewModel)); }
public ActionResult FeaturedBlogPost(AgilityContentItem module) { #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion string postIDs = module["PostIDs"] as string; var post = BlogUtils.GetItemsByIDs(blogPosts.ContentReferenceName, postIDs).FirstOrDefault(); if (post == null) { return(null); } var model = new PostViewModel(); model.Configuration = blogConfig; model.Post = post; return(PartialView(AgilityComponents.TemplatePath("Blog-FeaturedPostModule"), model)); }
public ActionResult BlogRecent(AgilityContentItem module) { #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion int recentPostsLimit; int.TryParse(string.Format("{0}", blogConfig["RecentPostsMax"]), out recentPostsLimit); if (recentPostsLimit < 1) { recentPostsLimit = 12; } var posts = BlogUtils.GetPosts(blogPosts, "", "Date Desc", recentPostsLimit, 0); var model = new BlogLinkViewModel(); model.ShowCount = false; model.Items = posts.Select(i => new BlogLinkItem() { Title = i["Title"] as string, Url = i.BlogDynamicUrl(blogConfig, null), Excerpt = BlogUtils.GetPostDescription(i, "Excerpt", blogConfig["AutoExcerptLength"]) }).ToList(); model.Configuration = blogConfig; return(PartialView(AgilityComponents.TemplatePath("Blog-RecentPostsModule"), model)); }
public ActionResult BlogHistory(AgilityContentItem module) { #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion int numMonthsToDisplay; int.TryParse(string.Format("{0}", blogConfig["BlogHistoryMonthsMax"]), out numMonthsToDisplay); if (numMonthsToDisplay < 1) { numMonthsToDisplay = 12; } var months = new List <DateTime>(); for (var i = 0; i < numMonthsToDisplay; i++) { var month = DateTime.Now.AddMonths(-i); months.Add(month); } var model = new BlogLinkViewModel(); model.ShowCount = model.ShowCount = BlogUtils.GetBool(blogConfig["ShowPostCounts"]); model.Items = BlogUtils.GetBlogLinksWithPostCounts(blogConfig, blogPosts, months, model.ShowCount); model.SkipZeroPosts = true; model.Configuration = blogConfig; return(PartialView(AgilityComponents.TemplatePath("Blog-HistoryModule"), model)); }
public BlogPaginationViewModel(int pageNumber, int pageSize, int totalCount, bool showLastPage, int lengthOfPager = 5, string queryStringParam = "page", string activeClass = "active", string disabledClass = "disabled", string nextLabel = "Next", string prevLabel = "Previous" ) { Page = pageNumber; PageSize = pageSize; TotalCount = totalCount; NumberOfPages = (int)Math.Ceiling((double)TotalCount / PageSize); LengthOfPager = lengthOfPager; QueryStringParam = queryStringParam; ActiveClass = activeClass; DisabledClass = disabledClass; NextLabel = nextLabel; PreviousLabel = prevLabel; ShowLastPage = showLastPage; //set start and end range indexes double result = (double)Page / LengthOfPager; StartRangeIndex = (int)(Math.Floor(result) * LengthOfPager); if (Page % LengthOfPager == LengthOfPager) { StartRangeIndex = StartRangeIndex + LengthOfPager; } if (StartRangeIndex == 0) { StartRangeIndex = 1; } EndRangeIndex = StartRangeIndex + (LengthOfPager - 1); //set rel/prev for seo string relPrev = ""; if (Page > 1) { relPrev = string.Format("<link rel=\"prev\" href=\"{0}\" />", BlogUtils.GetPagedUrl(QueryStringParam, Page - 1, true)); } if (Page != NumberOfPages && NumberOfPages != 0) { if (relPrev.Length > 0) { relPrev += Environment.NewLine; } relPrev += string.Format("<link rel=\"next\" href=\"{0}\" />", BlogUtils.GetPagedUrl(QueryStringParam, Page + 1, true)); } AgilityContext.Page.MetaTagsRaw += relPrev; }
public ActionResult BlogAuthorDetails(AgilityContentItem module) { HttpContext.Response.Cache.VaryByParams[BlogContext.PagingQueryStringKey] = true; #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion var author = AgilityContext.GetDynamicPageItem <AgilityContentItem>(); if (!author.IsBlogAuthor()) { return(null); } #region --- Get Posts and set Pagination --- List <AgilityContentItem> posts = null; BlogPaginationViewModel pagination = null; if (BlogUtils.GetBool(module["DisplayRecentBlogPosts"])) { int pageSize = 10; int.TryParse(string.Format("{0}", module["PageSize"]), out pageSize); if (pageSize < 1) { pageSize = 10; } int pageNumber = 1; int.TryParse(Request.QueryString[BlogContext.PagingQueryStringKey] as string, out pageNumber); if (pageNumber < 1) { pageNumber = 1; } int skip = (pageNumber * pageSize) - pageSize; int totalCount = 0; //get the posts posts = BlogUtils.GetPosts(blogPosts, author.ContentID, "", "", "", "", "Date Desc", pageSize, skip, out totalCount); pagination = new BlogPaginationViewModel(pageNumber, pageSize, totalCount, true, 5, BlogContext.PagingQueryStringKey, "agility-active", "agility-disabled"); } #endregion var model = new BlogAuthorViewModel(); model.Author = author; model.Posts = posts; model.Module = module; model.Configuration = blogConfig; model.Pagination = pagination; return(PartialView(AgilityComponents.TemplatePath("Blog-AuthorDetailsModule"), model)); }
public EditBlogViewModel(string blogId) { var utils = new BlogUtils(Context); BlogId = Int32.Parse(blogId); _memUser = Membership.GetUser(HttpContext.Current.User.Identity.Name); SiteUrl = HTTPUtils.GetFullyQualifiedApplicationPath() + "blog/"; ThisBlog = Context.Blogs.FirstOrDefault(x => x.BlogId == BlogId); if (ThisBlog == null) { throw new KeyNotFoundException(); } if (ThisBlog.Category == null) { ThisBlog.Category = utils.GetUncategorizedCategory(); } // Make sure we have a permalink set if (String.IsNullOrEmpty(ThisBlog.PermaLink)) { ThisBlog.PermaLink = ContentUtils.GetFormattedUrl(ThisBlog.Title); Context.SaveChanges(); } // Get the list of Authors for the drop down select BlogUsers = Context.BlogUsers.Where(x => x.IsActive).OrderBy(x => x.DisplayName).ToList(); Categories = Context.BlogCategories.Where(x => x.IsActive).ToList(); UsersSelectedCategories = new List <string>(); _thisUser = Context.Users.FirstOrDefault(x => x.Username == _memUser.UserName); // Get and parse tags for unqiue count var tagList = Context.Blogs.Select(x => x.Tags).ToList(); var tagStr = String.Join(",", tagList); var tags = tagStr.Split(',').Select(x => x.Trim()).ToList(); TagCounts = new List <TagMetric>(); TagCounts = Context.BlogTags.Select(t => new TagMetric() { Tag = t.BlogTagName, Count = t.Blogs.Count() }).ToList(); BookmarkTitle = ThisBlog.Title; // Get the admin modules that will be displayed to the user in each column getAdminModules(); }
public EditBlogViewModel(string blogId) { var utils = new BlogUtils(Context); BlogId = Int32.Parse(blogId); _memUser = Membership.GetUser(HttpContext.Current.User.Identity.Name); SiteUrl = HTTPUtils.GetFullyQualifiedApplicationPath() + "blog/"; ThisBlog = Context.Blogs.FirstOrDefault(x => x.BlogId == BlogId); if (ThisBlog == null) { throw new KeyNotFoundException(); } if (ThisBlog.Category == null) { ThisBlog.Category = utils.GetUncategorizedCategory(); } // Make sure we have a permalink set if (String.IsNullOrEmpty(ThisBlog.PermaLink)) { ThisBlog.PermaLink = ContentUtils.GetFormattedUrl(ThisBlog.Title); Context.SaveChanges(); } // Get the list of Authors for the drop down select BlogUsers = Context.BlogUsers.Where(x => x.IsActive).OrderBy(x => x.DisplayName).ToList(); Categories = Context.BlogCategories.Where(x => x.IsActive).ToList(); UsersSelectedCategories = new List<string>(); _thisUser = Context.Users.FirstOrDefault(x => x.Username == _memUser.UserName); // Get and parse tags for unqiue count var tagList = Context.Blogs.Select(x => x.Tags).ToList(); var tagStr = String.Join(",", tagList); var tags = tagStr.Split(',').Select(x => x.Trim()).ToList(); TagCounts = new List<TagMetric>(); TagCounts = Context.BlogTags.Select(t => new TagMetric() { Tag = t.BlogTagName, Count = t.Blogs.Count() }).ToList(); BookmarkTitle = ThisBlog.Title; // Get the admin modules that will be displayed to the user in each column getAdminModules(); }
private static PostViewModel CreatePostViewModel(Post post) { post.Content = BlogUtils.FormatPostContent(post.Content); return(new PostViewModel() { Id = post.Id, Title = post.Title, Content = post.Content, PubDate = post.PubDate, Comments = post.Comments.OrderByDescending(c => c.PubDate), Slug = post.Slug }); }
public async ValueTask ExecuteAsync(IConsole console) { var table = new Table(); table.AddColumn("Draft filename"); table.AddColumn("Title"); table.AddColumn(new TableColumn("Created").Centered()); table.AddColumn(new TableColumn("Tags").Centered()); table.AddColumn(new TableColumn("Permalink").Centered()); await foreach (var(fileInfo, draftFrontMatter) in BlogUtils.GetDraftInfos()) { table.AddRow($"{fileInfo.Name}", $"{draftFrontMatter.Title}", $"[green]{draftFrontMatter.Date}[/]", $"{string.Join(", ", draftFrontMatter.Tags)}", $"{draftFrontMatter.PermaLink}"); } AnsiConsole.Render(table); }
public async Task <IActionResult> AddComment(string comment, string postId, string postSlug) { var user = await GetLoggedInUser(); var post = await _postRepo.GetPostById(postId); await _postRepo.AddComment(BlogUtils.CreateComment(user, comment, post)); if (post.IsPublished) { return(Redirect(Url.Action("Post", new { slug = postSlug }) + CommentsSection)); } return(Redirect(Url.Action("AnyPost", new { slug = postSlug }) + CommentsSection)); }
public ActionResult BlogTags(AgilityContentItem module) { #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion var model = new BlogLinkViewModel(); model.ShowCount = BlogUtils.GetBool(blogConfig["ShowPostCounts"]); model.Items = BlogUtils.GetBlogLinksWithPostCounts(blogConfig, blogPosts, blogTags, model.ShowCount); model.Configuration = blogConfig; return(PartialView(AgilityComponents.TemplatePath("Blog-TagsModule"), model)); }
public async ValueTask ExecuteAsync(IConsole console) { var(draftFileInfo, draftFrontMatter) = await BlogUtils.AskUserToSelectDraft("Which draft do you want to publish?"); var blogPostPath = Path.Combine(BlogSettings.PostsFolder, draftFileInfo.Name); if (!Overwrite && File.Exists(blogPostPath)) { await console.Output.WriteLineAsync($"File exists, please use {nameof(Overwrite)} parameter."); return; } var updatedDraftLines = await GetUpdatedDraftFrontMatterLines(draftFileInfo.FullName, draftFrontMatter); await File.WriteAllLinesAsync(blogPostPath, updatedDraftLines); File.Delete(draftFileInfo.FullName); AnsiConsole.Markup($"Published [green]{blogPostPath}[/]"); }
public BlogController() { Utils = new BlogUtils(Context); }
public async ValueTask ExecuteAsync(IConsole console) { var(fileInfo, _) = await BlogUtils.AskUserToSelectDraft("Which draft do you want to edit?"); await Command.RunAsync("cmd.exe", $"/c code {fileInfo.FullName}", "./"); }
public ActionResult BlogListing(AgilityContentItem module) { HttpContext.Response.Cache.VaryByParams["month"] = true; HttpContext.Response.Cache.VaryByParams[BlogContext.PagingQueryStringKey] = true; /* * check querystrings for filtering by "month" * check module for any specific filters being set (by category(s) or by tag(s)) * check current dynamic page item and identify if its a category or tag, if so override any previous filter * get all blog posts by passing in filter and paging logic * create a viewmodel that contains posts, the module, and blog configuration * return partial view in inline code or local files (dependant on setting in BlogUtils) */ #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion #region --- Determine Filters --- DateTime filterMonth = DateTime.MinValue; var categories = new List <AgilityContentItem>(); var tags = new List <AgilityContentItem>(); //check for month string monthQS = Request.QueryString["month"] as string; //look for month=05-2015 if (!string.IsNullOrEmpty(monthQS)) { try { filterMonth = DateTime.ParseExact(monthQS, "MM-yyyy", CultureInfo.InvariantCulture); } catch (FormatException ex) { Agility.Web.Tracing.WebTrace.WriteInfoLine(ex.ToString()); } } //check for dynamic item var dynamicItem = ResolveBlogCategory(); var node = SiteMap.CurrentNode; if (dynamicItem != null) { if (dynamicItem.IsBlogTag()) { tags.Add(dynamicItem); } else if (dynamicItem.IsBlogCategory()) { categories.Add(dynamicItem); } else { //this is on some other dynamic page item, ignore it dynamicItem = null; } } //skip module settings if we have a dynamic item set, else check if (dynamicItem == null) { string categoryIDs = module["FilterByCategoriesIDs"] as string; string tagsIDs = module["FilterByTagsIDs"] as string; if (!string.IsNullOrEmpty(categoryIDs)) { var categoriesFromModule = blogCategories.GetByIDs(categoryIDs); if (categoriesFromModule != null && categoriesFromModule.Any()) { categories.AddRange(categoriesFromModule); } } if (!string.IsNullOrEmpty(tagsIDs)) { var tagsFromModule = blogTags.GetByIDs(tagsIDs); if (tagsFromModule != null && tagsFromModule.Any()) { tags.AddRange(tagsFromModule); } } } string dateFilter = ""; if (filterMonth != DateTime.MinValue) { dateFilter = BlogUtils.GetSqlBetweenMonthRangeStatement("Date", filterMonth); } #endregion --- End Determine Filters --- #region --- Get Posts and set Pagination --- int pageSize = 10; int.TryParse(string.Format("{0}", module["PageSize"]), out pageSize); if (pageSize < 1) { pageSize = 10; } int pageNumber = 1; int.TryParse(Request.QueryString[BlogContext.PagingQueryStringKey] as string, out pageNumber); if (pageNumber < 1) { pageNumber = 1; } int skip = (pageNumber * pageSize) - pageSize; int totalCount = 0; //get the posts List <AgilityContentItem> posts = BlogUtils.GetPosts(blogPosts, null, null, categories, tags, dateFilter, "Date Desc", pageSize, skip, out totalCount); var pagination = new BlogPaginationViewModel(pageNumber, pageSize, totalCount, true, 5, BlogContext.PagingQueryStringKey, "agility-active", "agility-disabled"); #endregion #region --- Set Title --- //cannot set Page Title from child controller action and no way of knowing how the website layout is setting the title... //best we can do is utilize the Page Title from the Dynamic Page settings and set the <h1> on the module string title = module["DefaultTitle"] as string; if (dynamicItem != null) { title = dynamicItem["Title"] as string; } if (filterMonth != DateTime.MinValue) { if (!string.IsNullOrEmpty(title)) { title += ": "; } title += filterMonth.ToString("MMMM yyyy"); } #endregion #region --- Set ViewModel --- var model = new BlogListingViewModel(); model.Module = module; model.Posts = posts; model.Title = title; model.Configuration = blogConfig; model.CurrentCategory = categories.FirstOrDefault(); model.Pagination = pagination; #endregion return(PartialView(AgilityComponents.TemplatePath("Blog-ListingModule"), model)); }
public static string BlogDynamicUrl(this AgilityContentItem item, AgilityContentItem blogConfig, AgilityContentItem currentBlogCategory = null) { string url = ""; string nestedDynamicPageUrl = ""; if (item.IsBlogPost()) { /* * Determine if we have a current blog category (i.e. from category landing pages), use that to route the post * If no current blog category set, use canonical category as main url * If post has no category associated at all, use default post details route (without category) */ AgilityContentItem category = null; if (currentBlogCategory == null) { //use the canonical category (first category = canonical category) category = BlogUtils.GetItemsByIDs(item["Categories"], item["CategoriesIDs"]).FirstOrDefault(); } else { category = currentBlogCategory; } //no category set - use default route if (category == null) { url = BlogContext.GetDynamicDefaultBlogPostPath(blogConfig); } else { url = BlogContext.GetDynamicCategoryBlogPostPath(blogConfig, category); nestedDynamicPageUrl = BlogContext.GetDynamicCategoryBlogPostPath(blogConfig, category, true); } } if (item.IsBlogAuthor()) { url = BlogContext.GetDynamicBlogAuthorPath(blogConfig); } if (item.IsBlogCategory()) { url = BlogContext.GetDynamicBlogCategoryPath(blogConfig); } if (item.IsBlogTag()) { url = BlogContext.GetDynamicBlogTagPath(blogConfig); } if (string.IsNullOrEmpty(url)) { return(""); } DynamicPageItem d = Data.GetDynamicPageItem(url, item.ReferenceName, item.Row); //must get dynamic page using static paths (no nested dynamic names that have been already formulated) if (!string.IsNullOrEmpty(nestedDynamicPageUrl)) { url = nestedDynamicPageUrl; // do the string replacement using the dynamic formulized route } url = string.Format("{0}/{1}", url.Substring(0, url.LastIndexOf('/')), d.Name).ToLowerInvariant(); return(url); }
public CategoryController() { utils = new BlogUtils(Context); }
public ActionResult BlogDetails(AgilityContentItem module) { #region --- Get Blog Config and Repos --- var blogConfigRef = module["BlogConfiguration"] as string; AgilityContentItem blogConfig = null; IAgilityContentRepository <AgilityContentItem> blogPosts = null; IAgilityContentRepository <AgilityContentItem> blogCategories = null; IAgilityContentRepository <AgilityContentItem> blogTags = null; IAgilityContentRepository <AgilityContentItem> blogAuthors = null; BlogUtils.GetBlogConfig(blogConfigRef, out blogConfig, out blogPosts, out blogCategories, out blogTags, out blogAuthors); #endregion #region --- Resolve Dynamic Post and Category (if any) --- var post = ResolveBlogPostDetails(); if (post == null || !post.IsBlogPost()) { Agility.Web.Tracing.WebTrace.WriteErrorLine("Cannot resolve current dynamic item to a Blog Posts."); return(null); } var currentNode = SiteMap.CurrentNode; AgilityContentItem currentCategory = null; if (currentNode != null && currentNode.ParentNode != null) { currentCategory = AgilityContext.GetDynamicPageItem <AgilityContentItem>(currentNode.ParentNode); } //only set category if the parent dynamic item is a category if (currentCategory != null && !currentCategory.IsBlogCategory()) { currentCategory = null; } #endregion #region --- Get Related Posts --- int relatedPostsLimit; int.TryParse(string.Format("{0}", module["RelatedPostsLimit"]), out relatedPostsLimit); if (relatedPostsLimit < 0) { relatedPostsLimit = 0; } var relatedPosts = BlogUtils.GetRelatedPosts(post, blogPosts, true, relatedPostsLimit); #endregion #region --- Set SEO Properties --- string canonicalUrl = post.BlogDynamicUrl(blogConfig, currentCategory); AgilityContext.CanonicalLink = BlogUtils.GetAbsoluteUrl(canonicalUrl); //Enables image for twitter cards - but twitter cards need to be enabled ... //to enable twitter cards include setting in app settings in web.config AgilityContext.FeaturedImageUrl = BlogUtils.GetPostImageUrl(blogConfig, post, PostImageType.Details); if (string.IsNullOrEmpty(AgilityContext.Page.MetaTags)) { AgilityContext.Page.MetaTags = Server.HtmlEncode(BlogUtils.GetPostDescription(post, "Excerpt", 255, true)); } string websiteName = blogConfig["WebsiteName"] as string; if (string.IsNullOrEmpty(websiteName)) { websiteName = AgilityContext.WebsiteName; } AgilityContext.Page.MetaTagsRaw += string.Format( "{6}" + "<meta property='og:title' content='{0}' />" + "<meta property='og:type' content='{1}' />" + "<meta property='og:url' content='{2}' />" + "<meta property='og:image' content='{3}' />" + "<meta property='og:site_name' content='{4}' />" + "<meta property='og:description' content='{5}' />", Server.HtmlEncode(AgilityContext.Page.Title), "article", Request.Url.ToString(), BlogUtils.GetPostImageUrl(blogConfig, post, PostImageType.Details), websiteName, Server.HtmlEncode(AgilityContext.Page.MetaTags), Environment.NewLine ); #endregion #region --- Set ViewModel --- var model = new PostViewModel(); model.Configuration = blogConfig; model.Post = post; model.RelatedPosts = relatedPosts; model.CurrentCategory = currentCategory; model.Module = module; model.Categories = BlogUtils.GetItemsByIDs(blogCategories.ContentReferenceName, post["CategoriesIDs"]);; model.Tags = BlogUtils.GetItemsByIDs(blogTags.ContentReferenceName, post["BlogTagsIDs"]);; #endregion return(PartialView(AgilityComponents.TemplatePath("Blog-PostDetailsModule"), model)); }