Developer forum

Forum » CMS - Standard features » Issue with Sitemap.xml

Issue with Sitemap.xml

Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi,

 

We are experiencing some issues with sitemap.xml and we tracked it down to the Ecom Navigation setting on a page. More and more we have situations where the Product list page is not the page PageId as the Product detail page. Example:

 

This all works apparently fine, and despite some headscratching developing the templates, I realized what DW was doing when the customer started enforcing SEO requirements.

 

Setting up the Ecommerce navigation settings we set up the Product Page, interpreting it would affect only links to Product detail page. What this actually does is affect all links, which makes it nor render the sitemap.xml correctly.

  • If I leave it blank OR point to itself, all product list and product detail pages point to "models"
  • If I set it to "product" page, the product list pages point to "product"

 

Here's a repro https://www.screencast.com/t/M1k4cSg0

 

Can this be fixed (assuming my interpretation of the UI is accurate and it's a bug)? Is there a workaround I can use to keep the customer happy?

 

Best Regards,

Nuno Aguiar

EcomNavigationSettings.gif

Replies

 
Nicolai Pedersen
Reply

No, it cannot.

I have provided you guys with a custom sitemaps.xml template where you can hard code all your alternative implementations as you see fit and need. This is a never ending story of changing what comes out, and we have no chance of supporting what you and all other partners think is correct. Go custom - it is much easier for you.

BR Nicolai

The custom sitemapxml.cshtml template.

Setup a page using this template, hide it in navigation and set the response type to xml.

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
@using System;
@using System.Web;
@using System.Collections.Generic;
@using System.Linq;
@using Dynamicweb.Ecommerce.Products;
@using Dynamicweb.Frontend.Navigation;

@{
    string hostname = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
    var navigationSettingsMain = new Dynamicweb.Frontend.Navigation.NavigationSettings()
    {
        StartLevel = 1,
        StopLevel = 10,
        ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All
    };

    NavigationTreeViewModel navigation = GetNavigation(navigationSettingsMain);

}
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

    @RenderNodes(navigation.Nodes, hostname)

</urlset>

@helper RenderNodes(IEnumerable<NavigationTreeNodeViewModel> nodes, string hostname)
{
    foreach (NavigationTreeNodeViewModel node in nodes)
    {
        @RenderNode(node, hostname)

    }
}

@helper RenderNode(NavigationTreeNodeViewModel node, string hostname)
{
    var page = Dynamicweb.Services.Pages.GetPage(node.PageId);

    bool isEcommerceNavigation = false;
    string navsettings = string.Empty;
    if (page.NavigationSettings != null && page.NavigationSettings.UseEcomGroups)
    {
        isEcommerceNavigation = true;
        navsettings = page.NavigationSettings.Groups;
    }

    if (isEcommerceNavigation)
    {
        if (page.Allowclick && page.ShowInSitemap && !page.Noindex)
        {
            <url>
                <loc pageid="@node.PageId" groups="@navsettings">@hostname@node.Link</loc>
                <lastmod>@page.Audit.LastModifiedAt.ToString("s")</lastmod>
            </url>
            @RenderEcommerceGroupNodes(GetGroupsBySettings(page.NavigationSettings), node, hostname)
        }
    }
    else
    {
        if (page.Allowclick && page.ShowInSitemap && !page.Noindex)
        {
            <url>
                <loc>@hostname@node.Link</loc>
                <lastmod>@page.Audit.LastModifiedAt.ToString("s")</lastmod>
            </url>
        }
        if (node.Nodes.Any())
        {
            @RenderNodes(node.Nodes, hostname)
        }
    }
}

@helper RenderEcommerceGroupNodes(IEnumerable<Dynamicweb.Ecommerce.Products.Group> groups, NavigationTreeNodeViewModel node, string hostname)
{
    foreach (Group group in groups)
    {

        if (group.NavigationClickable && group.NavigationShowInSiteMap)
        {
            //Remember to check if this group is not having another primary page
            //Remember to check if this group does not have multiple parents - and if it has, decide if the group should be shown here
            //int primarypageid = group.Meta.PrimaryPageId; //Use this if needed - send it into the product
            string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?ID=" + node.PageId + "&GroupID=" + group.IdUrlEncoded);
            
            <url>
                <loc pageid="@node.PageId" groupid="@group.Id" group="@group.Name">@hostname@url</loc>
            </url>
        }
        @RenderEcommerceProductNodes(Dynamicweb.Ecommerce.Services.Products.GetProductsByGroupId(group.Id, true, group.LanguageId, false), node, hostname, group)
        @RenderEcommerceGroupNodes(group.Subgroups, node, hostname)

    }
}

@helper RenderEcommerceProductNodes(IEnumerable<Dynamicweb.Ecommerce.Products.Product> products, NavigationTreeNodeViewModel node, string hostname, Group group)
{
    //Locate the right pageid. This group is shown on a page that might link to another page to show product detail. So on this page, find the paragraph, lookup the setting, change pageid to the detail page.
    //The product might be in 2 groups - ensure this is the primary or default group of the product - if not, do not render
    foreach (Product product in products)
    {
        string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?ID=" + node.PageId + "&GroupID=" + group.IdUrlEncoded + "&ProductID=" + product.Id);
        <url>
            <loc pageid="@node.PageId" groupid="@group.Id" group="@group.Name" productid="@product.Id" product="@product.Name" variantid="@product.VariantId">@hostname@url</loc>
        </url>
    }
}

@functions{

    public IEnumerable<Dynamicweb.Ecommerce.Products.Group> GetGroupsBySettings(Dynamicweb.Content.PageNavigationSettings ecomSettings)
    {
        IEnumerable<Dynamicweb.Ecommerce.Products.Group> topLevelGroups;

        string languageId = Dynamicweb.Ecommerce.Common.Context.LanguageID;
        switch (ecomSettings.ParentType)
        {
            case Dynamicweb.Content.EcommerceNavigationParentType.Groups:
                {
                    Dynamicweb.Ecommerce.Extensibility.Controls.ProductsAndGroupsHandler groupHandler = new Dynamicweb.Ecommerce.Extensibility.Controls.ProductsAndGroupsHandler(ecomSettings.Groups);
                    if (groupHandler.Type == Dynamicweb.Ecommerce.Extensibility.Controls.HandlerConfigurationType.All)
                    {
                        Dynamicweb.Ecommerce.Shops.Shop shop = Dynamicweb.Ecommerce.Services.Shops.GetShop(string.IsNullOrEmpty(groupHandler.ShopSelected) ? ecomSettings.ShopID : groupHandler.ShopSelected);
                        if (shop == null)
                            topLevelGroups = Enumerable.Empty<Dynamicweb.Ecommerce.Products.Group>();
                        else
                            topLevelGroups = shop.get_TopLevelGroups(languageId);
                    }
                    else
                        topLevelGroups = groupHandler.GroupsSelected;
                    break;
                }

            case Dynamicweb.Content.EcommerceNavigationParentType.Shop:
                {
                    Dynamicweb.Ecommerce.Shops.Shop shop = Dynamicweb.Ecommerce.Services.Shops.GetShop(ecomSettings.ShopID);
                    if (shop == null)
                        topLevelGroups = Enumerable.Empty<Dynamicweb.Ecommerce.Products.Group>();
                    else
                        topLevelGroups = shop.get_TopLevelGroups(languageId);
                    break;
                }

            default:
                {
                    topLevelGroups = Enumerable.Empty<Dynamicweb.Ecommerce.Products.Group>();
                    break;
                }
        }

        return topLevelGroups;
    }

}
 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Nicolai,

 

Thank you. I hand't thought of this approach (I guess I need some vacations :p )

 

Best Regards,

Nuno Aguiar

 
Nicolai Pedersen
Reply

I am also working on a version that runs on top of the new url index and the new providers. It will not iterate pages and groups, but the urls. That will be opt in and is a totally different approach. Might work better in some cases, but probably not all.

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Nicolai,

 

That sounds promising. Looking forward to seeing it. SEO "settings" are always an issue with enterprise customers when we deviate from Dynamicweb's happy path. Having one less thing to worry about (as little as it is on the big picture of an All-in-One platform) is great getting these types of customers.

 

Thanks for the update

Nuno Aguiar

 

You must be logged in to post in the forum