Come rimuovere i duplicati delle meta tag title e description in BlogEngine.net
Ai fini di un buon posizionamento nei motori di ricerca, Google continua a dare molta importanza ai tag title e description.
La struttura dei Blog oggi è basata sulla visualizzazione dinamica di un elenco di contenuto rappresentato in ordine cronologico inverso.
L’elenco dei post, infatti, è consultabile sfogliando, attraverso i link di navigazione, la Home Page, la sezione Categorie, Tag e la lista dei Mesi, questo genera pagine diverse per contenuto ma aventi lo stesso titolo e descrizione con conseguente penalizzazione da parte di Google.
Per trovare una soluzione a questo problema occorre agire sul file default.aspx.cs di BlogEngine.Net, andando a modificare il codice e cercando di assegnare ad ogni pagina un titolo univoco e ad ogni sezione specifica, categoria,home,tag,ecc., una description di riferimento dalla lunghezza non breve, poichè Google segnala come errore anche le cosiddette meta descrizioni brevi.
Analizziamo il codice e vediamo le modifiche fatte.
Per quanto riguarda l’Home Page ho dovuto personalizzare il tag title in modo da attribuire a ciascuna pagina scelta nell’ambito del default.aspx un titolo univoco:
protected void Page_Load(object sender, EventArgs e) { bool DescriptionAdded = false; if (Page.IsCallback) return; BlogEngine.Core.Page frontPage = BlogEngine.Core.Page.GetFrontPage(); if (Request.QueryString.Count == 0 && frontPage != null) { Server.Transfer(Utils.RelativeWebRoot + "page.aspx?id=" + frontPage.Id); } else if (Request.RawUrl.ToLowerInvariant().Contains("/category/")) { DisplayCategories(); DescriptionAdded = true; } else if (Request.RawUrl.ToLowerInvariant().Contains("/author/")) { DisplayAuthors(); DescriptionAdded = true; } else if (Request.RawUrl.ToLowerInvariant().Contains("?tag=")) { DisplayTags(); DescriptionAdded = true; } else if (Request.QueryString["year"] != null || Request.QueryString["date"] != null || Request.QueryString["calendar"] != null) { if (Request.RawUrl.Contains("year=")) Redirect(); else DisplayDateRange(); } else if (Request.QueryString["apml"] != null) { DisplayApmlFiltering(); } else { PostList1.ContentBy = ServingContentBy.AllContent; PostList1.Posts = Post.Posts.ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); if (!BlogSettings.Instance.UseBlogNameInPageTitles) Page.Title = BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } } AddMetaKeywords(); if (!DescriptionAdded) base.AddMetaTag("description", Server.HtmlEncode(BlogSettings.Instance.Description)); base.AddMetaTag("author", Server.HtmlEncode(BlogSettings.Instance.AuthorName)); }
Per evitare duplicati di Title e Description sono intervenuto anche nelle sezioni Categorie, Tags, Autori e Data.
Ecco com’era il vecchio codice riguardante le Categorie:
private void DisplayCategories() { if (!String.IsNullOrEmpty(Request.QueryString["id"])) { Guid categoryId = new Guid(Request.QueryString["id"]); PostList1.ContentBy = ServingContentBy.Category; PostList1.Posts = Post.GetPostsByCategory(categoryId).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); Page.Title = Category.GetCategory(categoryId).Title;
Il nuovo codice, invece, ci permetterà con Base.AddMetaTag di personalizzare la description in base alla categoria scelta e con il Page.Title, in aggiunta al numero di pagina scelto, di personalizzare il title per ogni pagina che scorreremo. IN questo modo eviteremo duplicati per il tag title e qualche duplicato in meno per il tag description:
private void DisplayCategories() { if (!String.IsNullOrEmpty(Request.QueryString["id"])) { Guid categoryId = new Guid(Request.QueryString["id"]); PostList1.ContentBy = ServingContentBy.Category; PostList1.Posts = Post.GetPostsByCategory(categoryId).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); Page.Title = Category.GetCategory(categoryId).Title + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Dal Blog Informarea, un elenco degli articoli che appartengono alla categoria " + Category.GetCategory(categoryId) + ""); } }
Stessa cosa vale per il codice riguardante gli Autori, i Tags, e il mese e anno scelto:
private void DisplayAuthors() { if (!string.IsNullOrEmpty(Request.QueryString["name"])) { string author = Server.UrlDecode(Request.QueryString["name"]); PostList1.ContentBy = ServingContentBy.Author; PostList1.Posts = Post.GetPostsByAuthor(author).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); Page.Title = "Gli articoli di " + Request.QueryString["name"] + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Dal Blog Informarea, un elenco di tutti gli articoli scritti da " + Request.QueryString["name"]); } } private void DisplayTags() { if (!string.IsNullOrEmpty(Request.QueryString["tag"])) { PostList1.ContentBy = ServingContentBy.Tag; PostList1.Posts = Post.GetPostsByTag(Request.QueryString["tag"].Substring(1)).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); base.Title = " All posts tagged '" + Request.QueryString["tag"].Substring(1) + "'" + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Dal Blog di Informarea, un elenco di tutti gli articoli classificati con tag " + Request.QueryString["tag"].Substring(1) + ""); } } private void DisplayDateRange() { string year = Request.QueryString["year"]; string month = Request.QueryString["month"]; string specificDate = Request.QueryString["date"]; if (!string.IsNullOrEmpty(year) && !string.IsNullOrEmpty(month)) { DateTime dateFrom = DateTime.Parse(year + "-" + month + "-01", CultureInfo.InvariantCulture); DateTime dateTo = dateFrom.AddMonths(1).AddMilliseconds(-1); PostList1.ContentBy = ServingContentBy.DateRange; PostList1.Posts = Post.GetPostsByDate(dateFrom, dateTo).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); Page.Title = dateFrom.ToString("MMMM yyyy") + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Blog a carattere sociale con news dal web, aperto a tutti coloro che vogliono condividere un loro pensiero. " + Title + ""); } else if (!string.IsNullOrEmpty(year)) { DateTime dateFrom = DateTime.Parse(year + "-01-01", CultureInfo.InvariantCulture); DateTime dateTo = dateFrom.AddYears(1).AddMilliseconds(-1); PostList1.ContentBy = ServingContentBy.DateRange; PostList1.Posts = Post.GetPostsByDate(dateFrom, dateTo).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); ; Page.Title = dateFrom.ToString("yyyy") + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Blog a carattere sociale con news dal web, aperto a tutti coloro che vogliono condividere un loro pensiero. " + Title + ""); } else if (!string.IsNullOrEmpty(specificDate) && specificDate.Length == 10) { DateTime date = DateTime.Parse(specificDate, CultureInfo.InvariantCulture); PostList1.ContentBy = ServingContentBy.DateRange; PostList1.Posts = Post.GetPostsByDate(date, date).ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; })); ; Page.Title = date.ToString("MMMM d. yyyy") + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Blog a carattere sociale con news dal web, aperto a tutti coloro che vogliono condividere un loro pensiero. " + Title + ""); } else if (!string.IsNullOrEmpty(Request.QueryString["calendar"])) { calendar.Visible = true; PostList1.Visible = false; Page.Title = Server.HtmlEncode(Resources.labels.calendar) + " - " + BlogSettings.Instance.Name; if (Request.QueryString["page"] != "1" && Request.QueryString["page"] != null) { Page.Title += " - Pagina " + Request.QueryString["page"]; } base.AddMetaTag("description", "Blog a carattere sociale con news dal web, aperto a tutti coloro che vogliono condividere un loro pensiero. " + Title + ""); } } }
Queste modifiche al file default.aspx.cs vi permettono di avere titoli univoci per ciascuna pagina mentre per quanto riguarda la descrizione, avete l’univocità soltanto per le singole sezioni (Home,Categorie,Tags,Autori,Date).
Con qualche modifica in più è possibile personalizzare anche la description per ogni pagina facente parte delle sezioni indicate, ma con i suggerimenti proposti possiamo già ottenere quei miglioramenti che a Google farebbero sicuramente piacere.
Questo è il nuovo file zippato di default.aspx.cs (11.46 kb) da sostituire a quello che avete già nella root del vostro blog (fate sempre prima un backup del file esistente).
Attenzione perchè la soluzione proposta è stata testata con BlogEngine.net 2.5
Alla Prossima