Geta / SEO.Sitemaps

Search engine sitemaps.xml for EPiServer CMS
Apache License 2.0
28 stars 42 forks source link

Incorrect URL's on host without language specified #194

Open Eric-4NG opened 6 months ago

Eric-4NG commented 6 months ago

Hi there,

Currently I'm looking into an issue but I do not get any progress on it. We are having a site where by the hostname does not specify a culture. So there is a homepage in the NL language. And a subpage in the NL language.

When clicking through edit mode in the CMS this subpage will be shown as below after navigating using "View on Website":

[HOST]/nl/dit-is-een-nederlandse-pagina

When generating the sitemap the url will be included as:

[HOST]/dit-is-een-nederlandse-pagina

So somehow the "nl/" part is lost, per debugging / viewing source in this repository I did not find any reason for this. Anyone else experienced this before?

https://github.com/Geta/SEO.Sitemaps/blob/master/README.md#enabling-multi-language-support Following those steps doesn't help either.

Used packages: Geta.SEO.Sitemaps 4.0.1 Geta.SEO.Sitemaps.Commerce 4.0.1 EPiServer.CMS.Core 11.20.14 EPiServer.CMS.UI.Core 11.37.1 EPiServer.Commerce.Core 13.32.2

image

Eric-4NG commented 6 months ago

Work around using code. Not really nice, but it seems to work for this case. If anyone is aware of a better solution, feel free to reply :wink:

[ModuleDependency(typeof(SitemapInitialization))]
public class CustomSitemapInitialization : IConfigurableModule
{
    public void Initialize(InitializationEngine context)
    {
        //Intentionally left empty.
    }

    public void Uninitialize(InitializationEngine context)
    {
        //Intentionally left empty.
    }

    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.Services.RemoveAll<IStandardSitemapXmlGenerator>();
        context.Services.AddTransient<IStandardSitemapXmlGenerator, CustomSitemapXmlGenerator>();
    }
}

public class CustomSitemapXmlGenerator : SitemapXmlGenerator, IStandardSitemapXmlGenerator
{
    private const string LanguageCode = "nl";

    public CustomSitemapXmlGenerator(ISitemapRepository sitemapRepository, IContentRepository contentRepository, IUrlResolver urlResolver, ISiteDefinitionRepository siteDefinitionRepository, ILanguageBranchRepository languageBranchRepository, IContentFilter contentFilter) : base(sitemapRepository, contentRepository, urlResolver, siteDefinitionRepository, languageBranchRepository, contentFilter)
    {
        //Intentionally left empty.
    }

    protected override XElement GenerateSiteElement(IContent contentData, string url)
    {
        var baseElement = base.GenerateSiteElement(contentData, url);

        //We are having issues with the /nl part for business.domain.nl. So now we will try to fix that.
        if (baseElement != null
            && IsBusinessUrl(url)
            && contentData is ILocalizable localizedContent
            && LanguageCode.Equals(localizedContent.Language.Name, StringComparison.OrdinalIgnoreCase))
        {
            var locationNode = baseElement
                .Nodes()
                .Where(x => x.NodeType == XmlNodeType.Element)
                .Cast<XElement>()
                .FirstOrDefault(x => x.Name == base.SitemapXmlNamespace + "loc");

            if (locationNode != null
                && Uri.TryCreate(locationNode.Value, UriKind.Absolute, out Uri uriResult)
                && !uriResult.LocalPath.StartsWith(LanguageCode, StringComparison.OrdinalIgnoreCase))
            {
                var builder = new UriBuilder(uriResult);
                builder.Path = $"/{LanguageCode}{builder.Path}";

                locationNode.Value = builder.ToString();
            }
        }

        return baseElement;
    }

    private bool IsBusinessUrl(string url)
    {
        if (string.IsNullOrEmpty(url))
            return false;

        return new Regex("^https?://(business:52426|(int-|prep-)?business.domain.nl)/.*$").IsMatch(url);
    }
}