Try your search with a different keyword or use * as a wildcard.
using System.Net;
using Microsoft.AspNetCore.Http;
using Nop.Core.Domain.Localization;
using Nop.Core.Infrastructure;
namespace Nop.Services.Localization;
/// <summary>
/// Represents extensions for localized URLs
/// </summary>
public static class LocalizedUrlExtensions
{
private static readonly char[] _separator = ['/', '?'];
/// <summary>
/// Get a value indicating whether URL is localized (contains SEO code)
/// </summary>
/// <param name="url">URL</param>
/// <param name="pathBase">Application path base</param>
/// <param name="isRawPath">A value indicating whether passed URL is raw URL</param>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains true if passed URL contains SEO code; otherwise false. Language whose SEO code is in the URL if URL is localized
/// </returns>
public static async Task<(bool IsLocalized, Language Language)> IsLocalizedUrlAsync(this string url, PathString pathBase, bool isRawPath)
{
if (string.IsNullOrEmpty(url))
return (false, null);
//remove application path from raw URL
if (isRawPath)
url = url.RemoveApplicationPathFromRawUrl(pathBase);
//get first segment of passed URL
var firstSegment = url.Split(_separator, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? string.Empty;
if (string.IsNullOrEmpty(firstSegment))
return (false, null);
//suppose that the first segment is the language code and try to get language
var languageService = EngineContext.Current.Resolve<ILanguageService>();
var language = (await languageService.GetAllLanguagesAsync())
.FirstOrDefault(urlLanguage => urlLanguage.UniqueSeoCode.Equals(firstSegment, StringComparison.InvariantCultureIgnoreCase));
//if language exists and published passed URL is localized
return (language?.Published ?? false, language);
}
/// <summary>
/// Remove application path from raw URL
/// </summary>
/// <param name="rawUrl">Raw URL</param>
/// <param name="pathBase">Application path base</param>
/// <returns>Result</returns>
public static string RemoveApplicationPathFromRawUrl(this string rawUrl, PathString pathBase)
{
new PathString(rawUrl).StartsWithSegments(pathBase, out var result);
return WebUtility.UrlDecode(result);
}
/// <summary>
/// Remove language SEO code from URL
/// </summary>
/// <param name="url">Raw URL</param>
/// <param name="pathBase">Application path base</param>
/// <param name="isRawPath">A value indicating whether passed URL is raw URL</param>
/// <returns>URL without language SEO code</returns>
public static string RemoveLanguageSeoCodeFromUrl(this string url, PathString pathBase, bool isRawPath)
{
if (string.IsNullOrEmpty(url))
return url;
//remove application path from raw URL
if (isRawPath)
url = url.RemoveApplicationPathFromRawUrl(pathBase);
//get result URL
url = url.TrimStart('/');
var result = url.Contains('/') ? url[(url.IndexOf('/'))..] : string.Empty;
//and add back application path to raw URL
if (isRawPath)
result = pathBase + result;
return result;
}
/// <summary>
/// Add language SEO code to URL
/// </summary>
/// <param name="url">Raw URL</param>
/// <param name="pathBase">Application path base</param>
/// <param name="isRawPath">A value indicating whether passed URL is raw URL</param>
/// <param name="language">Language</param>
/// <returns>Result</returns>
public static string AddLanguageSeoCodeToUrl(this string url, PathString pathBase, bool isRawPath, Language language)
{
ArgumentNullException.ThrowIfNull(language);
//null validation is not required
//if (string.IsNullOrEmpty(url))
// return url;
//remove application path from raw URL
if (isRawPath && !string.IsNullOrEmpty(url))
url = url.RemoveApplicationPathFromRawUrl(pathBase);
//add language code
url = $"/{language.UniqueSeoCode}{url}";
//and add back application path to raw URL
if (isRawPath)
url = pathBase + url;
return url;
}
}