Пример #1
0
        // TODO: (core) Apply IDisplayedEntity to BlogPostTag

        public static string BuildSlug <T>(this T entity, int?languageId = null)
            where T : IDisplayedEntity
        {
            Guard.NotNull(entity, nameof(entity));

            var name = entity.GetDisplayName();

            if (entity is ILocalizedEntity le)
            {
                name = le.GetLocalized(entity.GetDisplayNameMemberName(), name, languageId);
            }

            return(SeoHelper.BuildSlug(name));
        }
Пример #2
0
        public virtual async ValueTask <ValidateSlugResult> ValidateSlugAsync <T>(T entity,
                                                                                  string seName,
                                                                                  bool ensureNotEmpty,
                                                                                  int?languageId = null)
            where T : ISlugSupported
        {
            Guard.NotNull(entity, nameof(entity));

            var displayName = entity.GetDisplayName();
            var entityName  = entity.GetEntityName();

            // Use entity DisplayName if seName is not specified
            if (string.IsNullOrWhiteSpace(seName) && !string.IsNullOrWhiteSpace(displayName))
            {
                seName = displayName;
            }

            // Validation
            var slug = SeoHelper.BuildSlug(seName,
                                           _seoSettings.ConvertNonWesternChars,
                                           _seoSettings.AllowUnicodeCharsInUrls,
                                           true,
                                           _seoSettings.SeoNameCharConversion);

            if (string.IsNullOrWhiteSpace(slug))
            {
                if (ensureNotEmpty)
                {
                    // Use entity identifier as slug if empty
                    slug = entityName.ToLower() + entity.Id.ToStringInvariant();
                }
                else
                {
                    // Return. no need for further processing
                    return(new ValidateSlugResult
                    {
                        Source = entity,
                        Slug = slug,
                        LanguageId = languageId,
                        WasValidated = true
                    });
                }
            }

            // Validate and alter slug if it could be interpreted as SEO code
            if (CultureHelper.IsValidCultureCode(slug))
            {
                if (seName.Length == 2)
                {
                    slug += "-0";
                }
            }

            // Ensure this slug is not reserved
            int       i           = 2;
            string    tempSlug    = slug;
            UrlRecord found       = null;
            bool      foundIsSelf = false;

            while (true)
            {
                // Check whether such slug already exists in the database
                var urlRecord = _extraSlugLookup.Get(tempSlug) ?? (await _db.UrlRecords.FirstOrDefaultAsync(x => x.Slug == tempSlug));

                // Check whether found record refers to requested entity
                foundIsSelf = FoundRecordIsSelf(entity, urlRecord, languageId);

                // ...and it's not in the list of reserved slugs
                var reserved = _seoSettings.ReservedUrlRecordSlugs.Contains(tempSlug);

                if ((urlRecord == null || foundIsSelf) && !reserved)
                {
                    found = urlRecord;
                    break;
                }

                // Try again with unique index appended
                var suffixLen = Math.Floor(Math.Log10(i) + 1).Convert <int>() + 1;
                tempSlug = string.Format("{0}-{1}", slug.Truncate(400 - suffixLen), i);
                found    = urlRecord;
                i++;
            }
            slug = tempSlug;

            return(new ValidateSlugResult
            {
                Source = entity,
                Slug = slug,
                Found = found,
                FoundIsSelf = foundIsSelf,
                LanguageId = languageId,
                WasValidated = true
            });
        }