modelsbuilder / ModelsBuilder.Original

The Community Models Builder for Umbraco
MIT License
114 stars 49 forks source link

Create a Dictionary Constants Class containing alises #220

Open NikRimington opened 4 years ago

NikRimington commented 4 years ago

Hey Stephan,

So I have an idea that would be really useful but it's "slightly" outside the scope of Models Builder. However would work in a similar way.

Thinking along the lines of https://github.com/zpqrtbnk/Zbu.ModelsBuilder/issues/215

However, the idea is to create a dedicated Class that exposes all the aliases configured in the dictionary. Maybe generate a class called DictionaryConstants.

Then use the Dictionary structure to generate nested class structures, with some logic to handle naming conventions..

e.g. Dictionary entry with name "Filters.Locations" would generate DictionaryConstants.Filters.Locations and that value would be "Filters.Locations" as that is what the dictionary alias is in Umbraco.

Reason:

Save people having to do @Umbraco.GetDictionaryValue("SomeAlias","Fallback value") instead they can do @Umbraco.GetDictionaryValue(DictionaryConstants.Filters.Locations, "Fallback Value")

Do you think the underlying tech of Models Builder could be used to do this?

zpqrtbnk commented 4 years ago

Well, Models Builder is meant to create models... not only for IPublishedContent, but any type of model that could simplifying the development of sites. Creating models for the dictionary definitely fits in this scope. In fact... it has been on my todo-list for a while, and I even thought we already had a task for it. Well, now we have.

And then, we can discuss it here.

Going from @Umbraco.GetDictionaryValue("SomeAlias","Fallback value") to @Umbraco.GetDictionaryValue(DictionaryConstants.Filters.Locations, "Fallback Value") is nice, but... what if we want to be more ambitious and have...

<!-- the value for key "filters.locations" for the current culture -->
@MB.Dictionary.Filters.Locations()

<!-- the value for key "filters.locations" for the fr-FR culture -->
@MB.Dictionary.Filters.Locations("fr-FR")

<!-- you get it -->
@MB.Dictionary.Filters.Locations(fallback: "fallback value")

In other words, align the dictionary API with what we already have for content models?

NikRimington commented 4 years ago

I think bringing the API in line with content models would be nice but it would still be useful to expose the alias/meta as well.

What if you wanted to access Filters for example and then Locations?

   @MB.Dictionary.Filters()
   @MB.Dictioanry.Filters.Locations()

I don't think that would work would it?

Also,

Something that would need to be considered is people giving dictionary items non-code friendly names. At the moment the "name" is the alias and it also doesn't respect hierarchy.

So you can create

Filters UK Regions

And that generates aliases of "Filters" and "UK Regions", so it would need to consider that.

zpqrtbnk commented 4 years ago

That could work with a clever combination of properties and extension methods. Whether it's a nice way... is a different question.

Now, you are right about exposing aliases too. So we'd have both aliases, and values.

The structure question is interesting. Assume I create the following structure:

Filters
    UK :: Regions
        London
        Something

I guess you could get the alias with Filters.UkRegions.London - same as with models, we would have to sanityze the keys into proper C# names. But the alias would still be "london" indeed.

How would we then get the alias for "UkRegions"? Filters.UkRegions cannot be a string here. It's going to be a class. But... we could define an implicit conversion so that it can be used as a string. Need to experiment.

And then we can generate

public static string UkRegions(this Filters that) 
  => Dictionary.Value(Meta.Dictionary.Filters.UkRegions)

public static string London(this UkRegions that) 
  => Dictionary.Value(Meta.Dictionary.Filters.UkRegions.London)

And use as

@Dictionary.Filters.UkRegions()
@Dictionary.Filters.UkRegions.London()

throwing random ideas here, will need to think about it - happy to hear more ideas & comments

NikRimington commented 4 years ago

For reference here are two structures I've seen recently for dictionary items: This first one I'm currently using: image

Second one: image

If you wanted to be similar to Content Models, what if

Filters.UkRegions.DictionaryItemAlias as a static property that is the alias, in the same way doc types models do it?

Then you could have @Dictionary.Filters.UKRegions << a class rather than a method, but override it's ToString to give the current culture value? @Dictionary.Filters.UKRegions.Value("fr-FR") << Get a specific culture?