U4-4650 - Pluralization of document type aliases doesn't always work

Created by Douglas Robar 09 Apr 2014, 11:06:30 Updated by Douglas Robar 16 May 2014, 12:43:16

Seen in 7.0.4 and 7.1.0

@CurrentPage.Children.Where("nodeTypeAlias = "promoRepository"") can be shortened using the pluralization syntax to @CurrentPage.PromoRepositories. This works perfectly.

However, if the document type alias were PromoRepositorys (note the final 's') the plural form of @CurrentPage.PromoRepositoryses won't work and returns nothing, though it should according to the 4 rules of pluralization:

Words ending in S become sES Words ending in H become hES Words ending in Y become IES All others have an S appended to the original word.

I can't find a pluralization that works in this case.

Comments

Douglas Robar 16 May 2014, 11:24:09

Aha, found the problem!

MakePluralName() never pluralizes words that end with a single 's'. Which means there is a case in which an alias cannot be pluralized.

The rules taken from SqlMetal make decent, if simplified, sense for English prose. For instance, words ending in 'ss' such as CLASS are appended with 'es' because. But words that end with a single 's' such as NEWS are never pluralized, probably under the assumption that words ending with 's' are already plural. Which is fine in English prose but not appropriate for a computer convention of using pluralized docType aliases in code.

The plural of any word ending in 's' should be to append 'es'. Thus, even though it isn't grammatically correct, the plural of NEWS should be NEWSES because there must be a way to use the plural in Umbraco.

The updated code should be something more like:

//this is modified from SqlMetal and just makes it a bit of fun to allow pluralisation public static string MakePluralName(this string name) { if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) { name = name + "e"; } if ((name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && (name.Length > 1)) && !IsVowel(name[name.Length - 2])) { name = name.Remove(name.Length - 1, 1); name = name + "ie"; } name = name + "s"; return name; }


Douglas Robar 16 May 2014, 11:29:13

FWIW, you don't actually need to use pluralized document type aliases in your razor code at all because TryGetChildrenByAlias() in DynamicPublishedcontent.cs which "works on both the plural and non-plural alias".

@CurrentPage.NewsArea.Children() works just as well as @CurrentPage.NewsAreas.Children()

But since we've been teaching this in the courses for almost two years we should make it work just the same.


Sebastiaan Janssen 16 May 2014, 12:22:33

Fixed in b07665f4d484d14a48b433af50f2c811017ff9a3 for 7.1.3 and in afa81be102ba9adb2afacc727284a87627af9ccc for 6.2.1


Sebastiaan Janssen 16 May 2014, 12:34:27

... yay for code duplication! Also fixed in string extensions method, not just in dynamics extensions..

43bfd6e4722ee6358645b27fd1e4c07aa9b0d0c7 / a55cd67fd63d789d197e7fc81b2b3df2e198e745


Douglas Robar 16 May 2014, 12:43:16

Wahoo! Thank you.

(not sure about the nested parenthesis in the 'if' statements which are vestiges of the original code; not sure they're all needed so hopefully you cast an eye of my proposed code change to make it as good as possible)


Priority: Normal

Type: Bug

State: Fixed

Assignee:

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.1.0, 7.0.4, 7.1.1, 7.1.2

Due in version: 7.1.3, 6.2.1

Sprint:

Story Points:

Cycle: