In this post we will talk about the code in details according Advanced Sitecore SiteMap module, I will explain the main areas and at the end I will include links to Github repository contains the latest code.
The main code areas contains the following:
- Generate SiteMap main function.
- Send SiteMap to search engine.
- Add SiteMap file name to Robots.txt
- Sitecore command and SiteMap manual Generation.
- HTML SiteMap builder function.
A. Generate SiteMap
main function
As you can see from the
following the code will loop through the sites already defined under the
related configuration item and for each site the code will get the start item
for each site, then the code will retrieve the available defined languages under
sitecore and loop through them and for each decedents item if it is allowed to
be included in sitemap by validating the field "Show In Xml SiteMap "
the code will read the SiteMap fields section and create the related xml tags; Finally
the xml file will be saved into the root folder with the name exists under related
configuration item.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void GenerateSiteMap() | |
{ | |
try | |
{ | |
SiteMapConfig siteMapConfig = new SiteMapConfig(); | |
if (siteMapConfig.definedSites == null || !siteMapConfig.definedSites.Any()) | |
return; | |
if (siteMapConfig.targetDatabaseName == string.Empty) | |
return; | |
foreach (var site in siteMapConfig.definedSites) | |
{ | |
if (site.Fields[SiteItemFields.SiteName] == null || string.IsNullOrEmpty(site.Fields[SiteItemFields.SiteName].Value)) | |
continue; | |
Sitecore.Sites.SiteContext _site = Factory.GetSite(site.Fields[SiteItemFields.SiteName].Value); | |
if (_site == null) | |
continue; | |
Item _root = GetTargetDatabase().GetItem(_site.StartPath); | |
if (_root == null) | |
continue; | |
StringBuilder sbSiteMap = new StringBuilder(); | |
sbSiteMap.Append("<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd'>"); | |
List<Item> siteMapItems = _root.Axes.GetDescendants().Where(P => P.Fields["Show In XML SiteMap"].Value == "1").ToList(); | |
if (siteMapItems != null && siteMapItems.Any()) | |
{ | |
if (_root.Fields["Show In XML SiteMap"].Value == "1") | |
siteMapItems.Add(_root); | |
var options = global::Sitecore.Links.LinkManager.GetDefaultUrlOptions(); | |
options.AlwaysIncludeServerUrl = true; | |
options.LanguageEmbedding = LanguageEmbedding.Always; | |
options.Site = SiteContext.GetSite(site.Name); | |
options.SiteResolving = true; | |
// get langauges | |
List<Language> _availbleLangauges = null; | |
if (siteMapConfig.multilingualSiteMapXML) | |
{ | |
Item _languagesRoot = GetTargetDatabase().GetItem(Guids.Items.LangaugesRootItem); | |
_availbleLangauges = _languagesRoot.Axes.GetDescendants().Where(P => P.Fields["Iso"].Value != string.Empty).Select(P => Language.Parse(P.Fields["Iso"].Value)).ToList(); | |
} | |
else | |
{ | |
_availbleLangauges = new List<Language>() { Language.Parse("en") }; | |
} | |
XmlDocument doc = new XmlDocument(); | |
foreach (var langauge in _availbleLangauges) | |
{ | |
options.Language = langauge; | |
options.EmbedLanguage(langauge); | |
foreach (var item in siteMapItems) | |
{ | |
string url = LinkManager.GetItemUrl(item, options); | |
string hostName = _site.HostName; | |
url = hostName + "//" + url; | |
if (!url.Contains("http://")) | |
{ | |
if (site.Fields[SiteItemFields.ServerURL] != null && | |
!string.IsNullOrEmpty(site.Fields[SiteItemFields.ServerURL].Value)) | |
{ | |
url = site.Fields[SiteItemFields.ServerURL].Value + "//" + url; | |
} | |
else | |
{ | |
url = "http://" + url; | |
} | |
} | |
string lastUpdated = DateUtil.IsoDateToDateTime(item.Fields[Sitecore.FieldIDs.Updated].Value).ToString("yyyy-MM-ddTHH:mm:sszzz"); | |
string FrequencyChange = "yearly"; | |
if (item.Fields[SiteMapFields.FrequencyChange] != null) | |
{ | |
if (!string.IsNullOrEmpty(item.Fields[SiteMapFields.FrequencyChange].Value)) | |
{ | |
Item _FrequencyChange = GetTargetDatabase().GetItem(item.Fields[SiteMapFields.FrequencyChange].Value); | |
if (_FrequencyChange != null) | |
FrequencyChange = _FrequencyChange.Name; | |
} | |
} | |
string Priority = "0.0"; | |
if (item.Fields[SiteMapFields.Priority] != null) | |
{ | |
if (!string.IsNullOrEmpty(item.Fields[SiteMapFields.Priority].Value)) | |
{ | |
Item _priority = GetTargetDatabase().GetItem(item.Fields[SiteMapFields.Priority].Value); | |
if (_priority != null && _priority.Fields["Value"] != null && !string.IsNullOrEmpty(_priority.Fields["Value"].Value)) | |
Priority = _priority.Fields["Value"].Value; | |
} | |
} | |
sbSiteMap.Append("<url>"); | |
sbSiteMap.Append("<loc>"); | |
sbSiteMap.Append(url); | |
sbSiteMap.Append("</loc>"); | |
sbSiteMap.Append("<lastmod>"); | |
sbSiteMap.Append(lastUpdated); | |
sbSiteMap.Append("</lastmod>"); | |
sbSiteMap.Append("<changefreq>"); | |
sbSiteMap.Append(FrequencyChange); | |
sbSiteMap.Append("</changefreq>"); | |
sbSiteMap.Append("<priority>"); | |
sbSiteMap.Append(Priority); | |
sbSiteMap.Append("</priority>"); | |
sbSiteMap.Append("</url>"); | |
} | |
} | |
sbSiteMap.Append("</urlset>"); | |
string fileName = "SiteMap.xml"; | |
if (site.Fields[SiteItemFields.SitemMapXMLFilename] != null && | |
!string.IsNullOrEmpty(site.Fields[SiteItemFields.SitemMapXMLFilename].Value)) | |
fileName = site.Fields[SiteItemFields.SitemMapXMLFilename].Value; | |
doc.LoadXml(sbSiteMap.ToString()); | |
string xmlFilePath = MainUtil.MapPath("/" + fileName); | |
doc.Save(xmlFilePath); | |
if (site.Fields[SiteItemFields.AddToRobotFile] != null) | |
{ | |
Sitecore.Data.Fields.CheckboxField _AddToRobotFile = site.Fields[SiteItemFields.AddToRobotFile]; | |
if (_AddToRobotFile != null) | |
{ | |
if (_AddToRobotFile.Checked) | |
AddSitemapToRobots(fileName); | |
} | |
} | |
Sitecore.Web.UI.Sheer.SheerResponse.Alert("SiteMap has been generated successfully"); | |
} | |
} | |
} | |
catch (Exception exception) | |
{ | |
Log.Error(exception.Message, "SiteMapBuilder - GenerateSiteMap method"); | |
} | |
} |
B. Send SiteMap to
Search Engine
If you enabled sending
the generated SiteMap xml file to search
engines and you defined search engines under the related configuration item the
following code will loop through the defined search engines and loop through defined
sites and send the xml into these search engines.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void SendSiteMapTOSearchEngines() | |
{ | |
try | |
{ | |
SiteMapConfig siteMapConfig = new SiteMapConfig(); | |
if (siteMapConfig.enabledSearchEngines == null) | |
return; | |
if (!siteMapConfig.enabledSearchEngines.Any()) | |
return; | |
if (siteMapConfig.definedSites == null) | |
return; | |
if (!siteMapConfig.definedSites.Any()) | |
return; | |
foreach (var engine in siteMapConfig.enabledSearchEngines) | |
{ | |
foreach (var site in siteMapConfig.definedSites) | |
{ | |
string SearchEngineRequstUrl = engine.Fields[SiteMapSearchEngineFields.SearchEngineRequestUrl].Value; | |
string siteMapUrl = HttpUtility.HtmlEncode(site.Fields[SiteItemFields.ServerURL].Value + "/" + site.Fields[SiteItemFields.SitemMapXMLFilename].Value); | |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(SearchEngineRequstUrl + siteMapUrl); | |
try | |
{ | |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |
if (response.StatusCode != HttpStatusCode.OK) | |
{ | |
throw new Exception("Submit SsiteMap error. Engine name is : " + engine.Name); | |
} | |
} | |
catch | |
{ | |
throw new Exception("404 error. Engine name is : " + engine.Name); | |
} | |
} | |
} | |
} | |
catch (Exception exception) | |
{ | |
Log.Error(exception.Message, "SiteMapBuilder - SendSiteMapTOSearchEngines"); | |
} | |
} |
C. Add SiteMap file
name to Robots.txt
The following code simply
read the Robots.txt file and add the SiteMap xml path into that file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void AddSitemapToRobots(string xmlFileName) | |
{ | |
try | |
{ | |
string _RobotsFilePath = MainUtil.MapPath("/" + "robots.txt"); | |
StringBuilder sbRobots = new StringBuilder(string.Empty); | |
if (File.Exists(_RobotsFilePath)) | |
{ | |
StreamReader reader = new StreamReader(_RobotsFilePath); | |
sbRobots.Append(reader.ReadToEnd()); | |
reader.Close(); | |
} | |
StreamWriter writer = new StreamWriter(_RobotsFilePath, false); | |
string _stringToAppend = "Sitemap: " + xmlFileName; | |
if (!sbRobots.ToString().Contains(_stringToAppend)) | |
{ | |
sbRobots.AppendLine(_stringToAppend); | |
} | |
writer.Write(sbRobots.ToString()); | |
writer.Close(); | |
} | |
catch (Exception ex) | |
{ | |
Log.Error(ex.Message, "SiteMapBuilder - AddSitemapToRobots method"); | |
} | |
} |
D. Sitecore command
and SiteMap manual Generation.
In this section I explain how the
manual generation of SiteMap will be done. and to implanted I did two things:
1.
Adding related
configuration into sitecore commands.config
And to this I just create
new configuration file called "Sitecore.AdvancedSiteMap.Commands.GenerateSiteMap.config"
and the following is the content of this file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<sitecore>
<commands>
<command name="contenteditor:GenerateSiteMap" type="Sitecore.AdvancedSiteMap.ManualSiteMapGeneration,
Sitecore.AdvancedSiteMap"/>
</commands>
</sitecore>
</configuration>
|
2.
Creating the command class
"ManualSiteMapGeneration.cs"
It is simple class the inherits
" Sitecore.Shell.Framework.Commands.command" and has the following
code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Serializable] | |
public class ManualSiteMapGeneration : Command | |
{ | |
public override void Execute(CommandContext context) | |
{ | |
Sitecore.Context.ClientPage.Start(this, "Run", context.Parameters); | |
} | |
protected static void Run(ClientPipelineArgs args) | |
{ | |
var SyunObj = new SiteMapBuilder(); | |
SyunObj.BuildSiteMap(); | |
} | |
} |
E. HTML SiteMap
builder function.
In the following code you
will see how HTML SiteMap is being generated using Sitecore advanced SiteMap module
At the end I believe I just provide a detailed description of all Sitecore Advanced SiteMap module, Also you download the code on the following link:
Sitecore Advanced SiteMap Module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protected void Page_Load(object sender, EventArgs e) | |
{ | |
AdvancedSiteMap.HTMLSiteMapBuilder hTMLSiteMapBuilder = new AdvancedSiteMap.HTMLSiteMapBuilder(); | |
liSiteMap.Text = hTMLSiteMapBuilder.BuildSitemapHTML(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HTMLSiteMapBuilder | |
{ | |
static SiteMapConfig siteMapConfig = new SiteMapConfig(); | |
StringBuilder sbSiteMapHTML = new StringBuilder(); | |
private Database GetTargetDatabase() | |
{ | |
return Factory.GetDatabase(siteMapConfig.targetDatabaseName); | |
} | |
public string BuildSitemapHTML() | |
{ | |
Item _currentItem = Sitecore.Context.Item; | |
if (_currentItem == null) | |
return string.Empty; | |
Item _root = _currentItem.Parent; | |
if (_root == null) | |
return string.Empty; | |
string displayText = string.Empty; | |
if (_root.Fields[SiteMapFields.HTMLSiteMapTitle] != null) | |
displayText = _root.Fields[SiteMapFields.HTMLSiteMapTitle].Value; | |
if (displayText == string.Empty && _root.Name != null) | |
displayText = _root.Name; | |
var options = global::Sitecore.Links.LinkManager.GetDefaultUrlOptions(); | |
options.AlwaysIncludeServerUrl = true; | |
options.LanguageEmbedding = LanguageEmbedding.Always; | |
options.Language = Sitecore.Context.Language; | |
options.EmbedLanguage(Sitecore.Context.Language); | |
string itemURL = Sitecore.Links.LinkManager.GetItemUrl(_root, options); | |
bool ShowInHTMLSiteMap = false; | |
CheckboxField _ShowInHTMLSiteMap = _root.Fields[SiteMapFields.ShowInHTMLSiteMap]; | |
if (_ShowInHTMLSiteMap != null) | |
ShowInHTMLSiteMap = _ShowInHTMLSiteMap.Checked; | |
if (ShowInHTMLSiteMap) | |
{ | |
sbSiteMapHTML.Append("<ul>"); | |
sbSiteMapHTML.Append("<li>"); | |
sbSiteMapHTML.Append("<a href='" + itemURL + "'>"); | |
sbSiteMapHTML.Append(displayText); | |
sbSiteMapHTML.Append("</a>"); | |
sbSiteMapHTML.Append("</li>"); | |
RecursiveChildBuilder(_root); | |
sbSiteMapHTML.Append("</ul>"); | |
} | |
else | |
{ | |
RecursiveChildBuilder(_root); | |
} | |
return sbSiteMapHTML.ToString(); | |
} | |
private void RecursiveChildBuilder(Item Root) | |
{ | |
if (Root == null) | |
return; | |
Item _currentLoopItem = Root; | |
if (_currentLoopItem == null) | |
return; | |
var options = global::Sitecore.Links.LinkManager.GetDefaultUrlOptions(); | |
options.AlwaysIncludeServerUrl = true; | |
options.LanguageEmbedding = LanguageEmbedding.Always; | |
options.Language = Sitecore.Context.Language; | |
options.EmbedLanguage(Sitecore.Context.Language); | |
List<Item> children = _currentLoopItem.Children.Where(x => x.Name != "*").ToList(); | |
if (children != null && children.Any()) | |
{ | |
sbSiteMapHTML.Append("<ul>"); | |
foreach (var child in children) | |
{ | |
string displayText = string.Empty; | |
if (child.Fields[SiteMapFields.HTMLSiteMapTitle] != null) | |
displayText = child.Fields[SiteMapFields.HTMLSiteMapTitle].Value; | |
if (displayText == string.Empty && child.Name != null) | |
displayText = child.Name; | |
string itemURL = Sitecore.Links.LinkManager.GetItemUrl(child, options); | |
bool ShowInHTMLSiteMap = false; | |
CheckboxField _ShowInHTMLSiteMap = child.Fields[SiteMapFields.ShowInHTMLSiteMap]; | |
if (_ShowInHTMLSiteMap != null) | |
ShowInHTMLSiteMap = _ShowInHTMLSiteMap.Checked; | |
if (ShowInHTMLSiteMap) | |
{ | |
sbSiteMapHTML.Append("<li>"); | |
sbSiteMapHTML.Append("<a href='" + itemURL + "'>"); | |
sbSiteMapHTML.Append(displayText); | |
sbSiteMapHTML.Append("</a>"); | |
sbSiteMapHTML.Append("</li>"); | |
} | |
if (child.HasChildren) | |
RecursiveChildBuilder(child); | |
} | |
sbSiteMapHTML.Append("</ul>"); | |
} | |
} |
At the end I believe I just provide a detailed description of all Sitecore Advanced SiteMap module, Also you download the code on the following link:
Sitecore Advanced SiteMap Module
No comments:
Post a Comment