GithubHelp home page GithubHelp logo

limbo-works / limbo.umbraco.modelsbuilder Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 3.0 990 KB

Custom models builder for Umbraco.

License: MIT License

C# 95.31% Batchfile 0.21% JavaScript 1.43% CSS 0.44% Less 0.49% HTML 2.13%
skybrud limbo umbraco-v9 umbraco umbraco-package umbraco-packages modelsbuilder models-builder package umbraco-v10

limbo.umbraco.modelsbuilder's People

Contributors

abjerner avatar hfloyd avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

limbo.umbraco.modelsbuilder's Issues

[ImplementPropertyType()] Attribute being ignored for customized property names

I noticed that if I specify a custom name for a property, the property is always regenerated, even if the customized property is marked with the [ImplementPropertyType()] attribute.

For example:

MyType.cs:

    partial class MyType
    {
        [ImplementPropertyType("fAQCategories")]
        public new System.Collections.Generic.IEnumerable<string> FaqCategories 
            => this.Value<System.Collections.Generic.IEnumerable<string>>("fAQCategories");
    }

(Notice the updated name: "fAQCategories" -> "FaqCategories")

When I generate models, this is generated:

MyType.generated.cs:

...
        [ImplementPropertyType("fAQCategories")]
        public new System.Collections.Generic.IEnumerable<string> FAqcategories 
            => this.Value<System.Collections.Generic.IEnumerable<string>>("fAQCategories");
...

I would expect that if my custom partial includes a property with [ImplementPropertyType("fAQCategories")], then the generation code would skip that property alias entirely.

Version 2.0.0-alpha002 - NuGet "DirectoryNotFoundException" for "staticwebassets"

Just did the NuGet update to the latest version (2.0.0-alpha002).

Build worked fine, but on running the site in a browser I get this:

image

An error occurred while starting the application.
DirectoryNotFoundException: C:\Users\Heather\.nuget\packages\limbo.umbraco.modelsbuilder\2.0.0-alpha002\staticwebassets\
Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(string root, ExclusionFilters filters)

DirectoryNotFoundException: C:\Users\Heather\.nuget\packages\limbo.umbraco.modelsbuilder\2.0.0-alpha002\staticwebassets\
Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(string root, ExclusionFilters filters)
Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(string root)
Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader+<>c.<UseStaticWebAssetsCore>b__1_0(string contentRoot)
Microsoft.AspNetCore.StaticWebAssets.ManifestStaticWebAssetFileProvider..ctor(StaticWebAssetManifest manifest, Func<string, IFileProvider> fileProviderFactory)
Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader.UseStaticWebAssetsCore(IWebHostEnvironment environment, Stream manifest)
Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader.UseStaticWebAssets(IWebHostEnvironment environment, IConfiguration configuration)
Microsoft.AspNetCore.WebHost+<>c.<ConfigureWebDefaults>b__9_0(WebHostBuilderContext ctx, IConfigurationBuilder cb)
Microsoft.AspNetCore.Hosting.GenericWebHostBuilder+<>c__DisplayClass9_0.<ConfigureAppConfiguration>b__0(HostBuilderContext context, IConfigurationBuilder builder)
Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
Microsoft.Extensions.Hosting.HostBuilder.Build()
Umbraco.Cms.Web.Common.Hosting.UmbracoHostBuilderDecorator.Build()
UmbracoProject.Program.Main(string[] args) in Program.cs
+
            => CreateHostBuilder(args)

Any ideas?

Smidge JS conflict with Umbraco Deploy and Umbraco Forms dashboards

This might only be an issue on sites with Umbraco Deploy/Umbraco Forms installed. I came across it on Umbraco Cloud, where on the live environment the "Deploy" and "Forms" dashboards weren't loading and were throwing Console errors. The Limbo dashboard was loading, but not showing the data.

image

This was the information provided to me by Umbraco Cloud Support:

If you go here - https://[YOURSITE].euwest01.umbraco.io/umbraco#/settings?dashboard=limboModelsBuilder - and open the console you'll see the same error which is also on the workspaces dashboard but this one also refers to the Limbo controller. There seems to be some sort of conflict between the Deploy controller and Limbo controller.

The only way we can explain why the package breaks the workspaces Dashboard only on live is that Deploy doesn't have the same features on the live env that it does on local/dev/stage.

So unfortunately you have hit into this issue Shazwazza/Smidge#132

There's an error in the bundled JS and if you enable debug mode on live then the dashboard with work fine, as the JS isn't bundled anymore which is why it works fine on dev/local

We've enabled debug mode on live and then it worked fine. We've disabled it back again.

The specific Console errors:

umbraco-backoffice-js.js.v637829646180394380:152 Error: [$controller:ctrlreg] http://errors.angularjs.org/1.8.0/$controller/ctrlreg?p0=UmbracoForms.Dashboards.FormsController
    at umbraco-backoffice-js.js.v637829646180394380:32:168
    at umbraco-backoffice-js.js.v637829646180394380:123:19
    at ea (umbraco-backoffice-js.js.v637829646180394380:105:20)
    at p (umbraco-backoffice-js.js.v637829646180394380:96:476)
    at g (umbraco-backoffice-js.js.v637829646180394380:90:292)
    at umbraco-backoffice-js.js.v637829646180394380:89:422
    at Object.link (umbraco-backoffice-js.js.v637829646180394380:326:432)
    at umbraco-backoffice-js.js.v637829646180394380:42:134
    at Ca (umbraco-backoffice-js.js.v637829646180394380:114:361)
    at p (umbraco-backoffice-js.js.v637829646180394380:98:340) '<div ng-include="property.view">'
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:152
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:124
Ca @ umbraco-backoffice-js.js.v637829646180394380:114
p @ umbraco-backoffice-js.js.v637829646180394380:98
g @ umbraco-backoffice-js.js.v637829646180394380:90
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:89
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:95
d @ umbraco-backoffice-js.js.v637829646180394380:92
m @ umbraco-backoffice-js.js.v637829646180394380:96
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:325
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:165
$digest @ umbraco-backoffice-js.js.v637829646180394380:176
$apply @ umbraco-backoffice-js.js.v637829646180394380:180
k @ umbraco-backoffice-js.js.v637829646180394380:131
v @ umbraco-backoffice-js.js.v637829646180394380:136
y.onload @ umbraco-backoffice-js.js.v637829646180394380:137

umbraco-backoffice-js.js.v637829646180394380:152 Error: [$controller:ctrlreg] http://errors.angularjs.org/1.8.0/$controller/ctrlreg?p0=UmbracoDeploy.ManagementDashboardController
    at umbraco-backoffice-js.js.v637829646180394380:32:168
    at umbraco-backoffice-js.js.v637829646180394380:123:19
    at ea (umbraco-backoffice-js.js.v637829646180394380:105:20)
    at p (umbraco-backoffice-js.js.v637829646180394380:96:476)
    at g (umbraco-backoffice-js.js.v637829646180394380:90:292)
    at umbraco-backoffice-js.js.v637829646180394380:89:422
    at Object.link (umbraco-backoffice-js.js.v637829646180394380:326:432)
    at umbraco-backoffice-js.js.v637829646180394380:42:134
    at Ca (umbraco-backoffice-js.js.v637829646180394380:114:361)
    at p (umbraco-backoffice-js.js.v637829646180394380:98:340) '<div ng-include="property.view">'
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:152

umbraco-backoffice-js.js.v637829646180394380:152 Error: [$controller:ctrlreg] http://errors.angularjs.org/1.8.0/$controller/ctrlreg?p0=Limbo.Umbraco.ModelsBuilder.Dashboard.Controller
    at umbraco-backoffice-js.js.v637829646180394380:32:168
    at umbraco-backoffice-js.js.v637829646180394380:123:19
    at ea (umbraco-backoffice-js.js.v637829646180394380:105:20)
    at p (umbraco-backoffice-js.js.v637829646180394380:96:476)
    at g (umbraco-backoffice-js.js.v637829646180394380:90:292)
    at umbraco-backoffice-js.js.v637829646180394380:89:422
    at Object.link (umbraco-backoffice-js.js.v637829646180394380:326:432)
    at umbraco-backoffice-js.js.v637829646180394380:42:134
    at Ca (umbraco-backoffice-js.js.v637829646180394380:114:361)
    at p (umbraco-backoffice-js.js.v637829646180394380:98:340) '<div ng-include="property.view">'
(anonymous) @ umbraco-backoffice-js.js.v637829646180394380:152
umbraco-backoffice-css.css.v637829646180394380:1          Failed to load resource: the server responded with a status of 500 ()

Clicking the related error link https://code.angularjs.org/1.8.0/docs/error/$controller/ctrlreg?p0=Limbo.Umbraco.ModelsBuilder.Dashboard.Controller
Shows:

image

I'm not sure if there is something wrong in the Limbo CSS/JS or something in the bundling instructions for those files which is causing an issue...

Nested Content Properties being generated with empty types

Working on a migration today, and after generating the Models, I see a bunch of these build errors:

Error CS7003 Unexpected use of an unbound generic name

This is showing up for a bunch of generated model files which have a Nested Content Data Type. What is getting generated is something like this:

 [ImplementPropertyType("fAQs")]
  public new System.Collections.Generic.IEnumerable<> FAqs => this.Value<System.Collections.Generic.IEnumerable<>>("fAQs");

The issue is the missing type inside the <>: IEnumerable<>

It seems if the actual DocumentType cannot be identified, it should at least use something general like PublishedElementModel, so that it doesn't cause errors.

Feature Request: Add in Static Getters for Compositions

Copied from a comment on another issue:

For reference, I've attached here two .generated.cs files from a v8 project which used OMB, which shows how the static "Getters" were generated.

One file is a "Composition" type (I always name my Composition Content Types with the prefix "Comp"), and the other is a "standard" Content Type, which includes a bunch of Compositions (so you can see how the properties are referenced). What was interesting here is the use of what Stephan called "Mixins" for the Compositions. Rather than just grabbing the property via alias directly, Compositions added an extra "layer" of static functions that get the data, and the property calls the function. What was really cool about this was that if you customized a Composition - specifically how a property value was obtained - that customization would apply to all Content Types which also used that Composition/Property.

MB_DEMO_TextPage.generated.cs.txt
MB_DEMO_CompHeroBanner.generated.cs.txt

For example, say you had a standard "CompPageSettings", with a string property of "MetaTitle", and if the property from the CMS data was blank, the Node Name was returned (so that property would always have a valid value). You would only have to make that update to the Composition code file, and all the Content Types, since they are calling that same static function, will automatically be getting the right data back.

Example:

 public partial class CompPageSettings
    {
        /// <summary>Static getter for Meta Title</summary>
        public static string GetMetaTitle(ICompPageSettings that)
        {
            var meta = that.GetPropertyValue("MetaTitle").ToString();
            return meta != "" ? meta : that.Name;
        }
    }
	/// <summary>Contact Us Page</summary>
	[PublishedContentModel("ContactUsPage")]
	public partial class ContactUsPage : PublishedContentModel, ICompPageSettings, 
	{
		...
		public ContactUsPage(IPublishedContent content): base(content){ }
		...

		///<summary>
		/// Meta Title
		///</summary>
		[ImplementPropertyType("MetaTitle")]
		public string MetaTitle
		{
			get { return MySite.Models.CompPageSettings.GetMetaTitle(this); }
		}
		...
	}

Originally posted by @hfloyd in #1 (comment)

Getting Started Questions/Issues

Hi @abjerner Thanks for sharing this new package. ๐Ÿ˜Š

While setting it up for my own project, I have come across a few things...

  1. The ReadMe doc states that "The ModelsMode option how Umbraco's build-in ModelsBuilder should work. To avoid conflicts with this package, the value should always be set to None." (https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder#models-mode) However, I was wondering if it should actually be "Nothing" (as per the official Umbraco config docs: https://our.umbraco.com/documentation/Reference/V9-Config/ModelsBuilderSettings/#models-mode)?

  2. I have a Media Composition defined and added to the three standard Media types (File, Folder, Image). After generating the models, they don't build successfully - I get a message for each of the three Media types like this: 'Image' does not implement interface member 'IMediaCompLegacyData.PreviousNodeId' Is there some way I can manually specify the implementation for those three items? In Umbraco 8 I used the VSIX ModelsBuilder and would have partial class files where I could include manual implementations as needed, but I'm not sure if that same sort of code will work with your package? Example:

     #region Implementation of IMediaCompLegacyData
     public int PreviousNodeId=> MediaCompLegacyData.GetPreviousNodeId(this);
     #endregion
    

Models generator doesn't detect classes in partial classes using file-scoped namespaces

https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder/blob/v2/main/src/Limbo.Umbraco.ModelsBuilder/CodeAnalasis/FileSummary.cs#L93

Regular block-scoped namespaces are represented by the NamespaceDeclarationSyntax class, whereas the new file-scoped namespaces are represented by the FileScopedNamespaceDeclarationSyntax class. Both extend the BaseNamespaceDeclarationSyntax class, so we should ideally look for this one instead.

Don't generate interface properties for customized interface properties

Hi!

So, related to #3... Sometimes I customize the property for an interface. For instance, Content Pickers or MNTP by default will be returning "IPublishedContent", but I might know that it will always be of a specific ContentType . In order to be able to call the property and get the strongly-typed model in a View, I customize the composition model and interface. Example:

Customized 'CompRelatedBlogPosts.cs'

partial interface ICompRelatedBlogPosts
    {
        IEnumerable<BlogPost> SelectedPosts { get; }
    }

    partial class CompRelatedBlogPosts
    {
        [ImplementPropertyType("SelectedPosts")]
        public IEnumerable<BlogPost> SelectedPosts => GetSelectedPosts(this);


        public static IEnumerable<BlogPost> GetSelectedPosts(ICompRelatedBlogPosts that)
        {
            return that.Value<IEnumerable<IPublishedContent>>("SelectedPosts").ToContentModels<BlogPost>(true);
        }
    }
}

Then I just add an override to set the correct type in the Models which use the Composition. Example:

partial class TextPage
    {
        #region Implementation of ICompRelatedBlogPosts
        IEnumerable<BlogPost> ICompRelatedBlogPosts.SelectedPosts => CompRelatedBlogPosts.GetSelectedPosts(this);
        #endregion
    }

This works fine. However, when I re-generate the Models, the generated composition file gets the "IPublishedContent" property again:

'CompRelatedBlogPosts.generated.cs'

 public partial interface ICompRelatedBlogPosts : IPublishedContent {

        System.Collections.Generic.IEnumerable<global::Umbraco.Cms.Core.Models.PublishedContent.IPublishedContent> SelectedPosts { get; }

    }

I can solve the issue by explicitly ignoring the property:

'GetModelsNotificationHandler.cs'

    public class GetModelsNotificationHandler : INotificationHandler<GetModelsNotification>
    {
        public void Handle(GetModelsNotification notification)
        {
            foreach (TypeModel model in notification.Models)
            {
            ...             
				//Content-Type specific processing

				if (model.Alias == CompRelatedBlogPosts.ModelTypeAlias)
				{
					foreach (PropertyModel property in model.Properties)
					{
						if (property.Alias == "SelectedPosts")
						{
							property.IsIgnored = true;
						}

					}
				}
               ... 
            }
        }
    }

But I wonder if the generating code can check for the customized property defined in a custom interface implementation and skip it, like it does for the regular properties?

[IgnorePropertyType] doesn't work as expected

I tried to use the Limbo.Umbraco.ModelsBuilder IgnorePropertyType, I created a separate class with the same name as the one generated in the same namespace and added IgnorePropertyType attribute with the field names which ones should be ignored but it doesn't work.
Should I do anything else?
I need to add Generation Rules for Model Builder in Umbraco 12 Application?

Build warning "warning CS0108" should be ignored

On Build I noticed a bunch of warnings for properties generated for inherited models.

example:
warning CS0108: 'MyModel.SeoTitle' hides inherited member 'Master.SeoTitle'. Use the new keyword if hiding was intended.

This is happening for a "nested" style DocumentType (as opposed to Composition-added properties):

public partial class MyModel: Master, IMaster, ICompLegacyData

I think it is safe to ignore this specific issue.

Generate Dictionary Items in a strongly-typed fashion

As per @NikRimington from umbraco/Umbraco-CMS#11854 (comment):

I would love it if Dictionary items could generate a single "DictionaryAliasses" class automatically that followed the hirearchy in the dictionary section to make accessing the aliases safer.

For example:

public static class DictionaryAliases
{
     public const String TopLevelDictionaryItemWithNoChildren = "Top Level Dictionary Item With No Children";
    
     public static class TopLevelDictionaryItemWithChildren
     {
             public const string Alias = "Top Level Dictionary Item With Children";
             public const string FirstChildNode = "First Child Node";
     }
}

I hope that makes some sort of sense. Then dictionary items can be a) Compile time safe, and b) runtime exception caught. They can be accessed like this: DictionaryAliases.TopLevelDictionaryItemWithChildren.Alias

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.